CUDA动态并行中的同步

CUDA动态并行中的同步,cuda,dynamic-parallelism,Cuda,Dynamic Parallelism,我正在使用以下内核测试动态并行性,该内核以分而治之的方式使用动态并行性获取整数数组的最大值: __global__ void getMax(int * arr, int ini, int fin, int * maxv) { if (ini >= fin) return; if (fin-ini==1) { *maxv = arr[ini]; printf("Elem: %d (ini:%d)\n", *maxv, ini); } else {

我正在使用以下内核测试动态并行性,该内核以分而治之的方式使用动态并行性获取整数数组的最大值:

__global__ void getMax(int * arr, int ini, int fin, int * maxv) {

  if (ini >= fin) return;

  if (fin-ini==1) {

    *maxv = arr[ini];
    printf("Elem: %d (ini:%d)\n", *maxv, ini);

  } else {

    int * max1, * max2;
    max1 = (int *) malloc(sizeof(int));
    max2 = (int *) malloc(sizeof(int));

    getMax<<<1,1>>>(arr, ini, (fin+ini)/2, max1);
    getMax<<<1,1>>>(arr, (fin+ini)/2, fin, max2);
    cudaDeviceSynchronize();

    printf("Max1: %d, Max2: %d (ini:%d,fin:%d)\n",
        *max1, *max2, ini, fin);
    *maxv = max(*max1, *max2);

    free(max1); free(max2);

  }
}
正如您所看到的,虽然正在使用
cudaDeviceSynchronize()
,但很多时候父网格在其子网格完成执行之前打印。更糟糕的是,在最终输出中没有考虑一些子值,从而从GPU得到错误的结果


我知道,内核内部使用malloc(使用全局内存)和动态并行本身的速度目前还不足以让这段代码在CPU上有很好的加速。我只是想了解为什么没有正确同步此代码。

每当您在CUDA代码中遇到问题时,建议您使用
CUDA memcheck运行代码,并执行以下操作。对于CUDA动态并行(CDP)代码,您可以(也应该)以相同的方式对设备端内核启动和运行时API的设备使用进行错误检查。即使您不理解生成的错误输出,它也会对那些试图帮助您的人有用

此外,当要求帮助使用不起作用的代码时,您需要提供一个。但在本例中,我可以通过添加自己的主机测试代码来重新创建您的观察结果

本例中的问题似乎是您超出了与CDP相关联的默认嵌套和同步深度,如前所述

通过在主机代码的开头添加一行:

cudaError_t err = cudaDeviceSetLimit(cudaLimitDevRuntimeSyncDepth, 16);
我能够在我的测试用例中消除观察到的问题

但是,请注意文档中的最大限制是24,因此随着问题规模的增大,需要在每个递归深度级别进行设备同步的递归机制不是很可行


我想你只是把这当作一个学习练习。如果您确实对高效的max查找感兴趣,则有。

每当您在CUDA代码中遇到问题时,建议您使用
CUDA memcheck运行代码,并执行以下操作。对于CUDA动态并行(CDP)代码,您可以(也应该)以相同的方式对设备端内核启动和运行时API的设备使用进行错误检查。即使您不理解生成的错误输出,它也会对那些试图帮助您的人有用

此外,当要求帮助使用不起作用的代码时,您需要提供一个。但在本例中,我可以通过添加自己的主机测试代码来重新创建您的观察结果

本例中的问题似乎是您超出了与CDP相关联的默认嵌套和同步深度,如前所述

通过在主机代码的开头添加一行:

cudaError_t err = cudaDeviceSetLimit(cudaLimitDevRuntimeSyncDepth, 16);
我能够在我的测试用例中消除观察到的问题

但是,请注意文档中的最大限制是24,因此随着问题规模的增大,需要在每个递归深度级别进行设备同步的递归机制不是很可行

我想你只是把这当作一个学习练习。如果你真的对高效的max finding感兴趣,这里有