正如标题中所提到的,我发现cudaMallocPitch()
的功能消耗了大量时间,cudaMemcpy2D()
消耗了相当长的时间。
以下是我正在使用的代码:
cudaMallocPitch((void **)(&SrcDst), &DeviceStride, Size.width * sizeof(float), Size.height);
cudaMemcpy2D(SrcDst, DeviceStride * sizeof(float),
ImgF1, StrideF * sizeof(float),
Size.width * sizeof(float), Size.height,
cudaMemcpyHostToDevice);
在实施过程中,Size.width
和Size.height
均为4800. cudaMallocPitch()
的耗时约为150-160毫秒(发生意外事件时多次测试),cudaMemcpy2D()
消耗大约50ms。
CPU和GPU之间的内存带宽似乎不太可能如此受限,但我看不到代码中的任何错误,那么原因是什么?
顺便说一句,我使用的硬件是Intel I7-4770K CPU和Nvidia Geforce GTX 780(非常好的硬件没有错误)。
答案 0 :(得分:3)
这里有许多因素可能影响绩效。
关于cudaMallocPitch
,如果它恰好是您程序中的第一个cuda调用,则会产生额外的开销。
关于cudaMemcpy2D
,这是通过一系列单独的memcpy操作完成的,每个2D区域一行(即4800个单独的DMA操作)。与普通cudaMemcpy
操作(在单个DMA传输中传输整个数据区域)相比,这必然会产生额外的开销。此外,峰值传输速度仅在主机端存储器缓冲器被固定时实现。最后,您没有说明您的平台的任何信息。如果你在Windows上,那么WDDM将干扰此操作的完整传输性能,我们不知道你在哪种PCIE链接。
4800 * 4800 * 4 / 0.050 = 1.84GB / s,这是~3GB / s的重要部分,大致可用于跨PCIE 2.0的非固定传输。从上面列出的其他因素可以很容易地解释从3GB减少到1.84GB。
如果您想要完全传输性能,请使用固定内存,不要使用音调/ 2D传输。