测量CUDA内核运行时间时是否需要预热代码?

测量CUDA内核运行时间时是否需要预热代码?,cuda,gpu,Cuda,Gpu,第85页: intmain() { ...... //运行预热内核以消除开销 大小/单位/单位,iElaps; cudaDeviceSynchronize(); iStart=秒(); 预热(d_C); cudaDeviceSynchronize(); iElaps=秒()-iStart; printf(“预热>经过%d秒\n”,网格.x,块.x,iElaps); //运行内核1 iStart=秒(); mathKernel1(d_C); cudaDeviceSynchronize(); iEl

第85页:

intmain()
{
......
//运行预热内核以消除开销
大小/单位/单位,iElaps;
cudaDeviceSynchronize();
iStart=秒();
预热(d_C);
cudaDeviceSynchronize();
iElaps=秒()-iStart;
printf(“预热>经过%d秒\n”,网格.x,块.x,iElaps);
//运行内核1
iStart=秒();
mathKernel1(d_C);
cudaDeviceSynchronize();
iElaps=秒()-iStart;
printf(“mathKernel1>已用%d秒\n”,grid.x,block.x,iElaps);
//运行内核3
iStart=秒();
mathKernel2(d_C);
cudaDeviceSynchronize();
iElaps=秒()-iStart;
printf(“mathKernel2>已用%d秒\n”,grid.x,block.x,iElaps);
//运行内核3
iStart=seconds();
mathKernel3(d_C);
cudaDeviceSynchronize();
iElaps=秒()-iStart;
printf(“mathKernel3>经过%d秒\n”,grid.x,block.x,iElaps);
......
}
我们可以看到在测量不同内核的运行时间之前有一个预热

从中,我知道原因是:

如果它们是非显示卡,很可能是驱动程序在一段时间不活动后自动关机。因此,您在第一次运行中看到的很可能是只发生一次的初始化开销


因此,如果我的GPU卡长时间不处于非活动状态,例如,我只是用它来运行一些程序,它应该不需要运行任何预热代码。我的理解正确吗?

除了GPU处于省电状态外,内核首次启动可能比进一步运行慢的原因还有很多:

  • 即时编译
  • 内核到GPU内存的传输
  • 缓存内容
出于这些原因,如果您对连续内核启动所达到的持续速度感兴趣,那么在定时内核运行之前至少执行一次“预热运行”总是一个好的做法


但是,如果您心中有一个特定的应用程序和用例,那么在相关情况下对该应用程序进行基准测试总是有意义的。不过,要准备好,在这种不太可控的测量中,运行时会有更大的变化。

您介意分享任何支持您答案的官方技术文档(由任何硬件供应商提供)吗?
int main()
{
    ......
    // run a warmup kernel to remove overhead
    size_t iStart,iElaps;
    cudaDeviceSynchronize();
    iStart = seconds();
    warmingup<<<grid, block>>> (d_C);
    cudaDeviceSynchronize();
    iElaps = seconds() - iStart;
    printf("warmup <<< %4d %4d >>> elapsed %d sec \n",grid.x,block.x, iElaps );

    // run kernel 1
    iStart = seconds();
    mathKernel1<<<grid, block>>>(d_C);
    cudaDeviceSynchronize();
    iElaps = seconds() - iStart;
    printf("mathKernel1 <<< %4d %4d >>> elapsed %d sec \n",grid.x,block.x,iElaps );

    // run kernel 3
    iStart = seconds();
    mathKernel2<<<grid, block>>>(d_C);
    cudaDeviceSynchronize();
    iElaps = seconds () - iStart;
    printf("mathKernel2 <<< %4d %4d >>> elapsed %d sec \n",grid.x,block.x,iElaps );

    // run kernel 3
    iStart = seconds ();
    mathKernel3<<<grid, block>>>(d_C);
    cudaDeviceSynchronize();
    iElaps = seconds () - iStart;
    printf("mathKernel3 <<< %4d %4d >>> elapsed %d sec \n",grid.x,block.x,iElaps);
    ......
}