如何计算程序(或函数调用)中两点之间执行的 x86-64 指令的数量?
Posted
技术标签:
【中文标题】如何计算程序(或函数调用)中两点之间执行的 x86-64 指令的数量?【英文标题】:How to count numbers of executed x86-64 instructions between two points in program (or function call)? 【发布时间】:2015-11-19 11:12:00 【问题描述】:我做了一些具有各种微优化的算法实现。我需要计算一个调用的执行指令的数量,或者两个地方之间(调用前后)的数量。
算法使用很少的循环和条件跳转,并且对数据敏感。所以我不能只使用计算出的每个循环迭代的指令数,并将其乘以迭代次数。
免责声明:我知道执行指令的数量无关紧要,因为相同指令的性能因 CPU 不同而异,但这仅用于演示目的。
【问题讨论】:
你研究过 valgrind 吗?有一个选项可以获取所有指令计数。也许有一种方法可以限制范围。 valgrind.org/docs/manual/lk-manual.html 你怎么数?前缀算作单独的指令吗?像rep movsb
这样的字符串指令呢?每次迭代都算作一次还是一次?
您是否尝试打开 asm 选项,允许在构建项目时生成汇编源文件。这至少会为您提供进行比较所需的来源。
我不确定您是否可以实际计算指令的数量,但如果您不知道,请查看 perf (sandsoftwaresound.net/perf/perf-tutorial-hot-spots)
这并不是衡量在支持推测执行的现代处理器内核上完成了多少有效工作的好方法。他们都这样做。 ISA 核心有一个计数器,可以报告 retired 指令的数量,这是更好的衡量标准。不要发明这个***,任何像样的分析器都可以让你访问它。
【参考方案1】:
在 x86(32 位和 64 位)上,您可能正在寻找 RDTSC 指令。 考虑到现代 CPU 的复杂性,任何形式的模拟或静态分析当然都不是。
您的编译器可能有也可能没有内在函数,如果没有,请执行以下操作:(内联 asm 的 GCC 语法)
uint64_t GetTSC(void)
uint64_t h, l;
h = l = 0;
__asm__("rdtsc" : "=a"(l), "=d"(h));
h <<= 32;
h |= l;
return h;
带有https://en.wikipedia.org/wiki/Time_Stamp_Counter中描述的警告
【讨论】:
但是,如果我理解正确的话,那是时钟计数器,不是执行指令计数器。以上是关于如何计算程序(或函数调用)中两点之间执行的 x86-64 指令的数量?的主要内容,如果未能解决你的问题,请参考以下文章