C++高性能并行编程与优化 - 课件 - 06 TBB 开启的并行编程之旅每个任务包含 8 个元素 tbb::static_partitioner ,指定区间的粒度 创建了 2 个线程 2 个任务 每个任务包含 16 个元素 tbb::simple_partitioner 创建了 4 个线程 32 个任务 每个任务包含 1 个元素 tbb::simple_partitioner ,指定区间的粒度 创建了 4 个线程 8 个任务 每个任务包含 4 个元素 tbb::auto_partitioner 记录历史,下次根据经验自动负载均衡 tbb::simple_partitioner 粒度为 1 太细了,效果不好 tbb::static_partitioner 粒度自动变成 n / 4 ,效果好 tbb::simple_partitioner 粒度手动设为 n / 8 ,效果稍微更好一点 tbb::auto_partitioner 自动判断合适的粒度,效果也不错 例子:矩阵转置 使用合适的 grain 大小, 大小, simple_partitioner 比 auto_partitioner 快 3.31 倍 原因 • tbb::simple_partitioner 能够按照给定的粒度 大小( grain )将矩阵进行分块。块内部小区 域按照常规的两层循环访问以便矢量化,块外 部大区域则以类似 Z 字型的曲线遍历,这样 能保证每次访问的数据在地址上比较靠近,并 且都是最近访问过的,从而已经在缓存里可以0 码力 | 116 页 | 15.85 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 07 深入浅出访存优化字节的跨步访问,都会导致数据全部被读取出来。而超过 64 字节的 跨步,则中间的缓存行没有被读取,从而变快了。 缓存行决定数据的粒度 • 结论:访问内存的用时,和访问的字节数 量无关,和访问的每个字节所在的缓存行 数量有关。 • 可见,能否很好的利用缓存,和程序访问 内存的空间局域性有关。 缓存行决定数据的粒度(续) • 所以我们设计数据结构时,应该把数据存 储的尽可能紧凑,不要松散排列。最好每 个缓存行里要么有数据,要么没数据,避 内部是 SOA ,而外部仍是一个 vector的 AOS—— 这种内存布局称为 AOSOA 。 • 缺点是必须保证数量是 1024 的整数倍, 而且因为要两次指标索引,随机访问比较 烦。 • 这里的 1024 并非随意选取,而是要让每 个属性 SOA 数组的大小为一个页 ( 4KB )才能最高效,原因稍后会说明。 AOSOA :注意,内部 SOA 的尺寸不宜太小 SOA 分开存”是没问题的。 • 而且 SOA 在遇到存储不是 vector ,而是稀疏的哈希网格之类索引有一定 开销的数据结构,可能就不适合了。这就是为什么王鑫磊最喜欢 AOSOA :在高层保持 AOS 的统一索引,底层又享受 SOA 带来的矢量化 和缓存行预取等好处……就是随机索引比较麻烦。 结构体剥离: https://blog.csdn.net/qq_36287943/artic 0 码力 | 147 页 | 18.88 MB | 1 年前3
Rust 异步并发框架在移动端的应用 - 陈明煜mobile environment Rust 异步机制 Asynchronous Rust 异步并发框架是许多大型应用、系统具备的底层能力。 区别于多线程编程模型,它带来以下优势: 任务调度颗粒度更小,充分利用线程资源 更可控的线程数 单个任务资源占用:几十 KB -> 几百 Byte 任务切换时间 : 10 微秒 -> 100 纳秒 Rust 语言并没有提供异步并发框架,0 码力 | 25 页 | 1.64 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 10 从稀疏数据结构到量化数据类型sys/mman.h 头文件里。 • Windows 可以用 VirtualAllocateEx 之类。 • mmap 出来的起始地址保证是对齐到 4KB 的,读写访问其 中偏移地址时,会按页的粒度自动分配和释放内存,从而满 足稀疏数据结构“按需分配”的需求。且由于分页是硬件自动 来做的,比我们软件哈希和指针数组的稀疏更高效,写起来 就和普通的二维数组没什么两样,就好像顺序访问。也用不0 码力 | 102 页 | 9.50 MB | 1 年前3
谈谈MYSQL那点事数据存储方式简单,使用 数据存储方式简单,使用 B+ Tree B+ Tree 进行索引 进行索引 • 使用三个文件定义一个表: 使用三个文件定义一个表: .MYI .MYD .frm .MYI .MYD .frm • 少碎片、支持大文件、能够进行索引压缩 少碎片、支持大文件、能够进行索引压缩 • 二进制层次的文件可以移植 二进制层次的文件可以移植 (Linux (Linux level lock , 读写性能都非常优秀 读写性能都非常优秀 • 能够承载大数据量的存储和访问 能够承载大数据量的存储和访问 • 拥有自己独立的缓冲池,能够缓存数据和索引 拥有自己独立的缓冲池,能够缓存数据和索引 MySQL 架构设计—应用架构 强一致性 对读一致性的权衡,如果是对读写实时性要求非常高的话, 就将读写都放在 M1 上面, M2 只是作为 standby 。 比如 对每个唯一打开的表需要 2 个文件描述符。 服务优化 服务优化 MyISAM MyISAM 选项 选项 选项 缺省值 推荐值 说明 key_buffer_size 8M 512M 用来存放索引区块的缓存值 , 建议 128M 以上,不要大于内存的 30% read_buffer_size 128K 64M 用来做 MyISAM 表全表扫描的缓冲大 小 . 为从数据表顺序读取数据的读操 作保留的缓存区的长度0 码力 | 38 页 | 2.04 MB | 1 年前3
新一代分布式高性能图数据库的构建 - 沈游人2021 年 CCF 科 学技术奖科技进步卓越奖”。 伴随市场对于知识图谱应用的不断深入,图数据规模和应用性能之间的矛盾愈 加凸显,海致针对以上背景展开了系统性的技术攻关,解决了图数据的高效存 储、索引及复制难题,提出了基于图缩减的高效分析方法,并孵化出了一个大 规模图数据分析平台 AtlasGraph 。 5 获得 2022 年中国电子学会科学技术奖科技进步一等奖 中国电子学会发布的《 2022 Processing 架构,大规模集群 分布式存储及并行计 算, Shared Nothing 模式支 持存储计算分离 高性能 基于 Rust 开发的分布式存储引 擎及图计算引擎,精细的内存 管理设计,内置索引系统,支 持毫秒级的并发查询响应速度 易用 AQL(Atlas Graph Query Language) ,类 SQL 的图查询 语言,内置上百种分析函数, 面向分析师友好,拥抱标准, 基于 存储层 副本管理 CRAQ 图原生存储 索引 LSM-Tree 容灾保障 ( BR ) 元数据层 事务管理 MVOCC 计算层 Cypher AST 优化器 图计算 内存加速引 擎 服务接口 HTTP/RPC Spark 连接器 Python UDF 执行器 索引管理 一致性存储 RAFT 分片管理 元数据 集群管理 用户权限0 码力 | 38 页 | 24.68 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 13 C++ STL 容器全解之 vector&operator[](size_t i) const noexcept; vector 容器: operator[] • 值得注意的是, [] 运算符在索引超出数组大 小时并不会直接报错,这是为了性能的考虑。 • 如果你不小心用 [] 访问了越界的索引,可能 会覆盖掉别的变量导致程序行为异常,或是访 问到操作系统未映射的区域导致奔溃。 • int &operator[](size_t i) noexcept; &operator[](size_t i) const noexcept; vector 容器: at • 为了防止不小心越界,可以用 a.at(i) 替代 a[i] , at 函数会检测索引 i 是否越界,如果他 发现索引 i >= a.size() 则会抛出异常 std::out_of_range 让程序提前终止(或者被 try-catch 捕获),配合任意一款调试器,就可 以很快速地定位到出错点。0 码力 | 90 页 | 4.93 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 04 从汇编角度看编译器优化因为这种线性变换在地址索引 中很常见,所以被 x86 做成 了单独一个指令。这里尽管不 是地址,但同样可以利用 lea 指令简化生成的代码大小。 eax = rdi + rsi * 8 指针访问对象:线性访问地址 rsi = (int64_t)esi eax = *(int *)(rdi + rsi * 4) 为什么乘以 4 ?因为访问的 对象, int 的大小是 4 。 指针的索引:尽量用 size_t 位系统上相当于 uint32_t 从而不需要用 movslq 从 32 位符号扩展 到 64 位,更高效。而且也能处理数组大 小超过 INT_MAX 的情况,推荐始终用 size_t 表示数组大小和索引。 浮点作为参数和返回: xmm 系列寄存器 xmm0 = xmm0 + xmm1 参数分别通过 xmm0 , xmm1 传入。 返回值通过 xmm0 传出。 什么是 xmm 系列寄存器?0 码力 | 108 页 | 9.47 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 14 C++ 标准库系列课 - 你所不知道的 set 容器元素从小到大排序,而 vector 会保持插入时的顺序。 • 区别 2 : set 会把重复的元素 去除,只保留一个,即去重。 • 区别 3 : vector 中的元素在内 存中是连续的,可以高效地按 索引随机访问, set 则不行。 • 区别 4 : set 中的元素可以高 效地按值查找,而 vector 则 低效。 set 的排序: string 会按“字典序”来排 • set 会从小到大排序,对 , O(1) unordered_multiset× ,因为是无序的 √ , O(1) √ , O(1) 查找方面各容器适合的领域 • vector 适合:按索引查找。通过运算符 [] 。 • set 适合:按值相等查找,按值大于 / 小于查找。分别通过 函数 find 、 lower_bound 、 upper_bound 。 • unordered_set 0 码力 | 83 页 | 10.23 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 02 现代 C++ 入门:RAII 内存管理std::dynamic_pointer_cast 8. 运算符重载 9. 右值引用 && 10. std::shared_ptr和 std::any • 只提供了关键字,详细信息请善用搜索引擎: bing.com 。(不要用 baidu.com ,那个是搜广告用的) • 如果感兴趣,我可以增添一节专门讲动态多态。 回家作业! • 已经发布到: https://github.com/parallel101/hw02 的拷贝构造函数能正常工作,且内存能够安全释放。 • 通过 pull request 提交你的作业,这样我可以通过 diff 页面清楚地看到你的改动。 • 什么事 pull request ?还是善用搜索引擎,这是作业的一部分( x 感谢观看! by 彭于斌( github@archibate ) 录播: https://space.bilibili.com/ 263032155 课件: https://github 0 码力 | 96 页 | 16.28 MB | 1 年前3
共 13 条
- 1
- 2













