cuda内核未访问数组的所有元素

时间:2018-10-09 11:00:15

标签: c cuda nvidia

我编写了一个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)数字。

如果numBlocksblockSize均为1,则它正在访问所有元素。并且如果数组大小小于4096,那么它也在访问所有元素。

2 个答案:

答案 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);
}