C++高性能并行编程与优化 - 课件 - 07 深入浅出访存优化
深入浅出访存优化 by 彭于斌( @archibate ) 往期录播: https://www.bilibili.com/video/BV1fa411r7zp 课程 PPT 和代码: https://github.com/parallel101/course 为什么往 int 数组里赋值 1 比赋值 0 慢一倍? 第 1 章:内存带宽 cpu-bound 与 memory-bound • 而 sine 这种内部需要泰勒展开来计算,每次迭代计算量很大的 循环体,并行才有较好的加速效果。称为计算瓶颈( cpu- bound )。 • 并行能减轻计算瓶颈,但不减轻内存瓶颈,故后者是优化的重点 。 浮点加法的计算量 • 冷知识:并行地给浮点数组每个元素做一次加法反而更慢。 • 因为一次浮点加法的计算量和访存的超高延迟相比实在太少了。 • 计算太简单,数据量又大,并行只带来了多线程调度的额外开销 无法合并写入,会产生有中间数据读的带 宽。 写入 1 比写入 0 更慢? • 很简单,因为写入 0 被编译器自动优化成 了 memset ,而 memset 内部利用了 stream 指令得以更快写入。 写入 1 比写入 0 更慢?解决 • 解决办法就是,我们也用 stream 指令, 这样就可以和标准库优化过的 memset 一 样快了。 Intel Intrinsics Guide • _mm0 码力 | 147 页 | 18.88 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 性能优化之无分支编程 Branchless Programming
性能优化 之 无分支编程 Branchless Programming by 彭于斌( @archibate ) 两种代码写法:分支 vs 三目运算符 两种使用方式:排序 vs 不排序 测试结果(均为 gcc -O3 ) 测试结果可视化 图表比较:分支 vs 无分支 分支 无分支 0 0.01 0.02 0.03 耗时(越低越好) 乱序 有序 • 传统的分支方法实现的 排序过的数据明显比乱序时高效。 • 无分支的方法对于乱序和有序的数据一样 高效,性能吊打了传统的分支方法。 • 对于传统分支的做法,为什么排序了的更 高效?既然无分支更高效,我要怎样优化 才能让我的程序变成无分支的呢?那就来 看本期性能优化专题课吧! 分支预测成败对性能的影响 排序为什么对有分支的版本影响那么大 为什么需要流水线 • 为了高效, CPU 的内部其实是一个流水 线 (pipeline) 节省时间。 • 例如洗脸需要眼睛嘴巴手,刷牙需要嘴巴手 ,那么洗脸和刷牙不能同时进行。但是烧开 水只需要占用煤气灶,和洗脸刷牙不冲突, 所以可以一边烧开水一边洗脸刷牙。 • 所以让小彭老师来优化的话,可以只需要 5 + 5 + 10 + 20 = 40 分钟,比你快一倍多。 任务 时间 占用资源 洗脸 5 分钟 眼睛,嘴巴,手 烧开水 10 分钟 煤气灶 刷牙 5 分钟 嘴巴,手0 码力 | 47 页 | 8.45 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 04 从汇编角度看编译器优化
从汇编角度看编译器优化 by 彭于斌( @archibate ) 往期录播: https://www.bilibili.com/video/BV1fa411r7zp 课程 PPT 和代码: https://github.com/parallel101/course 高性能并行编程与优化 - 课程大纲 • 分为前半段和后半段,前半段主要介绍现代 C++ ,后半段主要介绍并行编程与优化。 1.课程安排与开发环境搭建: 入门:常用 STL 容器, RAII 内存管理 3.现代 C++ 进阶:模板元编程与函数式编程 4.编译器如何自动优化:从汇编角度看 C++ 5.C++11 起的多线程编程:从 mutex 到无锁并行 6.并行编程常用框架: OpenMP 与 Intel TBB 7.被忽视的访存优化:内存带宽与 cpu 缓存机制 8.GPU 专题: wrap 调度,共享内存, barrier 9.并行算法实战: *(rsp - 4) = edi; 开启优化: -O3 movl %edi, %eax 相当于: eax = edi 32 位乘法运算: imull imull %esi, %eax 相当于: eax *= esi 64 位乘法运算: imulq imulq %rsi, %rax 相当于: rax *= rsi 不过是 int64_t 的 整数加法:被优化成 leal 了 eax = rdi0 码力 | 108 页 | 9.47 MB | 1 年前3KubeCon2020/大型Kubernetes集群的资源编排优化
0 码力 | 27 页 | 3.91 MB | 1 年前3绕过conntrack,使用eBPF增强 IPVS优化K8s网络性能
0 码力 | 24 页 | 1.90 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 17 由浅入深学习 map 容器
的遍历:不修改也建议加引用 k v (假如非常大的话) 执行你这段代码 的栈空间 & & ( 建立引用 ) map 中的 堆空间 • 何况 structural-binding 捕获的引用比刚刚图示的还要优化。他只会保存一个指向 pair 类 型的指针,然后在你使用 k 和 v 时再去按偏移量访问里面的 first 和 second ,所以 k , v 两个变量的 structural-binding O(n) 。 1 4 2 8 5 7 要找的数 内存 5 ==? 地址 a a+1 a+2 a+3 a+4 a+5 set 查找为什么高效 • set 又称集合(数学概念),是专为查找优化的容器,查找元素要用他自带的 find 函数。 • seta = { 1, 4, 2, 8, 5, 7 }; • a.find(5); • set 之所以能够实现 O(logn) 复杂度高效查找,是因为他内部预先构建好了一棵二叉排序树。 • 如何构建的?请看动画: 1 4 2 8 5 7 待插入的数 set 查找为什么高效 • set 又称集合(数学概念),是专为查找优化的容器,查找元素要用他自带的 find 函数。 • set a = { 1, 4, 2, 8, 5, 7 }; • a.find(5); • set 之所以能够实现 O(logn) 0 码力 | 90 页 | 8.76 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 11 现代 CMake 进阶指南
/opt/openvdb-8.0/lib/libopenvdb.so ) • cmake -B build -DCMAKE_BUILD_TYPE=Release • ↑ 设置构建模式为发布模式(开启全部优化) • cmake -B build ← 第二次配置时没有 -D 参数,但是之前的 -D 设置的变量都会被保留 • (此时缓存里仍有你之前定义的 CMAKE_BUILD_TYPE 和 CMAKE_INSTALL_PREFIX 也可以通过 pip install cmake 安装……) • 事实上, MSBuild 是单核心的构建系统, Makefile 虽然多核心但因历史兼容原因效率一 般。 • 而 Ninja 则是专为性能优化的构建系统,他和 CMake 结合都是行业标准了。 Ninja 和 Makefile 简单的对比 性能上: Ninja > Makefile > MSBuild Makefile 启动时会把每个文件都检测一遍, CMake 中一个特殊的变量,用于控制构建类型,他的值可以 是: • Debug 调试模式,完全不优化,生成调试信息,方便调试程序 • Release 发布模式,优化程度最高,性能最佳,但是编译比 Debug 慢 • MinSizeRel 最小体积发布,生成的文件比 Release 更小,不完全优化,减少二进制体积 • RelWithDebInfo 带调试信息发布,生成的文件比 Release0 码力 | 166 页 | 6.54 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 08 CUDA 开启的 GPU 编程
可以调 用 device ; device 可以调用 device 。 声明为内联函数 • 注意, inline 在现代 C++ 中的效果是声明一个函数为 weak 符号,和性能优化意义上的内联无关。 • 优化意义上的内联指把函数体直接放到调用者那里去。 • 因此 CUDA 编译器提供了一个“私货”关键字: __inline__ 来 声明一个函数为内联。不论是 CPU 函数还是 GPU 都可以使 __forceinline__ 这个关键字来强制一个函数为内联。 GCC 也有相应的 __attribute__((“always_inline”)) 。 • 此外,还有 __noinline__ 来禁止内联优化。 定义在 CPU 上的主机函数 • __device__ 将函数定义在 GPU 上,而 __host__ 则相反,将函数定义在 CPU 上。 定义在 CPU 上的主机函数 • CUDA 如果不指定,编译器默认的版本号是 52 ,他是针对 GTX900 系列显卡的。 • 不过英伟达的架构版本都是向前兼容的,即版本号为 75 的 RTX2080 也可以运行版本号为 52 的指令码,虽然 不够优化,但是至少能用。也就是要求:编译期指定的 版本 ≤ 运行时显卡的版本。 CMAKE_CUDA_ARCHITECTURES 会自动转换成 --gpu-code 等编 译 flag 版本号不要太新了0 码力 | 142 页 | 13.52 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 01 学 C++ 从 CMake 学起
@archibate ) 高性能并行编程与优化 - 课程大纲 • 分为前半段和后半段,前半段主要介绍现代 C++ ,后半段主要介绍并行编程与优化。 1.课程安排与开发环境搭建: cmake 与 git 入门 2.现代 C++ 入门:常用 STL 容器, RAII 内存管理 3.现代 C++ 进阶:模板元编程与函数式编程 4.编译器如何自动优化:从汇编角度看 C++ 5.C++11 起的多线程编程:从 起的多线程编程:从 mutex 到无锁并行 6.并行编程常用框架: OpenMP 与 Intel TBB 7.被忽视的访存优化:内存带宽与 cpu 缓存机制 8.GPU 专题: wrap 调度,共享内存, barrier 9.并行算法实战: reduce , scan ,矩阵乘法等 10.存储大规模三维数据的关键:稀疏数据结构 11.物理仿真实战:邻居搜索表实现 pbf 流体求解 120 码力 | 32 页 | 11.40 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 06 TBB 开启的并行编程之旅
com/parallel101/course 高性能并行编程与优化 - 课程大纲 • 分为前半段和后半段,前半段主要介绍现代 C++ ,后半段主要介绍并行编程与优化。 1.课程安排与开发环境搭建: cmake 与 git 入门 2.现代 C++ 入门:常用 STL 容器, RAII 内存管理 3.现代 C++ 进阶:模板元编程与函数式编程 4.编译器如何自动优化:从汇编角度看 C++ 5.C++11 起的多线程编程:从 起的多线程编程:从 mutex 到无锁并行 6.并行编程常用框架: OpenMP 与 Intel TBB 7.被忽视的访存优化:内存带宽与 cpu 缓存机制 8.GPU 专题: wrap 调度,共享内存, barrier 9.并行算法实战: reduce , scan ,矩阵乘法等 10.存储大规模三维数据的关键:稀疏数据结构 11.物理仿真实战:邻居搜索表实现 pbf 流体求解 12 量的增加,不再用于继续提升单核频率,转而 用于增加核心数量。单核性能不再指数增长! 你醒啦?免费午餐结束了! 指望靠单核性能的增长带来程序性 能提升的时代一去不复返了,现在 要我们动动手为多核优化一下老的 程序,才能搭上摩尔定律的顺风车 。 神话与现实: 2 * 3GHz < 6GHz • 一个由双核组成的 3GHz 的 CPU 实际上提供了 6GHz 的处理能力,是吗? • 显然不是0 码力 | 116 页 | 15.85 MB | 1 年前3
共 29 条
- 1
- 2
- 3