2017-09-17 121 views
1

我有一些使用PGI编译器编译的OpenACC加速C++代码。事情似乎有效,所以现在我想用分析信息来发挥效率。解释PGI_ACC_TIME输出

我通过设置产生一些定时信息:

export PGI_ACC_TIME=1 

,然后运行该程序。

的输出结果如下:

-bash-4.2$ ./a.out 
libcupti.so not found 

Accelerator Kernel Timing data 
    PGI_ACC_SYNCHRONOUS was set, disabling async() clauses 
/home/myuser/myprogram.cpp 
    _MyProgram NVIDIA devicenum=1 
    time(us): 97,667 
    75: data region reached 2 times 
     75: data copyin transfers: 3 
      device time(us): total=101 max=82 min=9 avg=33 
    76: compute region reached 1000 times 
     76: kernel launched 1000 times 
      grid: [1938] block: [128] 
      elapsed time(us): total=680,216 max=1,043 min=654 avg=680 
    95: compute region reached 1000 times 
     95: kernel launched 1000 times 
      grid: [1938] block: [128] 
      elapsed time(us): total=487,365 max=801 min=476 avg=487 
    110: data region reached 2000 times 
     110: data copyin transfers: 1000 
      device time(us): total=6,783 max=140 min=3 avg=6 
     125: data copyout transfers: 1000 
      device time(us): total=7,445 max=190 min=6 avg=7 

real 0m3.864s 
user 0m3.499s 
sys  0m0.348s 

它提出了一些问题:

  1. 我看到time(us): 97,667在顶部。这个好像是总共的时间,但是在底部,我看到了real 0m3.864s。为什么会有这样的差异?

  2. 如果总数为time(us): 97,667,为什么它比下降的值小很多,如elapsed time(us): total=680,216

  3. 该内核包括行(elapsed time(us): total=680,216 max=1,043 min=654 avg=680)运行1000次。是基于内核的每次运行值的最大值,最小值和平均值?

  4. 由于[grid][block]值可能会有所不同,经过的总值仍然是热点的一个很好的指标?

  5. 对于数据区域(device time(us): total=6,783)是测量转移时间还是花在处理数据(准备转移,收货后操作)上的全部时间?

  6. 行编号很奇怪。例如,我的程序中的第76行显然是一个for循环,第95行是一个大括号,而第110行是一个变量定义。行号应该被解释为“最接近指定行号的循环”,或以其他方式?

  7. 76处的内核包含95处的内核。计算的时间是76,包括在95中花费的时间吗?如果是这样,有没有一种方便的方法来查找在核心中花费的时间减去所有子核心的时间?

(其中的一些问题是有点肛门固,但我还没有找到这个文件,所以我想我是彻底的。)这里的问题的

回答

1

部分原因是运行时无法找到CUDA分析库(libcupti.so),因此您只能看到PGI CPU侧分析而不是设备分析。 PGI使用编译器($ PGI/[linux86-64 | linuxpower]/2017/cuda/[7.5 | 8.0]/lib64)下载了libcupti.so库,但这是可选的安装,因此您可能没有安装它你在跑步。 CUPTI还附带了CUDA SDK,因此如果系统安装了CUDA,则可以尝试设置您的LD_LIBRARY_PATH。在我的系统上,它安装在“/opt/cuda-8.0/extras/CUPTI/lib64/”中。

缺失的CUPTI库就是为什么你看到文件时间不好的时候,97,667。另外,由于你错过了CUPTI,你看到的时间是从主机测量的。通过CUPTI,除了时间流逝之外,您还可以看到每个内核的设备时间。经过时间和设备时间之间的差异是每个内核的启动开销。

最大值,最小值和平均值是基于内核的每次运行值吗?

是的。

4.由于[网格]和[块]值可能会有所不同,经过的总值仍然是一个很好的热点指标?

我倾向于先看看平均时间,因为通常有更多的机会来调整这些循环。如果你改变每次核心迭代的工作量(即网格大小的变化),那么它可能不是有用的,但是一个好的起点。

现在,如果您的平均值较低但调用次数较多,则耗用时间可能会受内核启动开销的影响。在这种情况下,我会考虑是否可以合并循环或将更多工作推送到每个循环中。

5.对于数据区域(设备时间(美国):总= 6783)是测量传输时间或者整个时间花费处理数据 (准备传送,接收后操作)?

只是数据传输时间。对于开销,您需要使用PGPROF/NVPROF。

6.行编号很奇怪。例如,我的程序中的第76行显然是一个for循环,第95行是一个大括号,第110行是一个 变量定义。行号应该被解释为“最接近指定行号的循环 ”,或者其他一些其他的 方式?

这是因为代码已经过优化,所以行号可能有点偏离,但它应该与编译器反馈消息(-Minfo = accel)的行号相对应。所以“循环最紧密......”选项应该是正确的。

+0

谢谢!我追踪了'libcupti.so',事实上,现在时机更加明智了。我还在上面添加了第7个问题:“76处的内核包含95的内核。是否计算了包含95个时间在内的76个时间?如果是这样,是否有一种方便的方法来查找在内核中花费的时间减去所有子核的时间?“ – Richard

+0

问题7我不清楚。这两个内核是独立的计算区域,所以76不能包含95.你的意思是在76内核中有一个设备子程序调用吗?如果是这样,最接近你可以使用PGPROF源代码反汇编视图(http://www.pgroup.com/resources/docs/17.7/x86/profiler-users-guide/index.htm#source-assembly-视图),它使用采样来获取行级别信息。务必使用“-Muda = lineinfo”进行编译,以确保编译器保留行信息。此外,抽样可能会侵入,所以时间可能会更长。 –