4

我正在研究一个简单的 cuda 程序,在该程序中我发现 90% 的时间都来自一个从设备到主机的 cudamemcpy 语句。该程序在 600-700 微秒内将大约 2MB 的数据从主机传输到设备,并在 10 毫秒内将 4MB 的数据从设备复制回主机。我的程序花费的总时间是 13 毫秒。我的问题是,为什么从设备到主机和主机到设备的两次复制存在不对称性。是不是因为 cuda 开发人员认为复制回来的字节数通常会更小。我的第二个问题是有什么办法可以规避它。

我正在使用具有 343 个内核和 1GB 内存的 Fermi GTX560 显卡。

4

1 回答 1

2

CUDA 功能的时序与 CPU 有点不同。首先确保你没有在应用程序开始时调用 CUDA 函数来考虑 CUDA 的初始化成本,否则它可能会在你开始计时时被初始化。

int main (int argc, char **argv) {
   cudaFree(0);
   ....//cuda is initialized..

}

像这样使用 Cutil 计时器

unsigned int timer;
cutCreateTimer(&timer);
cutStartTimer(timer);

//your code, to assess elapsed time..

cutStopTimer(timer);
printf("Elapsed: %.3f\n", cutGetTimerValue(timer));
cutDeleteTimer(timer);

现在,在这些初步步骤之后,让我们看看问题所在。当一个内核被调用时,CPU 部分只会在调用被传递到 GPU 之前停止。GPU 将继续执行,而 CPU 也会继续执行。如果你调用 cudaThreadSynchronize(..),那么 CPU 将停止直到 GPU 完成当前调用。cudaMemCopy 操作也需要 GPU 完成其执行,因为需要内核填充的值。

kernel<<<numBlocks, threadPerBlock>>>(...);

cudaError_t err = cudaThreadSynchronize();
if (cudaSuccess != err) {
  fprintf(stderr, "cudaCheckError() failed at %s:%i : %s.\n", __FILE__, __LINE__, cudaGetErrorString( err ) );
  exit(1);
}

//now the kernel is complete..
cutStopTimer(timer);

所以在调用停止定时器函数之前放置一个同步。如果在内核调用之后放置内存副本,那么内存副本的经过时间将包括内核执行的某些部分。所以memCopy操作可能会放在定时操作之后。

还有一些分析器计数器可用于评估内核的某些部分。

如何分析 cuda 内核的全局内存事务数量?

您如何分析和优化 CUDA 内核?

于 2012-09-02T16:23:39.130 回答