0

正如标题中提到的,我发现函数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.widthSize.height都是4800,耗时cudaMallocPitch()约150-160ms(以防万一多次测试),cudaMemcpy2D()耗时约50ms。

CPU和GPU之间的内存带宽似乎不可能如此有限,但是我看不到代码中的任何错误,那是什么原因呢?

顺便说一句,我使用的硬件是 Intel I7-4770K CPU 和 Nvidia Geforce GTX 780(相当不错的硬件,没有错误)。

4

1 回答 1

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 传输。

于 2014-06-18T11:18:57.723 回答