假设我有一个 local_size=8*8*8 的 OpenGL 计算着色器。调用如何映射到 nVidia GPU 扭曲?相同的调用gl_LocalInvocationID.x
会在同一个扭曲中吗?还是你?还是z?我不是指所有调用,我只是指一般聚合。
我之所以这样问是因为有一段时间的优化,并不是所有的调用都有工作要做,所以我希望它们处于同一个扭曲中。
假设我有一个 local_size=8*8*8 的 OpenGL 计算着色器。调用如何映射到 nVidia GPU 扭曲?相同的调用gl_LocalInvocationID.x
会在同一个扭曲中吗?还是你?还是z?我不是指所有调用,我只是指一般聚合。
我之所以这样问是因为有一段时间的优化,并不是所有的调用都有工作要做,所以我希望它们处于同一个扭曲中。
计算着色器执行模型允许调用的数量(大大)超过扭曲/波前中单个执行单元的数量。例如,硬件扭曲/波前大小往往在 16 到 64 之间,而GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS
OpenGL 中要求工作组 ( ) 中的调用次数不少于 1024。
barrier
shared
当工作组跨越多个经线/波前时调用和使用可变数据的工作原理基本上是通过停止所有经线/波前的进度,直到它们每个都通过该特定点。然后执行各种内存刷新,以便他们可以访问彼此的变量(当然基于内存屏障的使用)。如果一个工作组中的所有调用都适合一个单一的经线,那么就有可能避免这样的事情。
基本上,您无法控制 CS 调用如何分组到 warp 中。您可以假设实现不会尝试变慢(也就是说,它通常会将来自同一个工作组的调用分组到同一个 warp 中),但您不能假设同一个工作组内的所有调用都在同一个 warp 中.
您也不应该假设每个 warp 只执行来自同一个工作组的调用。
据此:https ://www.khronos.org/opengl/wiki/Compute_Shader#Inputs
gl_LocalInvocationIndex =
gl_LocalInvocationID.z * gl_WorkGroupSize.x * gl_WorkGroupSize.y +
gl_LocalInvocationID.y * gl_WorkGroupSize.x +
gl_LocalInvocationID.x;
因此,假设具有相同gl_LocalInvocationID.x
的调用在同一个扭曲中是非常安全的。