我的矩阵添加示例:
__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
)。如果是,那怎么样?如果不是那么为什么不呢?
答案 0 :(得分:1)
您可以使用printf(..)但仅适用于cc2.x或更高版本 您可以在CUDA编程指南附录B.16中阅读更多相关内容。
答案 1 :(得分: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硬件可以在内核需要的主机和设备之间执行内存的隐式复制。
所有这一切的原因是主机和设备之间的副本非常昂贵。通常,它们占用总计算时间的很大一部分。因此,有必要仔细考虑这些副本何时以及如何发生。我提到的所有技术都有各种性能影响,如何最好地处理复制是特定于应用程序的。