3

为了测试设备上的 printf() 调用,我编写了一个简单的程序,它将一个中等大小的数组复制到设备并将设备数组的值打印到屏幕上。尽管数组已正确复制到设备,但 printf() 函数无法正常工作,从而丢失了前几百个数字。代码中的数组大小为 4096。这是一个错误还是我没有正确使用这个函数?提前感谢。

编辑:我的 gpu 是 GeForce GTX 550i,计算能力 2.1

我的代码:

#include<stdio.h>
#include<stdlib.h>
#define N 4096

__global__ void Printcell(float *d_Array , int n){
    int k = 0;

    printf("\n=========== data of d_Array on device==============\n");
    for( k = 0; k < n; k++ ){
        printf("%f  ", d_Array[k]);
        if((k+1)%6 == 0) printf("\n");
    }
    printf("\n\nTotally %d elements has been printed", k);
}

int main(){

    int i =0;

    float Array[N] = {0}, rArray[N] = {0};
    float *d_Array;
    for(i=0;i<N;i++)
        Array[i] = i;


    cudaMalloc((void**)&d_Array, N*sizeof(float));
    cudaMemcpy(d_Array, Array, N*sizeof(float), cudaMemcpyHostToDevice);
    cudaDeviceSynchronize();
    Printcell<<<1,1>>>(d_Array, N);    //Print the device array by a kernel
    cudaDeviceSynchronize();

    /* Copy the device array back to host to see if it was correctly copied */   
    cudaMemcpy(rArray, d_Array, N*sizeof(float), cudaMemcpyDeviceToHost);

    printf("\n\n");

    for(i=0;i<N;i++){
        printf("%f  ", rArray[i]);
        if((i+1)%6 == 0) printf("\n");
    }
}
4

1 回答 1

13

来自设备的 printf 队列有限。它适用于小规模调试式输出,而不是大规模输出。

参考程序员指南

printf() 的输出缓冲区在内核启动之前设置为固定大小(请参阅关联的主机端 API)。它是循环的,如果在内核执行期间产生的输出多于缓冲区可以容纳的输出,则旧的输出将被覆盖。

您的内核中 printf 输出超出了缓冲区,因此在缓冲区转储到标准 I/O 队列之前,第一个打印的元素丢失(覆盖)。

链接的文档表明缓冲区大小也可以增加。

于 2013-03-14T23:12:01.360 回答