C++高性能并行编程与优化 - 课件 - 10 从稀疏数据结构到量化数据类型
从稀疏数据结构到量化数据类型 by 彭于斌( @archibate ) 往期录播: https://www.bilibili.com/video/BV1fa411r7zp 课程 PPT 和代码: https://github.com/parallel101/course 本课涵盖:稀疏矩阵、 unordered_map 、空间稀 疏网格、位运算、浮点的二进制格式、内存带宽优 化 面向人群:图形学、 是负数,则得到的模也是负数。 Python 的 % 就没问题 • 7 % 4 = 3 • -7 % 4 = 1 • Python 的模运算 a % b 的值始终是 [0, b) 区间内的正数,非常方便。 对稀疏数据结构造成的问题 • 如果这里的 x 是负数,则 x % B 也是负数,会造成对 m_block 的越界访问。 • 因此 % 会返回负数对 CFD 用户来说是个很大的坑点,很多人想当然地用 % 做循环边界, 是正数,则是向下取整。 Python 的 // 就没问题 • 7 // 4 = 1 • -7 // 4 = -2 • Python 的整除运算 a // b 的值始终是向下取整,非常方便。 对稀疏数据结构造成的问题 • 也就是说,如果 x 是 [-3,0] 则 x / B 会是 0 ,如果 x 是 [0,3] 则 x / B 也是 0 。导致两个 同时跑到一个 block 上去,会出错。 高效的解决:位运算0 码力 | 102 页 | 9.50 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 01 学 C++ 从 CMake 学起
被忽视的访存优化:内存带宽与 cpu 缓存机制 8.GPU 专题: wrap 调度,共享内存, barrier 9.并行算法实战: reduce , scan ,矩阵乘法等 10.存储大规模三维数据的关键:稀疏数据结构 11.物理仿真实战:邻居搜索表实现 pbf 流体求解 12.C++ 在 ZENO 中的工程实践:从 primitive 说起 13.结业典礼:总结所学知识与优秀作业点评 I 硬件要求: 64 CMake 认为一个包 (package) 可以提供多个库,又称组件 (components) ,比如 TBB 这个包,就包含了 tbb, tbbmalloc, tbbmalloc_proxy 这三个组件。 • 因此为避免冲突,每个包都享有一个独立的名字空间,以 :: 的分割(和 C++ 还挺像的) 。 • 你可以指定要用哪几个组件: • find_package(TBB REQUIRED0 码力 | 32 页 | 11.40 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 16 现代 CMake 模块化项目管理指南
OpenCV::videoio 这 两个组件,如果没有这两个组件也会报错。 • find_package(OpenCV REQUIRED OPTIONAL_COMPONENTS core videoio) • 查找名为 OpenCV 的包,找不到就报错,可具有 OpenCV::core 和 OpenCV::videoio 这两个 组件,没有这两组件不会报错,通过 ${OpenCV_core_FOUND} ${OpenCV_core_FOUND} 查询是否找到 core 组件。 find_package 说是找“包”,到底是在找什么? • find_package(OpenCV) 实际上是在找一个名为 OpenCVConfig.cmake 的文件。 • 注:出于历史兼容性考虑,除了 OpenCVConfig.cmake 以外 OpenCV-config.cmake 这 个文件名也会被 CMake 识别到。 • 同理, ${XXX_LIBRARIES} ,有的又是 $ {XXX_LIBRARY} 非常沙雕,需要看相应 cmake 文件的注释,才能确定具体是怎么命名的 。 • 现代 CMake 就好多了,统一用 包名 :: 组件名 的格式。但是具体的组件名,还是要查看 cmake 文件中的注释才能确定。例如 CURL::libcurl OpenCV::core Qt5::core TBB::tbb 等。 现代和古代区别的总结 •0 码力 | 56 页 | 6.87 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 11 现代 CMake 进阶指南
find_package(Qt5 REQUIRED) 出错了 原因: Qt5 具有多个组件,必须指定你需要哪些组件 find_package 生成的伪对象 (imported target) 都按照“包名 :: 组件名”的格式命名。 你可以在 find_package 中通过 COMPONENTS 选项,后面跟随一个列表表示需要用的组件。 测试一下能否找到 Qt 的头文件并编译通过 常见问题:小彭老师, Windows0 码力 | 166 页 | 6.54 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 07 深入浅出访存优化
如果有,则直接使用缓存中的数据。 • 这样一来,访问的数据量比较小时,就可以自动预先加 载到这个更高效的缓存里,然后再开始做运算,从而避 免从外部内存读写的超高延迟。 缓存的分级结构 查看高速缓存大小: lscpu • 可以看到我们 x86 电脑的缓存结构分为三级。 • 一级缓存分为数据缓存和指令缓存,其中数据缓存有 32 KB , 6 个物理核心每个都有一个,总共 192 KB 。而指令缓存的大小刚好和数据缓存一样也是 。而指令缓存的大小刚好和数据缓存一样也是 192 KB 。 • 二级缓存有 256 KB , 6 个物理核心每个都有一个, 总共 1.5 MB 。 • 三级缓存由各个物理核心共享,总共 12 MB 。 通过图形界面查看拓扑结构: lstopo 根据我们缓存的大小分析刚刚的图表 • 也可以看到刚刚两个出现转折的点,也是在 二级缓存和三级缓存的大小附近。 • 因此,数据小到装的进二级缓存,则最大带 宽就取决于二级缓存的带宽。稍微大一点则 宽。三级缓存也装不下,那就取决于主内存 的带宽了。 • 结论:要避免 mem-bound ,数据量尽量足 够小,如果能装的进缓存就高效了。 L2: 256 KB L3: 12 MB 缓存的工作机制:读 • 缓存中存储的数据结构: • struct CacheEntry { • bool valid; • uint64_t address; • char data[64]; • }; • CacheEntry0 码力 | 147 页 | 18.88 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 03 现代 C++ 进阶:模板元编程
被忽视的访存优化:内存带宽与 cpu 缓存机制 8.GPU 专题: wrap 调度,共享内存, barrier 9.并行算法实战: reduce , scan ,矩阵乘法等 10.存储大规模三维数据的关键:稀疏数据结构 11.物理仿真实战:邻居搜索表实现 pbf 流体求解 12.C++ 在 ZENO 中的工程实践:从 primitive 说起 13.结业典礼:总结所学知识与优秀作业点评 I 硬件要求: 64 get 的返回类型 。 tuple :结构化绑定 • 可是需要一个个去 get 还是好麻烦。 • 没关系,可以用结构化绑定的语法: • auto [x, y, ...] = tup; • 利用一个方括号,里面是变量名列表,即 可解包一个 tuple 。里面的数据会按顺序 赋值给每个变量,非常方便。 tuple :结构化绑定为引用 • 结构化绑定也支持绑定为引用: • auto &[x tuple :结构化绑定为万能推导 • 不过要注意一下万能推导的 decltype(auto) , 由于历史原因,他对应的结构化绑定是 auto && : • auto &&[x, y, ...] = tup; // 正确! • decltype(auto) [x, y, ...] = tup; // 错误! • 对的,是两个与号 && 。 结构化绑定:还可以是任意自定义类!0 码力 | 82 页 | 12.15 MB | 1 年前3Rust与算法 - 谢波
…………………………………………………………………………… …………………………….. 1 6 11 15 21 • 背景介绍 • 算法相关知识 • Rust 实现数据结构 • Rust 实现算法 • 总结及学习资源 背景介绍 • 个人信息 • 写作动机 • 可参考点 • 为什么 背景介绍 # 个人职业 # 与 Rust 结缘 # 前 GPT 时代作品 写作本书给我的启示 基础、排序、查找、树、图 代码框、颜色、图片绘制均由 Latex 完成 可参考点 为什么 为什么讲这个话题? 为什么要讲数据结构和算法两部分? 算法相关知识 算法相关知识 • 抽象数据类型 • 时空复杂度 • 复杂度计算 • 基本数据结构复杂度 抽象数据类型 什么是抽象数据类型? 为什么需要抽象数据类型? 时空复杂度 • 时间复杂度更被看重 • 时间和空间复杂度不是对立的,可以协同 时间和空间复杂度不是对立的,可以协同 时间和空间复杂度 复杂度计算 • 大O标记法(数量级近似) • 用 AI 来估计 算步骤、算存储 Rust 基本数据结构复杂度 线性数据结构 非线性数据结构 总体来看,时间复杂度没有超过 O(n) 的! Rust 实现数据结构 • 栈 • 链表 • Vec Rust 实现数据结 构 栈 借助 Vec 容器 泛型支持 Option ? 链表 链接可能为空0 码力 | 28 页 | 3.52 MB | 1 年前3Rust 异步并发框架在移动端的应用 - 陈明煜
任务优先级调度 异步并行迭代器 结构化并发 Ylong Runtime 对外 接口 APP/SA 调度器 提 交 任 务 Async function CPU Task CPU Task IO Task IO Task Executor 高 中 低 线程池 Reactor epoll fd1 fd2 …. 结构化并发 优先级 deadline Async Fusion of IO/CPU intensive 结构化并发 Structured Concurrency 核心在于通过一种父子结构化的方法实现并发程序,用具有明确入口点和出口 点的控制流结构来封装并发任务(可以是线程也可以是协程)的执行,确保所有派生任务在出口之前完 成。 Structured concurrency 结构化并发带来的好处: 更高的易用性,用户不再需要显示调用 await await 提高程序的可读性和可维护性 保证了变量生命周期合法,使子任务可以捕获父任务的变量 结构化并发 Structured concurrency Scope Rust 线程中的结构化并发 阻塞等待所有 Scope 内的子线程任务完成 子线程执行的闭包中可以捕获 Scope 外的变 量 AsyncScope 将 std 库中 thread scope 的思想异步化0 码力 | 25 页 | 1.64 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 04 从汇编角度看编译器优化
被忽视的访存优化:内存带宽与 cpu 缓存机制 8.GPU 专题: wrap 调度,共享内存, barrier 9.并行算法实战: reduce , scan ,矩阵乘法等 10.存储大规模三维数据的关键:稀疏数据结构 11.物理仿真实战:邻居搜索表实现 pbf 流体求解 12.C++ 在 ZENO 中的工程实践:从 primitive 说起 13.结业典礼:总结所学知识与优秀作业点评 I 硬件要求: 64 bitset, glm::vec, string_view • pair, tuple, optional, variant 存储在栈上无法动态扩充大小,这就是 为什么 vector 这种数据结构要存在堆上 ,而固定长度的 array 可以存在栈上 那么刚才那个例子改成 array 是不是就可 以自动优化成功了?你可以自己试试看, 想一想,为什么会是这个结果,然后在作 业的 PR 描述中和老师分享你的思考 SIMD 矢量化。 第 6 章:结构体 两个 float :对齐到 8 字节 成功 SIMD 矢量化! 三个 float :对齐到 12 字节 矢量化失败,生成了标量的低效代码 往 struct 里添加了个根本没有用到的 z ,却 直接导致了优化失败!这是为什么? 添加一个辅助对齐的变量:对齐到 16 字节 追加了一个没有用的 4 字节变量,整个结构体变 成 16 字节大小,矢量化反而成功了??0 码力 | 108 页 | 9.47 MB | 1 年前3Zadig 面向开发者的云原生 DevOps 平台
Zadig 每天数百次构建部署持续交付 “ 星云科技是我们持续创业的新业务,我们从一开始就采用了公有云、云原生等最新的理念, 结合以往的技术经验,毫无悬念的直接选择 Zadig 作为持续交付的核心组件,从最头打造最 高效的研发体系。 Zadig 解决了云原生环境的持续交付的难题,与 GitLab 等已在业界广泛 ” 使用的系统集成顺畅,互操作性强,是目前行业中最优雅的方案 去年, 我们整个微服务已经达到了 400 多个,还用传统那种运维方式很消耗内部开发资源。我们在 探索过程中发现了 Zadig ,今天 Zadig 技术体系已经成为我们的核心持续交付组件。 —— 研发负责人 詹佳杭 3 个集群、 15 个项目、 240 个服务、 52 条工作流、 18 个环境, 2397 个交付物 构建 3907 次,部署 2446 次0 码力 | 59 页 | 81.43 MB | 1 年前3
共 22 条
- 1
- 2
- 3