使用 mpirun 时,如何使分析器(valgrind、perf、pprof)拾取/使用带有调试符号的本地版本库?
Posted
技术标签:
【中文标题】使用 mpirun 时,如何使分析器(valgrind、perf、pprof)拾取/使用带有调试符号的本地版本库?【英文标题】:How to make profilers (valgrind, perf, pprof) pick up / use local version of library with debugging symbols when using mpirun? 【发布时间】:2011-10-01 19:04:04 【问题描述】:编辑: 添加了关于调试 MPI 应用程序的重要说明
系统安装的共享库没有调试符号:
$ readelf -S /usr/lib64/libfftw3.so | grep debug
$
因此,我在我的主目录中编译并安装了我自己的版本,启用了调试 (--with-debug CFLAGS=-g
):
$ $ readelf -S ~/lib64/libfftw3.so | grep debug
[26] .debug_aranges PROGBITS 0000000000000000 001d3902
[27] .debug_pubnames PROGBITS 0000000000000000 001d8552
[28] .debug_info PROGBITS 0000000000000000 001ddebd
[29] .debug_abbrev PROGBITS 0000000000000000 003e221c
[30] .debug_line PROGBITS 0000000000000000 00414306
[31] .debug_str PROGBITS 0000000000000000 0044aa23
[32] .debug_loc PROGBITS 0000000000000000 004514de
[33] .debug_ranges PROGBITS 0000000000000000 0046bc82
我已将 LD_LIBRARY_PATH 和 LD_RUN_PATH 都设置为首先包含 ~/lib64
,ldd program
确认应使用本地版本的库:
$ ldd a.out | grep fftw
libfftw3.so.3 => /home/narebski/lib64/libfftw3.so.3 (0x00007f2ed9a98000)
有问题的程序是并行使用MPI(消息传递接口)的数值应用程序。因此,要运行此应用程序,必须使用mpirun
包装器(例如mpirun -np 1 valgrind --tool=callgrind ./a.out
)。我使用 OpenMPI 实现。
尽管如此,各种分析器:Valgrind、CPU profiling、google-perfutils 和 perf 中的 callgrind 工具并没有找到那些调试符号,导致或多或少 无用 输出:
钙磨:
$ callgrind_annotate --include=~/prog/src --inclusive=no --tree=none
[...]
--------------------------------------------------------------------------------
Ir file:function
--------------------------------------------------------------------------------
32,765,904,336 ???:0x000000000014e500 [/usr/lib64/libfftw3.so.3.2.4]
31,342,886,912 /home/narebski/prog/src/nonlinearity.F90:__nonlinearity_MOD_calc_nonlinearity_kxky [/home/narebski/prog/bin/a.out]
30,288,261,120 /home/narebski/gene11/src/axpy.F90:__axpy_MOD_axpy_ij [/home/narebski/prog/bin/a.out]
23,429,390,736 ???:0x00000000000fc5e0 [/usr/lib64/libfftw3.so.3.2.4]
17,851,018,186 ???:0x00000000000fdb80 [/usr/lib64/libmpi.so.1.0.1]
谷歌性能工具:
$ pprof --text a.out prog.prof
Total: 8401 samples
842 10.0% 10.0% 842 10.0% 00007f200522d5f0
619 7.4% 17.4% 5025 59.8% calc_nonlinearity_kxky
517 6.2% 23.5% 517 6.2% axpy_ij
427 5.1% 28.6% 3156 37.6% nl_to_direct_xy
307 3.7% 32.3% 1234 14.7% nl_to_fourier_xy_1d
性能事件:
$ perf report --sort comm,dso,symbol
# Events: 80K cycles
#
# Overhead Command Shared Object Symbol
# ........ ....... .................... ............................................
#
32.42% a.out libfftw3.so.3.2.4 [.] fdc4c
16.25% a.out 7fddcd97bb22 [.] 7fddcd97bb22
7.51% a.out libatlas.so.0.0.0 [.] ATL_dcopy_xp1yp1aXbX
6.98% a.out a.out [.] __nonlinearity_MOD_calc_nonlinearity_kxky
5.82% a.out a.out [.] __axpy_MOD_axpy_ij
编辑 添加于 11-07-2011: 我不知道这是否重要,但是:
$ file /usr/lib64/libfftw3.so.3.2.4
/usr/lib64/libfftw3.so.3.2.4: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, stripped
和
$ file ~/lib64/libfftw3.so.3.2.4
/home/narebski/lib64/libfftw3.so.3.2.4: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, not stripped
【问题讨论】:
如果你使用Zoom 或this method of finding time drains 你不需要你的库有符号,因为你可以解决的任何问题是代码中的一行或几行,而不是外部库,并且这些线是精确的。 【参考方案1】:如果 /usr/lib64/libfftw3.so.3.2.4
列在 callgrind 输出中,则您的 LD_LIBRARY_PATH=~/lib64
没有效果。
使用export LD_LIBRARY_PATH=$HOME/lib64
重试。还要注意您调用的任何 shell 脚本,这可能会重置您的环境。
【讨论】:
你是对的。我正在使用来自 OpenMPI 的mpirun
,它确实将/usr/lib:/usr/lib64:
添加到'LD_LIBRARY_PATH'(我通过运行mpirun -np 1 printenv
进行了检查)。我必须使用--prefix
或-x
选项来mpirun。【参考方案2】:
您和受雇的俄罗斯人几乎肯定是对的; mpirun 脚本在这里搞砸了。两种选择:
实际上,大多数 x86 MPI 实现只运行可执行文件
./a.out
和
一样mpirun -np 1 ./a.out
.
他们不必这样做,但 OpenMPI 肯定会这样做,MPICH2 和 IntelMPI 也是如此。因此,如果您可以串行进行调试,则应该能够
valgrind --tool=callgrind ./a.out
.
但是,如果您确实想使用 mpirun 运行,问题可能在于您的 ~/.bashrc
(或其他)正在获取,撤消对LD_LIBRARY_PATH
等的更改。最简单的方法是在运行期间将更改的环境变量临时放入~/.bashrc
。
【讨论】:
不,不是这样。就是mpirun
在PATH和LD_LIBRARY_PATH中添加“前缀”,可以使用mpirun -np 1 printenv
查看。
如果我理解正确valgrind --tool=callgrind ./a.out
也会配置 mpirun 部分,这是我不想要的;虽然我没有检查它是否有很大的障碍。
前缀应该只是 OpenMPI 的路径,这应该是无关紧要的(除非你把 fftw 和 MPI 库放在同一个地方)。 valgrind --tool=callgrind ./a.out
不会神奇地调用 mpirun;它将启动 a.out 可执行文件。
OpenMPI 使用 '/usr' 前缀,mpirun
prefixes '/usr/bin' 到 PATH,以及 '/usr/lib' 和 '/usr/lib64 '(在 x86_64 上)到 LD_LIBRARY_PATH... 这意味着 mpirun ... ./a.out
使用了没有调试信息的剥离系统安装库,而不是用户安装的带有调试信息的库。
所以你确实把所有东西都安装在了同一个地方。这不是一个好主意,但如果你只是使用包管理器为你做的任何事情,那将会发生;太糟糕了。无论如何,再一次,可以通过不运行 mpirun 来避免该问题,因为您不需要它来执行 1 个任务。如果你不相信我,试试看。【参考方案3】:
最近的分析工具通常处理这种情况的方式是查阅外部匹配的非剥离版本的库。
在基于 debian 的 Linux 发行版上,这通常是通过安装带有 -dbg
后缀的软件包版本来完成的;在基于 Redhat 的情况下,它们被命名为 -debuginfo
。
对于您上面提到的工具;如果调试信息包已安装在标准位置,它们通常会 Just Work (tm) 并找到库的调试符号。
【讨论】:
如果有问题的发行版是 Gentoo(我不是管理员)怎么办? @Jakub:当然在perf report
的情况下,您可以使用--symfs
选项指定一个替代位置来查找调试信息文件。您必须检查您的其他工具是否支持类似的选项。
我想我必须升级perf
才能访问--symfs
选项;至少对于 2.6.36,文档中未提及此选项。以上是关于使用 mpirun 时,如何使分析器(valgrind、perf、pprof)拾取/使用带有调试符号的本地版本库?的主要内容,如果未能解决你的问题,请参考以下文章