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

我的第一个问题是如何有效地在工作组中的数十个或数百个线程中使用查找表?我了解GPU可以针对不同的任务使用不同类型的内存,但不能完全确定每种内存的运行方式或使用哪种类型。字节类型,大概可以打包成4kb纹理或SSBO。

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

评论

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

此外,请看一下此演示文稿:cvg.ethz.ch/teaching/2011spring/gpgpu/cuda_memory.pdf适用于CUDA,但它应该使您更好地了解底层硬件上发生的情况
并不是一个完整的答案,但您使用的内存量越少越好,因为它更可能适合缓存,并且缓存未命中的次数更少。如果您具有可插值,例如将曲线上的点烘焙为纹理,则可以将其检查为一种以较少的内存获取高质量曲线查找表的方法:blog.demofox.org/2016/02/22/…

#1 楼

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


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

将查找表作为只读缓冲区存储在全局内存中的效果也一样,具体取决于您正在其上运行的特定GPU的缓存大小。

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

评论


$ \ begingroup $
在某些情况下,只读缓冲区比将4kb的只读数据存储在共享本地内存中会更好。例如,将其存储在本地内存中可能意味着每个线程组都有唯一的数据副本。如果缓冲区适合高速缓存,则对于只读访问模式,高速缓存很有可能比本地内存性能更好。
$ \ endgroup $
– John Calsbeek
16年5月20日在6:17

$ \ begingroup $
感谢您的反馈。我已经完成了目前正在使用的项目,并且仅使用了r8ui只读缓冲区纹理进行了处理,效果很好:)
$ \ endgroup $
– russ
16年5月30日在8:01