C++高性能并行编程与优化 - 课件 - 15 C++ 系列课:字符与字符串
其实是同等 地位的。 • 虽然也可以给 std::string 定义很多个不同的 + 重载,每个针对不同的数字类 型( int 、 float 、 double )排列组合,但是这样没有可扩展性,而且影响编 译速度。 • 所以 cpp 说,你必须手动把 42 先转换为字符串,然后再和已有的字符串相 加: • “you have ” + std::to_string(42) + “ yuan” ,才能确定字符串在哪里结束,确定他的长度。换言之, strlen 函数 的复杂度为 O(n) ,如果需要频繁的查询长度,势必会非常低效。 • 4. 若需要在尾部切片就得修改字符串本身(写入一个 ‘ \0’ ),影响其他弱引 用。 胖指针大法横空出世 • 刚刚说了,要描述一个动态长度的数组(此处为字符串),需要首地址指针和 数组长度两个参数。 • void cihou_array(char *ptr, string_view ,这种弱引用( weak reference )不影响原对象的生命周期,原对象的销毁仍然由强引用控制。 • 这个弱引用的弱,体现在哪里? • 当 string_view 被拷贝时,其指向的字符串仍然是同一个(浅拷贝)。 • 当 string_view 被销毁时,其指向的字符串仍存在(弱引用不影响生命周期) 。 s1 s2 “ 具体字符 串” “ 具体字符 串”0 码力 | 162 页 | 40.20 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 性能优化之无分支编程 Branchless Programming
高效,性能吊打了传统的分支方法。 • 对于传统分支的做法,为什么排序了的更 高效?既然无分支更高效,我要怎样优化 才能让我的程序变成无分支的呢?那就来 看本期性能优化专题课吧! 分支预测成败对性能的影响 排序为什么对有分支的版本影响那么大 为什么需要流水线 • 为了高效, CPU 的内部其实是一个流水 线 (pipeline) 。流水线的目的是能把原本 串行的一系列指令并行化。为了理解为什 么需要流水线,我们先反过来,假设没有 刷牙 5 分钟 嘴巴,手 看比站 15 分钟 眼睛 吃饭 30 分钟 嘴巴,手 拉粑粑 20 分钟 屁股 (无条件)跳转到结束 去医院 10 分钟 全身 结束 跳转指令对流水线效率的影响 • 然而跳转指令的存在使得流水线的并行变得很困难了。例如我们本来可以烧开水和刷牙同 时进行节省时间的,但是因为烧好开水以后还要判断“是否烫伤”才能决定接下来是正常刷牙 还是去医院。这意味着流水 • 一般只需要把 if-else 改成三目运算符 ?: 编 译器就能成功识别了(见开头的例子)。 • 建议只有当性能遇到瓶颈时,再去针对性对 “热代码”优化,而不是一股脑儿全部改成无分 支,影响可读性。 “ 妙用加减乘”的无分支优化是万能的吗? • return x >= 0 ? sqrt(x) : 0; • 能不能优化成: • return (x >= 0) * sqrt(x);0 码力 | 47 页 | 8.45 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 02 现代 C++ 入门:RAII 内存管理
就是 C )的成员函数,不要混淆。 不影响 shared_ptr 计数:弱引用 weak_ptr • 有时候我们希望维护一个 shared_ptr 的弱引用 weak_ptr ,即:弱引用的拷贝与解构不影响其 引用计数器。 • 之后有需要时,可以通过 lock() 随时产生一个 新的 shared_ptr 作为强引用。但不 lock 的时 候不影响计数。 • 如果失效(计数器归零)则 效率低,需要额外的一块管理内存,访问实际对象 需要二级指针,而且 deleter 使用了类型擦除技术 。 2. 全部用 shared_ptr ,可能出现循环引用之类的问题 ,导致内存泄露,依然需要使用不影响计数的原始 指针或者 weak_ptr 来避免。比如右边这个例子: 循环引用:解决方案 1 • 如何解决?只需要把其中逻辑上“不具有所 属权”的那一个改成 weak_ptr 即可: • 因为父窗口“拥有”子窗口是天经地义的,而0 码力 | 96 页 | 16.28 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 08 CUDA 开启的 GPU 编程
先传回到 CPU 再进行调用,这是 CUDA 特有的能力。 常用于这种情况:需要从 GPU 端动态计算出 blockDim 和 gridDim ,而又不希望导回数据到 CPU 导致强制同步影响性能。 这种模式被称为动态并行( dynamic parallelism ), OpenGL 有一 个 glDispatchComputeIndirect 的 API 和这个很像,但毕竟没有 CUDA • 这里为什么用 sinf 而不是 sin ? • 因为 sin 是 double 类型的正弦函数,而我 们需要的 sinf 是 float 类型的正弦函数。可 不要偷懒少打一个 f 哦,否则影响性能。 • 完成同步之后,和 CPU 算出来的比较差值, 看看 GPU 算的是否准确无误,从右边的输出 可以看到基本是一致的。 测试一下时间 • 使用第六节课中的 ticktock.h 测试一下 来实现 浮点原子加法。 • 当然我们 CUDA 11 的 atomicAdd 本身 就支持 float 了,不需要这样魔改,这里 仅仅作为展示 atomicCAS 潜力的案例。 原子操作的问题:影响性能 • 不过由于原子操作要保证同一时刻只能有一个 线程在修改某个地址,如果多个线程同时修改 同一个就需要像“排队”那样,一个线程修改完 了另一个线程才能进去,非常低效。 • 但是为什么这里用了0 码力 | 142 页 | 13.52 MB | 1 年前3谈谈MYSQL那点事
途径,实际中尽可能两者兼顾。 MySQL 架构设计—高可用架构 系统优化:硬件、架构 系统优化:硬件、架构 服务优化 服务优化 应用优化 应用优化 MySQL MySQL 优化方式 优化方式 影响性能的因素 影响性能的因素 应用程序 应用程序 查询 查询 事务管理 事务管理 数据库设计 数据库设计 数据分布 数据分布 网络 网络 操作系统 操作系统 硬件 硬件 使用好的硬件,更快的硬盘、大内存、多核 代表日志只大约每秒写入日志文件并且日志文件 刷新到磁盘 ; 1 为执行完没执行一条 SQL 马上 commit; 2 代表日志写入日志文件在每次提交 后 , 但是日志文件只有大约每秒才会刷新到磁盘上 . 对速度影响比较大,同时也关系数据完整性 innodb_log_file_size 8M 512M 在日志组中每个日志文件的大小 , 一般是 innodb_buffer_pool_size 的 25% ,官方推荐是0 码力 | 38 页 | 2.04 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 07 深入浅出访存优化
31198 MB/s 。 • 和理论带宽 42672 MB/s 相差不多,符合我的预期 。 第 2 章:缓存与局域性 针对不同数据量大小的带宽测试 • 我们试试看 a 不同的大小,对带宽有什么影响。 针对不同数据量大小的带宽测试(续) • 可见数据量较小时,实际带宽甚至超过了 理论带宽极限 42672 MB/s ! • 而数据量足够大时, 才回落到正常的带宽 。 • 这是为什么? 素,还包含因为 jacobi 特性需要周围两个元素,导致 迭代 16 次就需要往边缘扩张的 16 个元素。 • 因为局部数组的大小远远小于一级缓存,这样迭代时 读写的带宽就是一级缓存的速度,几乎没有影响。 • 这里一次循环体直接相当于 16 次迭代,两次就完了。 但是可能加的有点过头变成 cpu-bound 了,所以只快 了 10 倍左右,大家掌握里面的思想就好。 进一步优化 • 用了一 顺便分享一个小妙招: find_package 后面不加 REQUIRED ,这样找不到就不会报错。 • 然后用 TARGET TBB::tbb 判断是否找到了 tbb , 如果没找到抛出警告,但是不影响使用。如果找到就 链接上,并定义宏 WITH_TBB 让源文件判断。 • 然后在 .cpp 文件里写 #ifdef WITH_TBB 包围住需 要用到 tbb 的部分,这样即使没有 tbb 的同学也能0 码力 | 147 页 | 18.88 MB | 1 年前3新一代分布式高性能图数据库的构建 - 沈游人
海致获得“ 2021 年 CCF 科学技术奖科技进步卓越奖” CCF 科学技术奖被认为是计算机科学与技术领域最具影响力的专业奖项之一, 其中科技进步卓越奖是 CCF 科技进步奖评选中的最高级别奖项,旨在嘉奖在计 算机科学、技术或工程领域具有重要发现、发明、原始创新,在相关领域有一 定国际影响的优秀成果, AtlasGraph 的获奖证明了其技术领先性、创新性、 重要性,在自主可控浪潮下,实现了对国外产品的有效替代,防止高新技术领0 码力 | 38 页 | 24.68 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 10 从稀疏数据结构到量化数据类型
以有的指针被重复分配了两遍,写入了那个地址却没有实际被存到 m_data 这个指针数组里。因此结果不对,还造成了内存泄露。 解决:使用互斥量和原子变量 暴力解决方案就是用 std::mutex 避免多个线程同时访问。 然而这样会严重影响性能,锁和原子多了,就根本并行不起来。 教科书式的解决:二次判断法 这样如果 block 已经非空,则可以不用上锁,减少上锁次数。 如果 block 为空,则上锁;再次检测是否为空,空则分配内存, operator= 和 operator bool 的 std::_Bit_reference 对象,而且效率很低。 • 如果配合用 decltype 和 auto 的话,他们不会正确推导出 bool ,影响我们正常使用模板元编 程。 • 一般认为 vector是 C++ 标准库设计上的一个败笔,是为了向前兼容才保持这样不变的 。 • 他们就不应该直接特化 vector 0 码力 | 102 页 | 9.50 MB | 1 年前3Zadig 面向开发者的云原生 DevOps 平台
价值被团队感知:自动化测试从开发到发布被全团队感知 部署频率升高 1-5 倍 验证有效性提升 100% 解放测试,全面自动化 提升效率,建设质量体系 安全 安全建设被动: • 安全建设缺乏时机和抓手 • 出现问题,影响业务进度 前置安全服务:全流程嵌入安全检测,避免流入业务环节。 全流程安全门禁:关键环节设置安全门禁,快速反馈研发改进 故障拦截率提升 1-3 倍 业务响应效率提升 3-5 倍 全流程安全建设 kubectl 登入服务 1. Zadig 工作流自动更新服务 2. Zadig 集成环境更新服务配置 3. 在 Zadig 的图形界面上查看实时日志、调试 测试 1. 测试因为环境不稳定经常受影响 1. 测试套件的自助式运行,管理和执行分析测试结果 2. 关联到开发工作流中,为开发提供自动化验证保障 效能提升场景: 2K+ 微服务、多语言、 Helm 、 K8s 多集群 1. 维护成本高昂0 码力 | 59 页 | 81.43 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 16 现代 CMake 模块化项目管理指南
”/opt/Qt5.12.1/lib/cmake/Qt5”) # 一定要加在最前面! 三种方案利弊分析 • 单次有效(通过命令行)最安全,小彭老师高度推荐。 • 全局有效(添加环境变量)可能影响以后其他项目。比如你 A 项目依赖 Qt5.12.1 ,你设置了环 境变量 Qt5_DIR=/opt/Qt5.12.1 ,后来又搞了个 B 项目依赖 Qt5.10.3 ,但是你忘了你设置过全 局的环境变量指向 但是,也有少数不听话的库,官方不提供 CMake 支持,即安装时不自带 Config 文件。 • 恼人的是,这些不听话的库有些竟然是非常热门的库!例如 Python , CUDA , Jemalloc 。 • 为了不影响 CMake 用户体验, CMake 发明了 Find 文件( FindXXX.cmake ),你不 支持我是吧?我支持你! Find 文件会在 CMake 安装时负责安装到 /usr/share/cmake/Modules0 码力 | 56 页 | 6.87 MB | 1 年前3
共 17 条
- 1
- 2