NVIDIA CUDA的NVCC编译过程之前已经介绍过了,编译ptx后,会生成cubin文件。
cubin文件是包含了CUDA执行代码节的ELF格式文件。类似于我们常见运行文件。而官方提供了两个工具来反编译cubin文件到sass文件(类似常见的汇编),官方使用文档。
nvdisasm
nvdisasm只接受cubin文件的输入而不支持包含host代码的二进制。
control flow graph
获得代码的执行流程图:
nvdisasm -cfg <input cubin file> | dot -ocfg.png -Tpng
官方给的样例图看起来很完美,但是一般情况下实际文件要复杂的多。
|
管道左边是nvdisasm的dot图输出,文本形式,可以利用linux自带的dot工具来生成png图片。当然也支持其他格式,比如jpg。
而大多数情况下,由于代码比较复杂,生成的图片非常大,普通的图片阅读工具根本无法处理这么大的文件。
而nvdisasm有fun
参数可以指定函数。但是fun的参数是函数的index,而官方并没有说明获得index的方法。我写了个暴力的方法,循环多次,获得每个函数的index。
https://github.com/FindHao/cuda_sasm_ptx_tools/blob/master/got_cfg_indices.py
利用获得的fun index,再产生想要的function的流程图。
命令行参数
举例:
nvdisasm -c -plr ./euler3d_double.sm_50.cubin >euler3d.double.plr.sass
最后将结果重定向到文件里。
Option (long) | Option (short) | Description |
---|---|---|
--base-address |
-base | Specify the logical base address of the image to disassemble. This option is only valid when disassembling a raw instruction binary (see option '--binary'), and is ignored when disassembling an Elf file. Default value: 0. |
--binary |
-b | SM50等,表明硬件的计算能力,获得相应硬件能力的代码。 |
--cuda-function-index |
-fun | 获得指定函数的信息 |
--help | -h | Print this help information on this tool. |
--life-range-mode | -lrm | 打印寄存器的生命周期。①count:指打印用到的寄存器的信息②wide:打印详细信息,这是default设置。③narrow:每个寄存器一列。 |
--no-dataflow | -ndf | Disable dataflow analyzer after disassembly. Dataflow analysis is normally enabled to perform branch stack analysis and annotate all instructions that jump via the GPU branch stack with inferred branch target labels. However, it may occasionally fail when certain restrictions on the input nvelf/cubin are not met. |
--no-vliw | -novliw | Conventional mode; disassemble paired instructions in normal syntax, instead of VLIW syntax. |
--options-file |
-optf | Include command line options from specified file. |
--output-control-flow-graph | -cfg | 输出控制流图 |
--print-code | -c | 只处理代码段 |
--print-instruction-encoding | -hex | When specified, print the encoding bytes after each disassembled operation. |
--print-life-ranges | -plr | 相当于lrm wide模式 |
--print-line-info | -g | 打印行信息(对应编译时的lineinfo) |
--print-raw | -raw | Print the disassembly without any attempt to beautify it. |
--separate-functions | -sf | Separate the code corresponding with function symbols by some new lines to let them stand out in the printed disassembly. |
--version | -V | Print version information on this tool. |
寄存器生命周期
在打印寄存器生命周期时,输出有三栏:
GPR(General Purpose Register) | PRED(Predicate) | SCOREBOARD(计分板) |
---|---|---|
代码里看到的 R0,R1,R2... | 用于分支判断的标志位 P0,P1,... | 寄存器分配和调度方法,把逻辑寄存器和物理寄存器对应起来 |
注意要关闭编辑器的wordwrap功能,否则自动换行以后根本没法看。
cuobjdump
cuobjdump -xelf all ./binary
可以直接获得所有的cubin文件
Comments