首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

评估 Linux on POWER 的性能(3)

评估 Linux on POWER 的性能(3)

性能评估的策略初始性能评估是通过检查 CPU 周期利用率计数器找到程序热点。要在 POWER7 上做到这一点,则需要监视 表 2 中列出的事件:
表 2. POWER7 CPU 周期利用率计数器计数器描述PM_CYCProcessor CyclesPM_INST_CMPL已完成的 PowerPC Instructions 数量PM_RUN_CYC可以通过运行锁存器得到控制的 Processor Cycles。操作系统使用运行锁存器来表示它们何时在做有益的工作。运行锁存器通常在 OS 的空闲循环中被清除。通过运行锁存器进行控制,可以过滤出空闲循环。PM_RUN_INST_CMPL已完成的运行指令数量
运行配有这些事件的 OProfile 将显示处理器在某个符号中花费的总时间。下面是一个使用 IBM Advance Toolchain 5.0 for POWER编译的 SPECcpu2006 基准套件的 403.gcc 组件的示例概要文件输出。以下是 opreport -l 命令的输出。
清单 5. 403.gcc 基准的 'opreport -' 输出(计数器 PM_CYC_GRP1 和 PM_INST_CMPL_GRP1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
CPU: ppc64 POWER7, speed 3550 MHz (estimated)
Counted PM_CYC_GRP1 events ((Group 1 pm_utilization) Processor Cycles) with a unit
mask of 0x00 (No unit mask) count 500000
Counted PM_INST_CMPL_GRP1 events ((Group 1 pm_utilization) Number of PowerPC
Instructions that completed.) with a unit mask of 0x00 (No unit mask) count 500000

samples  %        samples  %        image name      app name        symbol name
204528    7.9112  32132     1.3848  gcc_base.none   gcc_base.none   reg_is_remote_cons\
                                                                    tant_p.isra.3.part.4
125218    4.8434  246710   10.6324  gcc_base.none   gcc_base.none   bitmap_operation
113190    4.3782  50950     2.1958  libc-2.13.so    libc-2.13.so    memset
90316     3.4934  22193     0.9564  gcc_base.none   gcc_base.none   compute_transp
89978     3.4804  11753     0.5065  vmlinux         vmlinux         .pseries_dedicated_\
                                                                    idle_sleep
88429     3.4204  130166    5.6097  gcc_base.none   gcc_base.none   bitmap_element_\
                                                                    allocate
67720     2.6194  41479     1.7876  gcc_base.none   gcc_base.none   ggc_set_mark
56613     2.1898  89418     3.8536  gcc_base.none   gcc_base.none   canon_rtx
53949     2.0868  6985      0.3010  gcc_base.none   gcc_base.none   delete_null_\
                                                                    pointer_checks
51587     1.9954  26000     1.1205  gcc_base.none   gcc_base.none   ggc_mark_rtx_\
                                                                    children_1
48050     1.8586  16086     0.6933  gcc_base.none   gcc_base.none   single_set_2
47115     1.8224  33772     1.4555  gcc_base.none   gcc_base.none   note_stores




清单 6. 403.gcc 基准的 'opreport -' 输出(计数器 PM_RUN_CYC_GRP1 和 PM_RUN_INST_CMPL_GRP1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Counted PM_RUN_CYC_GRP1 events ((Group 1 pm_utilization) Processor Cycles gated by the
run latch.  Operating systems use the run latch to indicate when they are doing useful
work.  The run
latch is typically cleared in the OS idle loop.  Gating by the run latch filters out
the idle loop.) with a unit mask of 0x00 (No unit mask) count 500000
Counted PM_RUN_INST_CMPL_GRP1 events ((Group 1 pm_utilization) Number of run
instructions completed.) with a unit mask of 0x00 (No unit mask) count 500000

samples  %        samples  %        samples  %      app name        symbol name
204538    8.3658  32078     1.3965  gcc_base.none   gcc_base.none   reg_is_remote_consta\
                                                                    nt_p.isra.3.part.4
124596    5.0961  252227   10.9809  gcc_base.none   gcc_base.none   bitmap_operation
112326    4.5943  50890     2.2155  libc-2.13.so    libc-2.13.so    memset
90312     3.6939  21882     0.9527  gcc_base.none   gcc_base.none   compute_transp
0              0  0              0  vmlinux         vmlinux         .pseries_dedicated\
                                                                    _idle_sleep
88894     3.6359  124831    5.4346  gcc_base.none   gcc_base.none   bitmap_element_all\
                                                                    ocate
67995     2.7811  41331     1.7994  gcc_base.none   gcc_base.none   ggc_set_mark
56460     2.3093  89484     3.8958  gcc_base.none   gcc_base.none   canon_rtx
54076     2.2118  6965      0.3032  gcc_base.none   gcc_base.none   delete_null_pointer\
                                                                    _checks
51228     2.0953  26057     1.1344  gcc_base.none   gcc_base.none   ggc_mark_rtx_childr\
                                                                    en_1
48057     1.9656  16005     0.6968  gcc_base.none   gcc_base.none   single_set_2
47160     1.9289  33766     1.4700  gcc_base.none   gcc_base.none   note_stores




每个被监视的事件在输出中都是用一对列来表示的。第一列显示针对指定事件从 PCM 收集的样品数量,第二列显示它所表示的样本总数的百分比。正如在该报告所见,符号 reg_is_remote_constant_p 消耗了最多的处理器周期,并且是代码优化的一个很好的候选。此概要文件仅标识哪个符号消耗了最多的 CPU 周期,没有标识处理器流水线是否被充分利用。您可以通过比较计数器的结果,查看流水线的利用率。
查看计数器 PM_INST_CMPL_GRP1(第二对列);符号 bitmap_operation 显示出了比符号 reg_is_remote_constant_p 更高的百分比。完成每个处理器指令的时候,此性能计数器都会递增,而 PM_CYC_GRP1 仅意味着已被利用的 CPU 周期数量。如果没有进一步的分析,这可能表示符号 reg_is_remote_constant_p 包含比符号 bitmap_operation 更多的 CPU 停滞,因为为符号 reg_is_remote_constant_p 完成的指令数量明显更少一些。此概要文件提供了一个有关后续优化工作应该集中在哪个符号上的初始提示。
在您开始挖掘和破解代码之前,应该先了解工作负载是 CPU 密集型的还是内存密集型的,这样做明智之举。这很重要,因为每种工作负载类型的优化方法都非常不同。例如,最常见的内存访问来自缓存或主内存(与 NUMA 远程节点内存访问相反),性能几乎完全依赖于所使用的算法和数据结构。要调查内存访问模式,可以监视 表 3 中的以下两个性能计数器:
表 3. POWER7 内存利用率计数器计数器描述PM_MEM0_RQ_DISP读取为主内存分派的请求PM_MEM0_WQ_DISP写入为主内存分派的请求
这两个计数器可以指示内存访问模式主要来自内存读取、写入,还是两者兼而有之。使用和以前一样的基准(来自 SPECcpu2006 的 403.gcc),概要文件显示如下:
清单 7. 403.gcc 基准的 'opreport -' 输出(计数器 PM_MEM0_RQ_DISP 和 PM_MEM0_WQ_DISP)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CPU: ppc64 POWER7, speed 3550 MHz (estimated)
Counted PM_MEM0_RQ_DISP_GRP59 events ((Group 59 pm_nest2)  Nest events (MC0/MC1/PB/GX),
Pair0 Bit1) with a unit mask of 0x00 (No unit mask) count 1000
Counted PM_MEM0_WQ_DISP_GRP59 events ((Group 59 pm_nest2)  Nest events (MC0/MC1/PB/GX),
Pair3 Bit1) with a unit mask of 0x00 (No unit mask) count 1000
samples  %        samples  %        app name                 symbol name
225841   25.8000  289       0.4086  gcc_base.none            reg_is_remote_constant_p.\
                                                             isra.3.part.4
90068    10.2893  2183      3.0862  gcc_base.none            compute_transp
54038     6.1733  308       0.4354  gcc_base.none            single_set_2
32660     3.7311  2006      2.8359  gcc_base.none            delete_null_pointer_checks
26352     3.0104  1498      2.1178  gcc_base.none            note_stores
21306     2.4340  1950      2.7568  vmlinux                  .pseries_dedicated_idle_sl\
                                                             eep
18059     2.0631  9186     12.9865  libc-2.13.so             memset
15867     1.8126  659       0.9316  gcc_base.none            init_alias_analysis




要观察的另一组有趣的性能计数器是缓存(L2 和 L3)上的访问压力。下面的示例使用了 perf 来分析使用 RHEL6.2 Linux system GCC 构建的 SPECcpu2006 483.xalancbmk 组件。此组件大量使用了内存分配例程,因此预计内存子系统的压力会很大。为了分析压力,可以利用 OProfile 监视中的下列计数器:
表 4. POWER7 缓存/内存访问计数器计数器描述PM_DATA_FROM_L2处理器的 Data Cache 是因为需求负载从本地 L2 重新加载的PM_DATA_FROM_L3处理器的 Data Cache 是因为需求负载从本地 L3 重新加载的PM_DATA_FROM_LMEM处理器的 Data Cache 是从附加在该处理器所在的模块的内存进行重新加载的PM_DATA_FROM_RMEM处理器的 Data Cache 是因为需求负载从附加在与处理器所处模块不同的另一个模块的内存重新加载的
概要文件输出显示如下:
返回列表