我编写了一个cuda程序来对大型数组进行一些操作。但是,当我将该数组传递给cuda内核时,线程不会访问其所有元素。下面有一个简单的程序来说明我的用例:
#include <stdio.h>
#include <stdlib.h>
__global__
void kernel(int n){
int s = threadIdx.x + blockIdx.x*blockDim.x;
int t = blockDim.x*gridDim.x;
for(int i=s;i<n;i+=t){
printf("%d\n",i); //printing index of array which is being accessed
}
}
int main(void){
int i,n = 10000; //array_size
int blockSize = 64;
int numBlocks = (n + blockSize - 1) / blockSize;
kernel<<<numBlocks, blockSize>>>(n);
cudaDeviceSynchronize();
}
我尝试使用不同的blockSize = 256, 128, 64, etc
,它不是打印数组的所有索引。理想情况下,它应打印0 to n-1
的任何排列,但是它要打印较少的(<n)
数字。
如果numBlocks
和blockSize
均为1,则它正在访问所有元素。并且如果数组大小小于4096,那么它也在访问所有元素。
答案 0 :(得分:3)
实际上,所有值都在当前情况下被打印。但由于输出控制台的缓冲区限制,您可能无法看到所有这些内容。尝试增加输出控制台的缓冲区大小。
此外,请记住,内核中的printf
调用是无序执行的。另外,documentation中说明了设备上printf
缓冲区的局限性。
答案 1 :(得分:2)
使用更好的调试技术!您的代码正常运行
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <stdlib.h>
__global__
void kernel(int* in, int n){
int s = threadIdx.x + blockIdx.x*blockDim.x;
int t = blockDim.x*gridDim.x;
for (int i = s; i<n; i += t){
in[i] = 1; //printing index of array which is being accessed
}
}
int main(void){
int i, n = 10000; //array_size
int blockSize = 64;
int numBlocks = (n + blockSize - 1) / blockSize;
int* d_res,*h_res;
cudaMalloc(&d_res, n*sizeof(int));
h_res = (int*)malloc(n*sizeof(int));
kernel << <numBlocks, blockSize >> >(d_res, n);
cudaDeviceSynchronize();
cudaMemcpy(h_res, d_res, n*sizeof(int), cudaMemcpyDeviceToHost);
int sum = 0;
for (int i = 0; i < n; i++)
sum += h_res[i];
printf("%d", sum);
}