C++高性能并行编程与优化 -  课件 - 09 CUDA C++ 流体仿真实战memory CUDA 多维数组:封装 • cudaMalloc3DArray 用于分配一个三维数组。 各维度上的大小通过 cudaExtent 指定,方 便起见我们的 C++ 封装类用了 uint3 表示 大小。 • GPU 的多维数组有特殊的数据排布来保障 访存的高效,和我们 CPU 那样简单地行主 序或列主序(如 a[x + nx * y] )的多维数组 不一样。 • 随后可用 cudaMemcpy3D 在 GPU 的三 维数组和 CPU 的三维数组之间拷贝数据。 CUDA 表面对象:封装 • 要访问一个多维数组,必须先创建一个表面对象 ( cudaSurfaceObject_t )。 • 考虑到多维数组始终是需要通过表面对象来访问的,这 里我们让表面对象继承自多维数组。 • 在核函数中可以用 surf3Dread 和 surf3Dwrite 来读写 表面对象中的元素, x,y0 码力 | 58 页 | 14.90 MB | 1 年前3
 C++高性能并行编程与优化 -  课件 - 08 CUDA 开启的 GPU 编程结论:对于使用寄存器较少、访存为主的核函数(例如矢量加法),使用大 blockDim 为 宜。反之(例如光线追踪)使用小 blockDim ,但也不宜太小。 经典案例:矩阵转置 • 为什么需要多维?直接手动求模运算获取 x , y 坐标不行吗?看右边这个例子。 • 回顾一下:我们第七课讲过, CPU 上的 并行 for ,通常会做循环分块提升缓存局 域性。但是如果我们是传统的两层的 blockDim 和 gridDim ,然后在核函数里分别计算 x 和 y 的扁平化线程编号就行了!他会自动变 成 循环分块一样的效果,有利于缓存局域 性。 • 顺便一提 Taichi 没有用多维的 blockDim ,他统一用一维的网格跨步循环 来扁平化高维循环,这就是为什么我们用 Taichi 的 for 处理二维、三维数据的 stencil 时会比较低效。因为他们根本就不0 码力 | 142 页 | 13.52 MB | 1 年前3
 C++高性能并行编程与优化 - 课件 - Zeno 中的现代 C++ 最佳实践 态的虚函数,这就是被小彭老师称为自动 虚克隆 (auto-vitrual-clone) 的大法。 Zeno 中对 OpenVDB 对象的封装 • 开源的体积数据处理库 OpenVDB 中有许多“网格”的类(可以理解为多维数组),例如: • openvdb::Vec3fGrid , FloatGrid , Vec3IGrid , IntGrid , PointsDataGrid • 我们并不知道他们之间的继承关系,可能有也可能没有。但是在0 码力 | 54 页 | 3.94 MB | 1 年前3
 C++高性能并行编程与优化 -  课件 - 07 深入浅出访存优化用其成员的解构函数,而不会实际释放内存( free )。 • 因此第二次进入的时候,如果 n 不超过上一次的大小 ,就还是用的第一次分配的内存,避免了重新分配的开 销。对 func 需要被重复调用的情况很实用。 第 6 章:多维数组 C 语言静态数组 • float a[n]; 可以在栈上分配有 n 个元素的一维数组。 • 通过 a[i] 访问第 i 个元素。 • float a[n][m]; 可以在栈上分配 n 行0 码力 | 147 页 | 18.88 MB | 1 年前3
共 4 条
- 1
 













