我正在做一个实验,将循环索引写入CPU寄存器R11,然后使用gcc -ffixed-r11
构建它,尝试让编译器知道不使用该reg,最后使用perf来测量它
但是当我检查报告时(使用perf script
),大多数记录条目的R11值不是我预期的,它应该是数字序列,如1..2..3或1 .. 4..7等等但实际上只是几个固定值。 (可能受系统调用覆盖影响?)
如何让perf记录我在程序中设置的值?或者我必须用-ffixed-r11
重新编译整个内核才能实现?
谢谢大家。
答案 0 :(得分:0)
当您只想使用perf对一些寄存器进行采样时,不应该尝试重新编译内核。据我所知,内核有自己的一组寄存器,不会覆盖用户R11。 syscall
接口使用一些无法更改的固定寄存器(可以尝试不同的reg吗?)并且通常有glibc网关到syscall,可能会使用一些额外的寄存器(它们不在内核中,它们是用户空间)代码;通常用汇编程序生成或编写)。您可以尝试使用gdb监视寄存器以进行更改以查找是谁。它可以做到这一点(嗯,另一个链接到同一个用户的SO):gdb: breakpoint when register will have value 0xffaa,如gdb ./program
,然后gdb命令start; watch $r11; continue; where
。
两周大的时候,问题perf-report show value of CPU register关于寄存器值采样有问题:
我关注this document并将
perf record
与--intr-regs=ax,bx,r15
一起使用,尝试使用PEBS记录记录其他CPU注册信息。
虽然有x86& PEBS,ARM也可以实现--intr-regs
。检查perf record --intr-regs=\?
的输出(man perf-record:“列出可用的寄存器使用--intr-regs=\?
”)以查找支持状态和注册名称。
要打印寄存器,请使用perf script -F ip,sym,iregs
命令。在一些linux提交中有例子:
# perf record --intr-regs=AX,SP usleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.016 MB perf.data (8 samples) ]
# perf script -F ip,sym,iregs | tail -5
ffffffff8105f42a native_write_msr_safe AX:0xf SP:0xffff8802629c3c00
ffffffff8105f42a native_write_msr_safe AX:0xf SP:0xffff8802629c3c00
ffffffff81761ac0 _raw_spin_lock AX:0xffff8801bfcf8020 SP:0xffff8802629c3ce8
ffffffff81202bf8 __vma_adjust_trans_huge AX:0x7ffc75200000 SP:0xffff8802629c3b30
ffffffff8122b089 dput AX:0x101 SP:0xffff8802629c3c78
#
答案 1 :(得分:0)
如果您需要对金属CPU活动进行循环精确分析,那么perf不是正确的工具,因为它最多只是近似值,因为它只在选择点对程序进行采样。见this video on perf by Clang developer Chandler Carruth。
相反,您应该单步执行该程序,以便准确监视寄存器发生的情况。或者您可以在没有操作系统的情况下对系统裸机进行编程,但这可能超出了此范围。