C++高性能并行编程与优化 - 课件 - 09 CUDA C++ 流体仿真实战各维度上的大小通过 cudaExtent 指定,方 便起见我们的 C++ 封装类用了 uint3 表示 大小。 • GPU 的多维数组有特殊的数据排布来保障 访存的高效,和我们 CPU 那样简单地行主 序或列主序(如 a[x + nx * y] )的多维数组 不一样。 • 随后可用 cudaMemcpy3D 在 GPU 的三 维数组和 CPU 的三维数组之间拷贝数据。 CUDA 表面对象:封装 • clr 和 vel 使用了双缓冲,写入 clrNext 的同时读取 clr 没有冲突,写入完毕后对调 clrNext 和 clr 。 投影部分 投影部分 • 我们要模拟的流体是不可压缩的,因此有着无散度的特点: div v = 0 • 上式对时间求导,即 d(div v)/dt = div dv/dt = 0 ;带入 dv/dt = -p 得 div grad p = 0 。 • 因此为了模拟不可压缩流我们要求保证 的速度散度 。 投影部分:求速度的散度 • 第一步,如何求出速度场的散度呢?首先速度是一个矢量场,为了 CUDA 对齐方便我们用 了 float4 表示三维矢量,因此速度场在 CUDA 看来就是一个元素类型为 float4 的三维数 组。其散度则是一个标量场,用元素类型为 float 的三维数组来表示。 • 定义求散度的核函数,首先读取速度场周围六个元素的值,然后上下做差得到散度。 投影部分:0 码力 | 58 页 | 14.90 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 07 深入浅出访存优化float a[n]; 可以在栈上分配有 n 个元素的一维数组。 • 通过 a[i] 访问第 i 个元素。 • float a[n][m]; 可以在栈上分配 n 行 m 列的二维数组。 • 通过 a[i][j] 访问第 i 行,第 j 列的元素。 等一下……内存是一维的,为什么可以分配二维的数组? • 众所周知,内存是一维的,因此任何二维数组,都必须被扁平化,才能储存在内存中。 • 对于 float 可以在栈上分配有 n 个元素的一维数组。 • 通过 a[i] 访问第 i 个元素。 • array, m> a; 可以在栈上分配 n 行 m 列的二维数组。 • 通过 a[i][j] 访问第 i 行,第 j 列的元素。 • array 和 C 语言的 [] 数组相比,好处是作为参数传入时不会退化成指针。 C 语言动态数组 • float *a = malloc(n * • 通过 a[i] 访问第 i 个元素。 • float *a = malloc(n * m * sizeof(float)); 可以在堆上分配 n 行 m 列的二维数组。 • 通过 a[i * m + j] 访问第 i 行,第 j 列的元素。 • 释放时,统一用 free(a) • 注意到:动态的数组,因为编译器光从指针没办法推断出列数 m ,因此要手动扁平化。 C++ 动态数组 • 0 码力 | 147 页 | 18.88 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 14 C++ 标准库系列课 - 你所不知道的 set 容器中插入元素 • 可以通过调用 insert 往 set 中添加一个元素。 • 用户无需关心插入的位置, 例如插入元素 3 时, set 会 自动插入到 2 和 4 之间, 从而使元素总是从小到大排 列。 • pairinsert(int val); 向 set 中插入元素 • 刚刚说过 set 具有自动去重 的功能,如果插入的元素已 经在 set 中存在,则不会完 一样。虽然你可能注意到这 里的刚好和插入的顺序相反 ?巧合而已,具体怎么顺序 是和 glibc 实现有关的。 • set 基于红黑树实现,相当 于二分查找 树, unordered_set 基于散 列哈希表实现,正是哈希函 数导致了随机的顺序。 不同版本的 set 容器比较 类型 去重 有序 查找 插入 vector × × O(n) O(1) ~ O(n) set √ √ O(logn) 0 码力 | 83 页 | 10.23 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 17 由浅入深学习 map 容器k k k k k k k k k k k v v v v v v setmap 第四章:哈希散列表 高效的查找离不开我 高效的查找离不开我 unordered_set 查找为什么高效 • 为什么哈希散列表 unorered_set 会比线性数组 vector 在查找这一点上更高效? • 你看,我们刚才只判断了 3 次就找到了目标。这还是最坏的情况,最好只需要 0 码力 | 90 页 | 8.76 MB | 1 年前3
谈谈MYSQL那点事类型的索引(唯一索引) 大文本字段不建立为索引,如果要对大文本字段进行检索, 大文本字段不建立为索引,如果要对大文本字段进行检索, 可以考虑全文索引 可以考虑全文索引 频繁更新的列不适合建立过多索引 频繁更新的列不适合建立过多索引 应用优化 应用优化 索引建立原则(二) 索引建立原则(二) order by order by 字句中的字段, 字句中的字段, where where0 码力 | 38 页 | 2.04 MB | 1 年前3
Rust分布式账务系统 - 胡宇3 4 ● 1. 接受转账请求,转换成 events ● 2. 将 events 送入 Raft 共识,等待 events 被多数节点保存 ○ 共识:基于 raft-rs 的可靠消息队 列 ○ 存储: Rocksdb with Rust 账户层: Auticuro 分布式账务系统 1 2 3 4 ● 1. 接受转账请求,转换成 events ● 2. 将 events0 码力 | 27 页 | 12.60 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 05 C++11 开始的多线程编程int old = atm.fetch_add(val) • 除了会导致 atm 的值增加 val 外,还会 返回 atm 增加前的值,存储到 old 。 • 这个特点使得他可以用于并行地往一个列 表里追加数据:追加写入的索引就是 fetch_add 返回的旧值。 • 当然这里也可以 counter++ ,不过要追加 多个的话还是得用到 counter.fetch_add(n) 。0 码力 | 79 页 | 14.11 MB | 1 年前3
共 7 条
- 1













