[英]CUDA double precision and number of registers per thread
執行內核時出現錯誤
too many resources requested for launch
我在網上檢查了有關錯誤消息的任何提示,這表明發生這種情況是由於使用了比GPU為每個多處理器指定的限制更多的寄存器。 設備查詢結果如下:
Device 0: "GeForce GTX 470"
CUDA Driver Version / Runtime Version 5.0 / 5.0
CUDA Capability Major/Minor version number: 2.0
Total amount of global memory: 1279 MBytes (1341325312 bytes)
(14) Multiprocessors x ( 32) CUDA Cores/MP: 448 CUDA Cores
GPU Clock rate: 1215 MHz (1.22 GHz)
Memory Clock rate: 1674 Mhz
Memory Bus Width: 320-bit
L2 Cache Size: 655360 bytes
Total amount of constant memory: 65536 bytes
Total amount of shared memory per block: 49152 bytes
Total number of registers available per block: 32768
Warp size: 32
Maximum number of threads per multiprocessor: 1536
Maximum number of threads per block: 1024
Maximum sizes of each dimension of a block: 1024 x 1024 x 64
Maximum sizes of each dimension of a grid: 65535 x 65535 x 65535
更新 Robert Crovella表示他在運行代碼方面沒有問題,因此我在此處粘貼了完整的代碼片段以供執行。
完整的代碼如下所示:
__global__ void calc_params(double *d_result_array, int total_threads) {
int thread_id = threadIdx.x + (blockDim.x * threadIdx.y);
d_result_array[thread_id] = 1 / d_result_array[thread_id];
}
void calculate() {
double *h_array;
double *d_array;
size_t array_size = pow((double)31, 2) * 2 * 10;
h_array = (double *)malloc(array_size * sizeof(double));
cudaMalloc((void **)&d_array, array_size * sizeof(double));
for (int i = 0; i < array_size; i++) {
h_array[i] = i;
}
cudaMemcpy(d_array, h_array, array_size * sizeof(double), cudaMemcpyHostToDevice);
int BLOCK_SIZE = 1024;
int NUM_OF_BLOCKS = (array_size / BLOCK_SIZE) + (array_size % BLOCK_SIZE)?1:0;
calc_params<<<NUM_OF_BLOCKS, BLOCK_SIZE>>>(d_array, array_size);
cudaDeviceSynchronize();
checkCudaErrors(cudaGetLastError());
cudaFree(d_array);
free(h_array);
}
當我執行此代碼時,出現錯誤,因為啟動所需的資源過多
而不是在內核中使用逆語句
(即d_result_array [thread_id] = 1 / d_result_array [thread_id])
平等的陳述完美地工作
(即d_result_array [thread_id] = d_result_array [thread_id] * 200)。
為什么? 有沒有其他替代方法(除了使用較小的塊大小)。 如果那是唯一的解決方案,我將如何知道可以工作的塊大小。
問候,
PS對於那些可能想知道cudaCheckErrors是什么的人
#define checkCudaErrors(val) check( (val), #val, __FILE__, __LINE__)
template<typename T>
void check(T err, const char* const func, const char* const file, const int line) {
if (err != cudaSuccess) {
std::cerr << "CUDA error at: " << file << ":" << line << std::endl;
std::cerr << cudaGetErrorString(err) << " " << func << std::endl;
exit(1);
}
}
內部版本和操作系統信息
Build of configuration Debug for project TEST
make all
Building file: ../test_param.cu
Invoking: NVCC Compiler
nvcc -G -g -O0 -gencode arch=compute_20,code=sm_20 -odir "" -M -o "test_param.d" "../test_param.cu"
nvcc --compile -G -O0 -g -gencode arch=compute_20,code=compute_20 -gencode arch=compute_20,code=sm_20 -x cu -o "test_param.o" "../test_param.cu"
Finished building: ../test_param.cu
Building target: TEST
Invoking: NVCC Linker
nvcc -link -o "TEST" ./test_param.o
Finished building target: TEST
操作系統
Ubuntu Lucid (10.04.4) 64bit
Linux paris 2.6.32-46-generic #105-Ubuntu SMP Fri Mar 1 00:04:17 UTC 2013 x86_64 GNU/Linux
我收到錯誤
CUDA error at: ../test_param.cu:42
too many resources requested for launch cudaGetLastError()
這似乎是編譯器的產物。 問題似乎是寄存器使用情況,您可以通過在nvcc命令行上傳遞-Xptxas -v
選項來觀察。 由於某種原因, -G
版本的代碼使用的寄存器(每個線程)比常規代碼多得多。 您有幾種選擇:
-G
開關。 無論如何,此開關僅應用於調試目的,因為它生成的代碼可能比沒有-G開關時運行得慢。 -G
開關,則減少每個塊的線程數。 對於這種情況下的示例,我能夠使它以每個塊或更少的768個線程運行。 指示編譯器每個線程使用更少的寄存器。 您可以使用-maxrregcount
開關來執行此操作,例如:
nvcc -Xptxas -v -arch=sm_20 -G -maxrregcount=20 -o t145 t145.cu
最后一種情況的目的是使(每個線程的寄存器*每個塊的線程)小於所使用GPU的每個塊的最大寄存器。 典型的CC 2.0 GPU每塊最多具有32768個寄存器(您可以通過deviceQuery示例找到 )。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.