CUDA Thread Hierarchy vs OpenGL Compute Shader Thread Hierarchy
CUDA Thread Hierarchy
CUDA中的kernel
是一段可在GPU独立运行的小程序,而且这段程序会被实例化(类似的说法还有launched, issued, executed, invoked)成非常多的thread
, 这些线程可并发地在GPU上运行。程序员或者说编译器将这些线程组织成
- Thread
- Thread Block
- Grid of Thread Blocks
Thread
一个单独的线程必然属于一个Thread Block
, 它有自己的
- thread ID
- program counter
- registers
- per-thread private memory
- inputs
- output
Thread Block
一个Thread Block
必然属于一个Grid
, 它是一组并发执行的线程的集合,这些线程之间可以通过barrier synchronization
和per-Block shared memory
互相协同, 它也有一个Block ID
用来索引它在Grid
中的位置。
1 | dim3 blockDim; |
Grid of Thread Blocks
一个Grid
由一组执行相同kernel
的Thread Blocks
组成。可以这样说,一个Grid
是所有执行同一个Kernel
的线程的集合。
1 | dim3 gridDim; |
CUDA Thread Map
CUDA的threads层级结构可以映射到GPU的processors的层级结构上。
- 一个GPU执行一个或多个grids(kernels)
- 一个SM(Streaming Multiprocessor)执行一个或多个Thread Blocks
- CUDA Cores和一个SM里的其它执行单元(SFU, LDST)执行多个线程
SM执行线程的单位是warp
, 一般是32个线程一组,一个warp
里的32个线程是真正并行执行的。
CUDA Memory
1 | cudaError_t cudaMemcpy(void *dst, |
除了最后一个参数,其它参数都顾名知意。kind
指示内存拷贝的方向:
- cudaMemcpyHostToHost
- cudaMemcpyHostToDevice
- cudaMemcpyDeviceToHost
- cudaMemcpyDeviceToDevice
OpenGL Compute Shader Thread Hierarchy
有了前面的CUDA的Thread Hierarchy的了解,OpenGL的Compute Shader的线程层级就好理解了,本质上是一样的。一个OpenGL Compute Shader(cs)
就相当于一个cuda中的kernel
函数, 这些任务最终被分发到GPU的各个物理核心上去执行。在cs
中,单个任务叫做work item
, 除了work item
之外, 还有以下概念:
- subgroups
也就是warps
或者wavefronts
或者Compute Units
, 它们实际上就是threads
, shader cores
, cuda cores
- local workgroup
它的大小(维度)在cs
中通过layout
修饰符指定
1 | layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; |
local workgroup
相当于cuda的Thread Block
- global workgroup
它的大小(维度)通过OpenGL API设置, glDispatchCompute
发起一个或多个compute work groups, 此处的work groups就是local work group
1 | void glDispatchCompute(GLuint num_groups_x, |
global workgroup
相当于cuda的Grid
CUDA和Compute Shader变量对比
type | CUDA | type | Compute Shader |
---|---|---|---|
dim3 | gridDim | uvec3 | gl_NumWorkGroups |
uint3 | blockIdx | uvec3 | gl_WorkGroupID |
dim3 | blockDim | const uvec3 | gl_WorkGroupSize |
uint3 | threadIdx | uvec3 | gl_LocalInvocationID |
- | - | uvec3 | gl_GlobalInvocationID |
- | - | uint | gl_LocalInvocationIndex |
References: