我有一些使用 PGI 编译器编译的 OpenACC 加速 C++ 代码。事情似乎很奏效,所以现在我想用分析信息来提高效率。
我通过设置生成一些时间信息:
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 次。最大值、最小值和平均值是否基于内核的每次运行值?由于
[grid]
和[block]
值可能会有所不同,经过的总值仍然是热点的良好指标吗?对于数据区域 (
device time(us): total=6,783
) 是测量传输时间还是处理数据所花费的全部时间(准备传输、接收后操作)?行号很奇怪。例如,我的程序中的第 76 行显然是一个
for
循环,第 95 行是一个右大括号,第 110 行是一个变量定义。行号应该被解释为“最接近指定行号的循环”,还是以其他方式?76 的内核包含 95 的内核。计算 76 的时间是否包括在 95 中花费的时间?如果是这样,是否有一种方便的方法可以找到在内核中花费的时间减去所有子内核的时间?
(其中一些问题有点难以理解,但我还没有找到这方面的文档,所以我想我会很彻底。)