我有一些OpenACC加速的C ++代码,我使用PGI编译器编译。事情似乎正在起作用,所以现在我想用分析信息来发挥效率打击鼹鼠。
我通过设置:
生成一些时间信息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
提出了一些问题:
我在顶部看到time(us): 97,667
。这个似乎就像一个总时间,但是,在底部,我看到real 0m3.864s
。为什么会有这样的差异?
如果time(us): 97,667
是总数,为什么它比下限值小得多,例如elapsed time(us): total=680,216
?
包含行(elapsed time(us): total=680,216 max=1,043 min=654 avg=680
)的内核运行了1000次。 max,min和avg值是否基于内核的每次运行值?
由于[grid]
和[block]
值可能会有所不同,经过的总值是否仍然是热点的良好指标?
对于数据区域(device time(us): total=6,783
),是测量转移时间还是处理数据所花费的整个时间(准备转移,收货后操作)?
行编号很奇怪。例如,我的程序中的第76行显然是for
循环,第95行是闭括号,第110行是变量定义。行号是否应解释为"循环最接近指示的行号"或以其他方式?
76处的内核包含95的内核。计算的时间是否为76,包括在95中花费的时间?如果是这样,有没有一种方便的方法来查找在内核中花费的时间减去所有子内核的时间?
(其中一些问题有点肛门保留,但我还没有找到这方面的文件,所以我认为我是彻底的。)
答案 0 :(得分:1)
这里的部分问题是运行时无法找到CUDA分析库(libcupti.so),因此您只能看到PGI CPU端分析而不是设备分析。 PGI将libcupti.so库与编译器一起发布(在$ PGI / [linux86-64 | linuxpower] / 2017 / cuda / [7.5 | 8.0] / lib64下),但这是一个可选安装,因此您可能没有在系统上安装它你正在跑步。 CUPTI还附带了CUDA SDK,因此如果系统安装了CUDA,您可以尝试在那里设置LD_LIBRARY_PATH。在我的系统上,它安装在" /opt/cuda-8.0/extras/CUPTI/lib64 /"。
缺少CUPTI库是您查看文件时间错误时间97,667的原因。此外,由于您错过了CUPTI,您正在从主机测量您所看到的时间。使用CUPTI,除了经过的时间外,您还可以看到每个内核的设备时间。经过时间和设备时间之间的差异是每个内核的启动开销。
max,min和avg值是否基于内核的每次运行值?
是
4.由于[grid]和[block]值可能会有所不同,经过的总值是否仍然是热点的良好指标?
我倾向于首先查看平均时间,因为通常有更多机会来调整这些循环。如果你改变每个内核迭代的工作量(即网格大小的变化),那么它可能不是那么有用,而是一个很好的起点。
现在,如果你的平均值很低但很多次调用,那么经过的时间可能会受到内核启动开销的支配。在这种情况下,我会查看是否可以组合循环或将更多工作推入每个循环。
5.对于数据区域(设备时间(us):总计= 6,783)是测量传输时间或处理数据所花费的整个时间 (准备转账,收货后运营)?
只是数据传输时间。对于开销,您需要使用PGPROF / NVPROF。
6.线路编号很奇怪。例如,我的程序中的第76行显然是for循环,第95行是紧密支撑,而第110行是a 变量定义。行号应该被解释为"循环 最接近指示的行号"或其他一些 方式是什么?
这是因为代码已经过优化,所以行号可能有点偏,但它应该与编译器反馈消息的行号(-Minfo = accel)相对应。所以"循环最紧密......"选项应该是正确的。