gpt4 book ai didi

linux - 用于分析函数缓存行为的 SystemTap 脚本

转载 作者:太空狗 更新时间:2023-10-29 12:29:38 25 4
gpt4 key购买 nike

我想用 SystemTap 分析内核模块的缓存行为(#cache 引用、#cache 未命中等)。有一个在线示例脚本,展示了如何使用 SystemTap 读取性能事件和计数器,包括与缓存相关的事件和计数器: https://sourceware.org/systemtap/examples/profiling/perf.stp

此示例脚本默认适用于进程:

probe perf.hw.cache_references.process("/usr/bin/find").counter("find_insns") {} 

我用 module 替换了 process 关键字,用我的内核模块的名称替换了可执行文件的路径:

probe perf.hw.cache_references.module(MODULE_NAME).counter("find_insns") {} 

我很确定我的模块有调试信息,但是运行我得到的脚本:

semantic error: while resolving probe point: identifier 'perf' at perf.stp:14:7 source: probe perf.hw.instructions.module(MODULE_NAME).counter("find_insns") {}

任何想法可能是错误的?

编辑:

好吧,我意识到性能计数器只能绑定(bind)到进程而不是模块(此处解释:https://sourceware.org/systemtap/man/stapprobes.3stap.html)。因此,我将其改回:

probe perf.hw.cache_references.process(PATH_TO_BINARY).counter("find_insns") {} 

现在,如示例脚本所示,我有:

probe module(MODULE_NAME).function(FUNC_NAME) {
#save counter values on entrance
...
}

但现在运行它,我得到:

semantic error: perf counter 'find_insns' not defined semantic error: while resolving probe point: identifier 'module' at perf.stp:26:7 source: probe module(MODULE_NAME).function(FUNC_NAME)

编辑2:

所以这是我的完整脚本:

#! /usr/bin/env stap

# Usage: stap perf.stp <path-to-binary> <module-name> <function-name>

global cycles_per_insn
global branch_per_insn
global cacheref_per_insn
global insns
global cycles
global branches
global cacherefs
global insn
global cachemisses
global miss_per_insn

probe perf.hw.instructions.process(@1).counter("find_insns") {}
probe perf.hw.cpu_cycles.process(@1).counter("find_cycles") {}
probe perf.hw.branch_instructions.process(@1).counter("find_branches") {}
probe perf.hw.cache_references.process(@1).counter("find_cache_refs") {}
probe perf.hw.cache_misses.process(@1).counter("find_cache_misses") {}


probe module(@2).function(@3)
{
insn["find_insns"] = @perf("find_insns")
insns <<< (insn["find_insns"])
insn["find_cycles"] = @perf("find_cycles")
cycles <<< insn["find_cycles"]
insn["find_branches"] = @perf("find_branches")
branches <<< insn["find_branches"]
insn["find_cache_refs"] = @perf("find_cache_refs")
cacherefs <<< insn["find_cache_refs"]
insn["find_cache_misses"] = @perf("find_cache_misses")
cachemisses <<< insn["find_cache_misses"]
}


probe module(@2).function(@3).return
{
dividend = (@perf("find_cycles") - insn["find_cycles"])
divisor = (@perf("find_insns") - insn["find_insns"])
q = dividend / divisor
if (q > 0)
cycles_per_insn <<< q

dividend = (@perf("find_branches") - insn["find_branches"])
q = dividend / divisor
if (q > 0)
branch_per_insn <<< q

dividend = (@perf("find_cycles") - insn["find_cycles"])
q = dividend / divisor
if (q > 0)
cacheref_per_insn <<< q

dividend = (@perf("find_cache_misses") - insn["find_cache_misses"])
q = dividend / divisor
if (q > 0)
miss_per_insn <<< q
}

probe end
{
if (@count(cycles_per_insn)) {
printf ("Cycles per Insn\n\n")
print (@hist_log(cycles_per_insn))
}
if (@count(branch_per_insn)) {
printf ("\nBranches per Insn\n\n")
print (@hist_log(branch_per_insn))
}
if (@count(cacheref_per_insn)) {
printf ("Cache Refs per Insn\n\n")
print (@hist_log(cacheref_per_insn))
}
if (@count(miss_per_insn)) {
printf ("Cache Misses per Insn\n\n")
print (@hist_log(miss_per_insn))
}
}

最佳答案

Systemtap 无法读取内核探测的硬件 perfctr 值,因为 linux 没有提供合适的(例如,原子的)内部 API 来安全地从所有上下文中读取这些值。 perf...process 探测器之所以起作用,是因为该上下文不是原子的:systemtap 探测器处理程序可以安全地阻塞。

我无法回答您关于您上次试验的两个(?)脚本的详细问题,因为它们不完整。

关于linux - 用于分析函数缓存行为的 SystemTap 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31549671/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com