编译器是sw5cc还是swgcc,要用对应版本的
JFLFY2255
@JFLFY2255
JFLFY2255 发布的帖子
-
RE: MPI的C++程序想用athread,编译出错?
主要问题为athread.h中不包含给c++使用的extern "C"声明,以及c++严格的类型检查。
强行在c++中使用athread中请按照如下思路:
自行声明athread相关函数:extern "C" void __real_athread_spawn(void*, void*); extern "C" void int athread_join();
声明slave函数:
extern "C" void slave_func(void*);
调用(手动强制类型转换):
__real_athread_spawn((void*)slave_func, ¶m);
-
RE: 编译选项-finstrument-functions的错误
如果一个函数使用了动态栈帧,即alloca函数(Fortran下则是函数里定义的数组等都很容易成为动态栈帧,动态栈这件事在fortran中极为常见)。那么他将使用fp寄存器来保存栈顶,并以fp为基址寄存器使用栈空间。
ra寄存器作为返回值寄存器,在这个时候也一般使用fp作为基址寄存器。
而-finstrument-functions有自己的一套栈帧逻辑,使用0(sp)保存ra寄存器,并取消了原来*(fp)的形式。这在动态栈帧的情况下会产生冲突,即本来fp基址的访存方式,也使用了0(sp)这个地址。而0(sp)又是用来存放ra的。这会导致这个保存的ra可能被覆写,从而丢失ra的值。导致了程序崩溃。一句话:除非编译组出面修复这个功能就当它不存在
-
SWLU:主核性能采样、调试工具包
SWLU 是一个针对国产神威芯片主核的开发者工具包。支持主核调用栈回溯、主核性能采样(对应于gprof)、主核调试(对应于swgdb-bt)等功能。
目前版本为初版暂不开源,之后的正式版计划开源(
因为源代码有点丑,功能也不完善)。使用初步:
本库支持C、C++和Fortran。
库的链接:
现在SWLU提供两个库文件:
- libswlu.a
- libswlu_mpi.a
分别对应于串行程序和MPI程序。
当你使用串行程序的时候,请链接libswlu.a;
当你使用MPI 程序的时候,请链接libswlu_mpi.a。
库的链接方法和x86平台是一致的。库的头文件:
库的头文件仅有swlu.h,包含了所有接口函数的定义,支持c和c++。
库的获取:
目前位于目录
// 根目录 /home/export/online1/swmore/opensource/swlu/ // 相关文件 /home/export/online1/swmore/opensource/swlu/lib/libswlu.a /home/export/online1/swmore/opensource/swlu/lib/libswlu_mpi.a /home/export/online1/swmore/opensource/swlu/include/swlu.h
*符号表处理:
由于SWLU中部分功能依赖于符号表,所以需要显示的符号表。
SWLU目前获取符号表的方式是通过readelf获得,具体操作如下:readelf -s *.exe > swlu_symtable.txt
需要在bsub之前执行。
其中*.exe是你bsub的可执行文件,swlu_symtatble.txt是SWLU所依赖的符号表文件。
如过建立符号表的时候没有符号表文件(swlu_symtatble.txt),将会得到提示:Error : Can't find symbol table file: swlu_symtable.txt Please execute "readelf -s $EXE > swlu_symtable.txt" before running EXE
对于性能采样和调试,初始化过程都会自动尝试建立符号表,用户也可以手动调用swlu_build_symtable()函数显式构建符号表。
主核性能采样:
这是该工具包中目前为止最有效的功能,已经在GROMACS、CESM等重量级项目中提供了全程的性能分析指导,并在lammps、wrf、fft、masnum等项目中进行了运行测试。
工具特点:
SWLU-prof是一个基于定时器采样的profiling工具。
- 相比于gptl等插桩工具,可以获得系统库的信息;
- 相比于神威自带的gprof,可以提供完整的调用栈信息。
缺点在于现有版本采样粒度较粗,1s只能采样50~100次,导致采样次数不足时结果有一定误差。
一般认为一个函数采样次数到达5000次时误差趋于稳定,建议采样段至少运行1分钟以上,如果函数杂而多,则需要更长时间的采样。接口函数:
一共有以下四个函数:
- swlu_prof_init: 初始化函数,在使用采样前必须调用。对于MPI程序,需要在MPI_Init之后调用。
- swlu_prof_print: 结果打印函数,对于MPI程序,需要在MPI_finalize前调用。使用后将结果输出到swlu_prof.txt和swlu_prof.dot中,前者是结果的文本格式,后者用于生成pdf。目前版本原则上你仅应该在程序末尾调用一次swlu_prof_print
- swlu_prof_start: 开启采样
- swlu_prof_stop: 停止采样
以上函数参数均为空。具体示例如下 :
// c & c++: swlu_prof_init();
// fortran: call swlu_prof_init
(
原有未发布版接口以samprof为前缀,而非swlu_prof。这些接口在初版的库中依旧保留,只是使用是会提示"Warning : samprof_* is deprecated, please use swlu_prof_* instead"。未来的版本将会移除这套接口。)swlu_prof函数依赖于符号表,在swlu_prof_init中会运行swlu_build_symtable, 尝试读取符号表信息。
如果没有符号表文件,最后运行的结果将只能得到一个名为(null)的空函数。func-name = (null), func-addr = 0, self = 100.000000%, tot = 100.000000%
结果格式:
结果文件有两个,一个是swlu_prof.txt,这是一个文本格式的性能结果,一般不常使用,格式如下:
1 =========================================== 2 3 +++++++++++++++++++++++++++++++++++++++++++ 4 - function - 5 total sample = 572 6 func-name = _Z2fdv, func-addr = 4ff0416d60, self = 68.881119%, tot = 68.881119% 7 func-name = main, func-addr = 4ff0416b10, self = 0.000000%, tot = 100.000000% 8 func-name = __libc_start_main, func-addr = 4ff064f7f0, self = 0.000000%, tot = 100.000000% 9 func-name = _host_start, func-addr = 4ff0416920, self = 0.000000%, tot = 100.000000% 10 func-name = _Z2fcv, func-addr = 4ff0416db0, self = 31.118881%, tot = 31.118881% 11 +++++++++++++++++++++++++++++++++++++++++++ 12 - calls - 13 main -> _Z2fdv 68.8811% 14 __libc_start_main -> main 100.0000% 15 _host_start -> __libc_start_main 100.0000% 16 main -> _Z2fcv 31.1189%
另一个结果文件是swlu_prof.dot,这是一个用于生成调用关系图的文件。
dot -Tpdf swlu_prof.dot -o example.pdf // -o 用于指定目标pdf的名称。
(dot是graphviz中的一个指令,关于graphviz画图工具更多功能可见 http://www.graphviz.org)
运行上面这条指令即可得到调用关系图。效果如下:
节点:
- 第一行:函数名
- 第二行:该函数占用总时间的百分比,avg/max/min格式。即第一个数是所有进程的平均数,第二个数最大值,第三个数最小值。
- 第三行:该函数自身指令占用总时间的百分比,avg/max/min格式。即不包括子调用的时间。
边:
- 表示一个调用弧占用总时间的百分比。仅有平均数信息。
以及(lammps运行图):
*注意事项:
由于该工具会运行时触发系统软中断,可能导致本来能运行的程序运行崩溃。这不是工具的bug,而是被测程序本身有 “使用未定义内存”的bug。
正确的处理过程应该是找出被测程序的bug并修复。该问题在CESM和GROMACS中出现并定位,并采取了一定方案修复/规避。
(具体来说,就是工具在采样的时候改变了被测内存段的数值,导致本来不影响结果的未定义内存影响了结果)
2018.11.27-version 0.5 : 特别鸣谢段晓辉,他发现了linux的altstack。现在时钟中断使用了这个功能,理论上来说不会对程序产生任何影响了。
2018.12.06 发现了一个在CESM初始化中打开采样会发生的问题。主核调试工具(仅backtrace功能):
这是通过注册几个关键信号(linux软中断机制)实现的自动backtrace工具。
支持在触发浮点异常(SIGFPE)、段错误(SIGSEGV)以及非法指令(SIGILL)时,先打印函数栈,再进行原本的处理(结束程序等)。为何要使用这个功能:
比swgdb方便,只需要初始化下,程序出问题了自动打印调用栈信息。
比swgdb准确,swgdb经常调用栈信息错误,无法正确回溯。接口函数:
仅一个初始化函数: swlu_debug_init
c & c++: swlu_debug_init(); fortran: call swlu_debug_init
swlu_debug函数部分依赖于符号表,有符号表的时候输出完整信息,没有符号表的时候仅输出地址信息,没有函数名信息。
swlu_debug_init也会尝试加载符号表。使用方法:
当程序运行崩溃以后,自动打印调用栈信息,效果如下:
目前只有0号进程有输出信息。此外,会在应用执行的文件夹生成swlu_debug[mpi_rank].txt,比如一个16个进程的文件会生成swlu_debug0.txt~swlu_debug15.txt。
以下是4个进程的应用生成的文件:
2018.11.27-version 0.5 : 特别鸣谢段晓辉,现在写完文件会有屏幕输出提示
也可以和
研究科学家段晓辉的spc工具一样,通过bsignal,提供手动的调用栈打印(目前设置和spc有冲突,后续解决):bsignal -s 30 bjobid // 将所有进程的调用栈信息写文件,不写屏幕
bsignal -s 31 bjobid // 屏幕打印主进程(0号进程的)的调用栈,不写文件;屏幕打印效果和运行崩溃时一致
2018.11.27-version 0.5 : 现在程序启动时(MPI_Init前,swlu_debug_init前)有一个自动的debug初始化。可以在MPI初始化前正常使用signo30,但是signo31会打印所有进程号的信息,可能会有错行。
主核调用栈回溯工具:
这是SWLU工具包核心技术,就是实现了一个通用的主核backtrace函数,比swgdb自带的backtrace更稳定(用swgdb的都知道backtrace经常跳不出来,没法正确解析函数栈;
就是因为太烂了才会重新写一个...)。
这个backtrace基本可以认为有99.9999%的正确率(新发现的bug也会持续修复),已经经过了大量测试。一般来说用户调试测试程序可能不会使用到这个接口,这个接口是提供给二次开发使用的。
函数接口:
c & c++ : int swlu_backtrace(uint64_t *func_ptr, int depth); fortran : subroutine swlu_backtrace(func_ptr, depth, ret) integer(8), dimension(:), intent(out) :: func_ptr integer(4), intent(in) :: depth integer(4), intent(out) :: ret
此函数采用execinfo.h中的backtrace函数的接口。
http://velep.com/archives/1032.html 这个网页有简单的说明。func_ptr是一个uint64_t的数组,用来存调用栈的pc信息,参数depth用于指定回溯的最大深度。
返回值用来返回实际回溯的调用栈深度。如果函数栈深度 <= depth,将返回函数栈实际深度。
如果函数栈深度 > depth, 那将只回溯depth深度,并且返回值为depth。swlu_backtrace函数不依赖于符号表,无需任何初始化就可以在程序任何地方调用。
======================================================================
2018.12.01 Verson 0.6beta 更新:
现有接口保持兼容。- 通过int swlu_prof_index支持了多个采样实例(每个实例都需要独立的init, start, stop, print)。
- 通过int swlu_prof_set_mpi和MPI_Comm swlu_prof_comm支持了对于特定采样实例,指定通信子(MPI_Comm)。
- 略微修改了.txt的内容,并增加了Basic Block级的采样结果。
- 通过int swlu_prof_print_every支持了所有进程打印自己的采样结果。
- 在找不到swlu_symtable.txt后会尝试自动获取符号表(目前无失败情况)(by 段晓辉)。