CUDA基准测试中的执行时间问题



我正在尝试分析一些CUDA Rodinia基准测试,包括SM和内存利用率、功耗等。为此,我同时执行基准测试和分析器,它实际上生成一个pthread来使用NVML库分析GPU的执行情况。

问题是,如果我不调用分析器,那么基准测试的执行时间要比使用分析器执行基准测试的情况高得多(大约3倍)。CPU的频率缩放调控器是用户空间,所以我认为CPU的频率不会改变。是由于GPU频率的闪烁吗?下面是分析器的代码。

#include <pthread.h>
#include <stdio.h>
#include "nvml.h"
#include "unistd.h"
#define NUM_THREADS     1
void *PrintHello(void *threadid)
{
   long tid;
   tid = (long)threadid;
  // printf("Hello World! It's me, thread #%ld!n", tid);
nvmlReturn_t result;
nvmlDevice_t device;
nvmlUtilization_t utilization;
nvmlClockType_t jok;
unsigned int device_count, i,powergpu,clo;
char version[80];
result = nvmlInit();
result = nvmlSystemGetDriverVersion(version,80);
printf("n Driver version: %s nn", version);
result = nvmlDeviceGetCount(&device_count);
printf("Found %d device%snn", device_count,
device_count != 1 ? "s" : "");
printf("Listing devices:n");
result = nvmlDeviceGetHandleByIndex(0, &device);
while(1)
{
result = nvmlDeviceGetPowerUsage(device,&powergpu );
result = nvmlDeviceGetUtilizationRates(device, &utilization);
printf("n%dn",powergpu);


        if (result == NVML_SUCCESS)
        {
           printf("%dn",  utilization.gpu);
           printf("%dn",  utilization.memory);
        }
result=nvmlDeviceGetClockInfo(device,NVML_CLOCK_SM,&clo);
if(result==NVML_SUCCESS)
{
printf("%dn",clo);
}
usleep(500000);
}

pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
   pthread_t threads[NUM_THREADS];
int rc;
   long t;
   for(t=0; t<NUM_THREADS; t++){
      printf("In main: creating thread %ldn", t);
      rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
      if (rc){
         printf("ERROR; return code from pthread_create() is %dn", rc);
         exit(-1);
      }
   }
   /* Last thing that main() should do */
   pthread_exit(NULL);
}

随着你的分析器的运行,GPU(s)正在被拉出他们的睡眠状态(由于访问nvml API,这是从GPU查询数据)。这使得它们对CUDA应用程序的响应更快,因此如果你对整个应用程序执行计时(例如使用linux time命令),应用程序似乎运行得"更快"。

一种解决方案是使用nvidia-smi命令将gpu置于"持久模式"(使用nvidia-smi --help来获得命令行帮助)。

另一个解决方案是在应用程序内部进行计时,并从计时测量中排除CUDA启动时间,可能通过在计时开始之前执行cudaFree(0);等CUDA命令。

最新更新