使用 CudaEventElapsedTime 测量 Cuda 内核时间

Cuda kernel time measurement with CudaEventElapsedTime

我有 NVS 5400M,我正在尝试为矩阵(实例 1000 x 1000)上的 cuda 添加获得可靠的时间测量结果。

__global__ void MatAdd(int** A, int** B, int** C) {
int i = threadIdx.x;
int j = threadIdx.y;
C[i][j] = A[i][j] + B[i][j]; }

我正在做这样的测量:

int numBlocks = 1;
dim3 threadsPerBlock(1000, 1000);

float time;
cudaEvent_t start, stop;
cudaEventCreate(&start);
cudaEventCreate(&stop);
cudaEventRecord(start, 0);

MatAdd <<<numBlocks, threadsPerBlock>>>(pA, pB, pC);

cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
cudaEventElapsedTime(&time, start, stop);

cout << setprecision(10) << "GPU Time [ms] " << time << endl;

结果是:0.001504000043 ms,比较小。我的问题是我做对了吗?

你的时间是正确的,但你对 CUDA 的一般使用是错误的。

这是非法的:

dim3 threadsPerBlock(1000, 1000);

CUDA 内核限制为每个块最多 1024 个线程,但您请求每个块 1000x1000 = 1,000,000 个线程。

因此,您的内核实际上并未启动:

MatAdd <<<numBlocks, threadsPerBlock>>>(pA, pB, pC);

所以测量的时间很短。

建议您使用 proper cuda error checking 和 运行 对 cuda-memcheck 进行测试,以确保没有报告 运行 时间错误(我猜现在你甚至不知道您的代码报告的错误 - 您必须检查它们。)

由于您没有显示完整的代码,我不会尝试找出可能存在的所有其他问题,但必须重构您的内核代码才能处理 1000x1000 数组正确地,将双指针(例如 int** A)参数传递给内核比单个指针或 "flat" 数组要困难得多。