我正在使用CUDA 5.0(GTK 110)中的新動態並行性功能進行試驗。我面對奇怪的行爲,即我的程序沒有爲某些配置返回預期結果 - 不僅意外,而且每次啓動都會產生不同的結果。某些子網格未使用CUDA動態並行執行
現在我想我找到了我的問題的來源:似乎有一些兒童網格(由其他內核發起的內核)有時不會在太多的子網格產生時同時執行。
我寫了一個小的測試程序來說明這個問題:
#include <stdio.h>
__global__ void out_kernel(char* d_out, int index)
{
d_out[index] = 1;
}
__global__ void kernel(char* d_out)
{
int index = blockIdx.x * blockDim.x + threadIdx.x;
out_kernel<<<1, 1>>>(d_out, index);
}
int main(int argc, char** argv) {
int griddim = 10, blockdim = 210;
// optional: read griddim and blockdim from command line
if(argc > 1) griddim = atoi(argv[1]);
if(argc > 2) blockdim = atoi(argv[2]);
const int numLaunches = griddim * blockdim;
const int memsize = numLaunches * sizeof(char);
// allocate device memory, set to 0
char* d_out; cudaMalloc(&d_out, memsize);
cudaMemset(d_out, 0, memsize);
// launch outer kernel
kernel<<<griddim, blockdim>>>(d_out);
cudaDeviceSynchronize();
// dowload results
char* h_out = new char[numLaunches];
cudaMemcpy(h_out, d_out, memsize, cudaMemcpyDeviceToHost);
// check results, reduce output to 10 errors
int maxErrors = 10;
for (int i = 0; i < numLaunches; ++i) {
if (h_out[i] != 1) {
printf("Value at index %d is %d, should be 1.\n", i, h_out[i]);
if(maxErrors-- == 0) break;
}
}
// clean up
delete[] h_out;
cudaFree(d_out);
cudaDeviceReset();
return maxErrors < 10 ? 1 : 0;
}
程序啓動內核與一個給定數量的線程中的每個(第2參數)塊(第一個參數)的給定數。然後該內核中的每個線程將使用單個線程啓動另一個內核。這個子內核將在輸出數組的一部分中寫入1(用0初始化)。
在執行結束時,輸出數組中的所有值應爲1.但對於某些塊和網格大小奇怪的是,某些數組值仍然爲零。這基本上意味着一些子網格不被執行。
這隻會發生在許多子網格同時產生的情況下。在我的測試系統(特斯拉K20x)上,每個包含210個線程的10個塊都是這種情況。儘管如此,有200個線程的10個塊可以提供正確的結果。但是也有3個塊,每個1024個線程都會導致錯誤。奇怪的是,運行時沒有報告錯誤。調度器似乎忽略了子網格。
還有其他人面臨同樣的問題嗎?這種行爲記錄在某處(我沒有找到任何東西),還是它真的是設備運行時的錯誤?
這非常合理,謝謝您的回答!我不知道可以使用'cudaGetLastError()'_inside_內核。我還發現可以使用'cudaDeviceSetLimit(cudaLimitDevRuntimePendingLaunchCount,)'來增加掛起啓動計數。如果您可以將其添加到您的答案中,那將是非常好的。再次感謝! –
+1,照亮答案。 – JackOLantern