在GPU上使用查找表时的最佳内存访问?


9

我正在为单身汉的项目探索GPU上的等值面算法(特别是仅关注二进制输入/输出体素数据,而不是实值字段)。因此,我有一个良好的旧行军多维数据集的CPU实现,并在OpenFrameworks中运行,现在处于尝试将其移植到GLSL计算着色器的阶段,并在下潜之前考虑了陷阱。我只写了vert和frag着色器在此之前,这对我来说都是全新的。

我的第一个问题是如何有效地在工作组中的数十个或数百个线程中使用查找表?我了解GPU可以为不同的任务提供不同类型的内存,但不能完全确定每个GPU的工作方式或使用哪种类型。

Paul Bourke的经典copypasta表是256 * 16的数组,因此,如果使用标量字节类型,则可以将其打包为4kb纹理或SSBO。

问题是,如何阻止不同的线程相互跳闸?每个工作组中的许多多维数据集都可能具有相同的配置,因此尝试同时访问缓冲区中的相同位置。有解决方法或优化来解决吗?


如果它是只读查询表,则可以只使用缓冲区/纹理。您可以将其打包为一种正常的纹理格式,也可以使用DX11 / OpenGL的某些较新功能来具有自定义格式。DX11区域中的无人机,或OpenGL区域中的纹理/ shader_image_load_store。
RichieSams,2015年

此外,请看一下此演示文稿:cvg.ethz.ch/teaching/2011spring/gpgpu/cuda_memory.pdf适用于CUDA,但它应该使您更好地了解底层硬件的状况
RichieSams 2015年

并不是一个完整的答案,但您使用的内存量越少越好,因为它更可能适合缓存,并且缓存未命中的次数更少。如果您具有可插值,例如将曲线上的点烘焙为纹理,则可以将其检查为一种以较少的内存获得高质量曲线查找表的方法:blog.demofox.org/2016/02/22/…
艾伦·沃尔夫

Answers:


6

放置GPU计算着色器的查找表的最佳位置取决于查找表的大小以及访问的频率/一致性。在您的情况下(您提到4kb),共享本地内存可能是最好的(假设您在同一内核中不需要此内存用于其他用途)。该内存在不同的API中具有不同的名称,但是是相同的体系结构,并且遵循相同的性能准则:

  • CUDA:线程组共享内存
  • DirectCompute:分组共享内存
  • OpenCL:本地内存
  • 金属:线程组内存
  • OpenGL:共享内存

将查找表作为只读缓冲区存储在全局内存中的效果也可能相同,具体取决于您所运行的特定GPU的缓存大小。

请注意,我假设这是一个只读查询表。读写查找表是完全不同的野兽,您在那里没有任何好的选择。


在某些情况下,只读缓冲区会比在共享本地内存中存储4kb的只读数据更好。例如,将其存储在本地内存中可能意味着每个线程组都有唯一的数据副本。如果缓冲区适合高速缓存,则对于只读访问模式,高速缓存很有可能比本地内存性能更好。
约翰·卡尔斯贝克

谢谢你们的反馈。我已经完成了目前正在使用的项目,并且仅使用了r8ui只读缓冲区纹理进行了整理,效果很好:)
鲁斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.