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 年前3
C++高性能并行编程与优化 - 课件 - 性能优化之无分支编程 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 年前3
C++高性能并行编程与优化 - 课件 - 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 年前3
KubeCon2020/大型Kubernetes集群的资源编排优化0 码力 | 27 页 | 3.91 MB | 1 年前3
绕过conntrack,使用eBPF增强 IPVS优化K8s网络性能0 码力 | 24 页 | 1.90 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 17 由浅入深学习 map 容器乍看之下好像没错,运行结果也是正确的,但 这只是碰巧你的 items 里存在 “ hello” 而已, 如果哪天 “ hello” 不存在了他也不会报错而是 默默创建然后返回 0 ,后患无穷! • 这种代码就像被抽空的叠叠乐一样危险重重, 稍有一根稻草就能压垮骆驼,而且都不知道是 这根稻草压垮的,难以溯源。 错误示范 • 假如我这里不小心手一滑,把 “ hello” 打错成了 “ hell” } • } • 封装成函数方便使用: • auto val = map_get(m, “key”, “default”); • ss map 常用函数不同情况下的行为分析 类型 C++ 代码 key 已存在 key 不存在 读取 val = m.at(key) 读取这个值 抛出 out_of_range 异常 val = m[key] 读取这个值 创建并零初始化(默认构造函数) 写入 默默放弃 小彭老师四定律: 读取,要用 at 。 写入,要用 [] 。 判断存在,用 count 。 删除,用 erase 。 这四个已经够用了。 map 常用函数不同情况下的行为分析 类型 C++ 代码 key 已存在 key 不存在 读取 val = m.at(key) 读取这个值 抛出 out_of_range 异常 val = m[key] 读取这个值 创建并零初始化(默认构造函数) 写入0 码力 | 90 页 | 8.76 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 11 现代 CMake 进阶指南现代 CMake 进阶指南 by 彭于斌( @archibate ) 往期录播: https://www.bilibili.com/video/BV1fa411r7zp 课程 PPT 和代码: https://github.com/parallel101/course 为什么要学习现代 CMake ? • 现代 CMake 指的是 CMake 3.x 。 • 古代 CMake 指的是 CMake build 目录下生成本地构建系统能识别的项目文件( Makefile 或是 .sln ) • 第二步是 cmake --build build ,称为构建阶段( build ),这时才实际调用编译器来编译代码 • 在配置阶段可以通过 -D 设置缓存变量。第二次配置时,之前的 -D 添加仍然会被保留。 • cmake -B build -DCMAKE_INSTALL_PREFIX=/opt/openvdb-8 /opt/openvdb-8.0/lib/libopenvdb.so ) • cmake -B build -DCMAKE_BUILD_TYPE=Release • ↑ 设置构建模式为发布模式(开启全部优化) • cmake -B build ← 第二次配置时没有 -D 参数,但是之前的 -D 设置的变量都会被保留 • (此时缓存里仍有你之前定义的 CMAKE_BUILD_TYPE 和 CMAKE_INSTALL_PREFIX0 码力 | 166 页 | 6.54 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 08 CUDA 开启的 GPU 编程CUDA 开启的 GPU 编程 by 彭于斌( @archibate ) 往期录播: https://www.bilibili.com/video/BV1fa411r7zp 课程 PPT 和代码: https://github.com/parallel101/course 前置条件 • 学过 C/C++ 语言编程。 • 理解 malloc/free 之类的概念。 • 熟悉 STL 中的容器、函数模板等。 CUDA 和 C++ 的关 系就像 C++ 和 C 的关系一样,大部分都兼容 ,因此能很方便地重用 C++ 现有的任何代码库 ,引用 C++ 头文件等。 • host 代码和 device 代码写在同一个文件内,这 是 OpenCL 做不到的。 编写一段在 GPU 上运行的代码 • 定义函数 kernel ,前面加上 __global__ 修 饰符,即可让他在 GPU 上执行。 • 不过调用 上执行 printf 了。 • 这里的 kernel 函数在 GPU 上执行,称为核 函数,用 __global__ 修饰的就是核函数。 没有反应?同步一下! • 然而如果直接编译运行刚刚那段代码,是不会打印出 Hello, world! 的。 • 这是因为 GPU 和 CPU 之间的通信,为了高效,是异 步的。也就是 CPU 调用 kernel<<<1, 1>>>() 后,并不 会立即在0 码力 | 142 页 | 13.52 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 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 流体求解 12 i_blend ) 关于作者(再续) • 主导 Zeno 节点仿真框架的开发( https://github.com/zenustech/zeno ) 什么是编译器 • 编译器,是一个根据源代码生成机器码的程序。 • > g++ main.cpp -o a.out • 该命令会调用编译器程序 g++ ,让他读取 main.cpp 中的字符串(称为源码),并根据 C+ + 标准生成相应的机器指令码,输出到0 码力 | 32 页 | 11.40 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 06 TBB 开启的并行编程之旅https://www.bilibili.com/video/BV1fa411r7zp 课程 PPT 和代码: https://github.com/parallel101/course 高性能并行编程与优化 - 课程大纲 • 分为前半段和后半段,前半段主要介绍现代 C++ ,后半段主要介绍并行编程与优化。 1.课程安排与开发环境搭建: cmake 与 git 入门 2.现代 C++ 入门:常用 STL STL 容器, RAII 内存管理 3.现代 C++ 进阶:模板元编程与函数式编程 4.编译器如何自动优化:从汇编角度看 C++ 5.C++11 起的多线程编程:从 mutex 到无锁并行 6.并行编程常用框架: OpenMP 与 Intel TBB 7.被忽视的访存优化:内存带宽与 cpu 缓存机制 8.GPU 专题: wrap 调度,共享内存, barrier 9.并行算法实战: 量的增加,不再用于继续提升单核频率,转而 用于增加核心数量。单核性能不再指数增长! 你醒啦?免费午餐结束了! 指望靠单核性能的增长带来程序性 能提升的时代一去不复返了,现在 要我们动动手为多核优化一下老的 程序,才能搭上摩尔定律的顺风车 。 神话与现实: 2 * 3GHz < 6GHz • 一个由双核组成的 3GHz 的 CPU 实际上提供了 6GHz 的处理能力,是吗? • 显然不是0 码力 | 116 页 | 15.85 MB | 1 年前3
共 34 条
- 1
- 2
- 3
- 4













