【发布时间】:2017-01-28 04:55:54
【问题描述】:
我正在开发一个可多次调用自身的 cuda 内核(动态并行)。所有后续内核调用都必须在父内核完成后执行。所以算法是轮流工作的。
这是一个最小的例子:EDIT
$ cat turn.cu
#include <stdio.h>
__global__ void turnBasedAlgo(int depth, cudaStream_t stream) {
if (depth < 3) {
printf("depth: %d\n", depth);
cudaEvent_t e;
cudaEventCreateWithFlags(&e, cudaEventDisableTiming);
cudaEventRecord(e, stream);
turnBasedAlgo<<<1,1,0,stream>>>(depth+1, stream);
cudaStream_t s2;
cudaStreamCreateWithFlags(&s2, cudaStreamNonBlocking);
cudaStreamWaitEvent(s2, e, 0);
turnBasedAlgo<<<1,1,0,s2>>>(depth+1, s2);
// some work
clock_t start = clock();
clock_t end = clock();
while (end - start < 100000) {
end = clock();
}
}
}
int main(int argc, char **argv) {
cudaStream_t s;
cudaStreamCreateWithFlags(&s, cudaStreamNonBlocking);
turnBasedAlgo<<<1,1,0,s>>>(0, s);
cudaDeviceSynchronize();
cudaDeviceReset();
return 0;
}
$ nvcc -arch=sm_35 -dc turn.cu && nvcc -arch=sm_35 -link -o turn turn.o
$ ./turn
depth: 0
depth: 1
depth: 2
$ nvvp ./turn
第一个子调用是通过将内核放入父流中来完成的。它根本不执行。第二个子调用是通过创建一个新流并等待父内核完成时记录的事件e 来完成的。这个子调用会立即执行。
编辑:
在主机上创建的流和事件在任何内核中使用时具有未定义的行为,就像在子网格中使用时由父网格创建的流和事件具有未定义的行为一样。
阅读更多:http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#ixzz4KngEXdsC
不过:有没有办法实现回合制动态并行?
【问题讨论】:
标签: cuda