0

我的矩阵加法示例:

 __global__ void matrix_add(float *a, float*b, float *c, int N)
{
    int index;
    int Row = blockIdx.y * blockDim.y + threadIdx.y;
    int Col = blockIdx.x * blockDim.x + threadIdx.x;

    int index = Row * N + Col;      // N is the order of the square matrix

    cd[index]= ad[index] + bd[index];

}

我可以在上面的内核中使用 printf 或任何其他类似的功能吗?这样我就不需要将数据从设备传输到主机内存(即cudaMemcpyDeviceToHost)。如果是,那怎么办?如果没有,那为什么不呢?

4

2 回答 2

1

您可以使用 printf(..) 但仅适用于 cc2.x 或更高版本。
您可以在 CUDA 编程指南附录 B.16 中阅读更多相关信息。

于 2012-10-19T10:52:01.800 回答
1

在不将数据复制回主机的情况下显示内核结果的唯一方法是使用其中一种图形互操作模式。CUDA 支持 OpenGL 和 Direct3D 互操作性。CUDA 编程指南中有关于如何使用这些的示例。

__device__ printf()(计算能力 >= 2.0)和__device__ cuPrintf()(计算能力 < 2.0)都导致将打印的字符串隐式复制回主机。很可能,这两者也会导致所有尝试同时打印的内核的隐式序列化,因此通常仅用于调试。

如果您在调试器中运行 CUDA 应用程序,您在调试器中查看的设备值也已隐式复制到主机。

从您的问题中不清楚您是要避免将值复制回主机还是只想避免必须显式复制值。如果是后者,那么这些__device__ printf()方法对于在主机上显示少量结果是可行的。避免显式复制值的另一种方法是使用thrust::device_vector. Thrust 是 CUDA 附带的一个库。它的灵感来自 C++ STL。您可以在主机端读取和写入device_vector,并在后台对设备执行隐式复制。

您还可以使用所谓的映射内存来进行隐式复制。使用映射内存,CUDA 硬件可以在内核需要时在主机和设备之间执行内存的隐式复制。

这一切的原因是主机和设备之间的副本非常昂贵。通常,它们占用了总计算时间的很大一部分。因此,有必要仔细考虑这些副本何时以及如何发生。我提到的所有技术都有不同的性能影响,如何最好地处理复制是特定于应用程序的。

于 2012-10-19T15:17:14.427 回答