我想知道CUDA应用程序的warp调度顺序是否是确定性的。
具体来说,我想知道在相同设备上使用相同输入数据的同一内核的多次运行时,warp执行的顺序是否保持不变。如果没有,是否有任何可能强制执行warp执行的命令(例如在调试依赖于顺序的算法时)?
答案 0 :(得分:9)
未定义CUDA warp调度的精确行为。因此,你不能依赖它是确定性的。特别是,如果准备好在给定的发布槽中执行多个warp,则不会描述warp scheduler将选择哪个warp。
没有外部方法来精确控制warp执行的顺序。
当然可以构建确定warp ID的代码,并强制warp以特定顺序执行。像这样:
#include <stdio.h>
#define N_WARPS 16
#define nTPB (32*N_WARPS)
__device__ volatile int my_next = 0;
__device__ int warp_order[N_WARPS];
__global__ void my_kernel(){
__shared__ volatile int warp_num;
unsigned my_warpid = (threadIdx.x & 0x0FE0U)>>5;
if (!threadIdx.x) warp_num = 0;
__syncthreads(); // don't use syncthreads() after this point
while (warp_num != my_warpid);
// warp specific code here
if ((threadIdx.x & 0x01F) == 0){
warp_order[my_next++] = my_warpid;
__threadfence();
warp_num++; // release next warp
} // could use syncthreads() after this point, if more code follows
}
int main(){
int h_warp_order[N_WARPS];
for (int i = 0; i < N_WARPS; i++) h_warp_order[i] = -1;
cudaMemcpyToSymbol(warp_order, h_warp_order, N_WARPS*sizeof(int));
my_kernel<<<1,nTPB>>>();
cudaDeviceSynchronize();
cudaMemcpyFromSymbol(h_warp_order, warp_order, N_WARPS*sizeof(int));
for (int i = 0; i < N_WARPS; i++) printf("index: %d, warp_id: %d\n", i, h_warp_order[i]);
return 0;
}
当然只允许一次执行一个warp将是非常低效的。
通常,最好的可并行化算法很少或没有顺序依赖。