使用 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" 数组要困难得多。
我有 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" 数组要困难得多。