我需要计算一部分 (C++) 代码的运行时间,并希望通过查找代码执行期间经过的时钟周期数来实现此目的。
我想找到代码开头处的处理器时间和末尾处的处理器时间,然后将它们相减以找到经过的时钟周期数。
这可以通过 clock function 来完成。然而,我测量的时间需要非常精确,并且使用函数调用被证明是非常具有侵入性的,因为调用者保存的寄存器分配器在每次调用时都会溢出许多变量。
因此,我无法使用任何函数调用,需要自己检索处理器时间。汇编代码没问题。
我使用的是 Debian 和 i7 Intel 处理器。我无法使用探查器,因为它的侵入性太强。
最佳答案
您应该阅读time(7) 。请注意,即使用汇编程序编写,您的程序也会在任意时刻重新安排(可能每毫秒 context switch ;另请参阅 /proc/interrupts
并查看 proc(5) )。那么任何硬件定时器都是没有意义的。偶using RDTSC
x86-64 机器指令来读取 hardware timestamp counter是无用的(因为在任何上下文切换之后都会出错,并且 Linux 内核正在执行 preemptive 调度,这确实随时发生)。
您应该考虑clock_gettime(2) 。它真的很快(在我的 i5-4690S 上大约 3.5 或 4 纳秒,当测量对它的数千次调用时),因为 vdso(7) 。顺便说一句,它是 system call ,因此您可以直接编写执行这些操作的汇编指令。我认为不值得这么麻烦(并且可能比 vdso 调用慢)。
顺便说一句,任何类型的分析或基准测试在某种程度上都是侵入性的。
最后,如果您的基准测试函数运行速度非常快(远小于一微秒),cache未命中变得很严重,甚至占主导地位(请记住,需要有效访问 DRAM 模块的 L3 高速缓存未命中持续数百纳秒,足以在 L1 I 高速缓存中运行数百条机器指令)。您可能(并且可能应该)尝试对多个(数百个)连续调用进行基准测试。但您将无法精确且准确地进行测量。
因此,我相信你不能比使用clock_gettime
做得更好,并且我不明白为什么它不好足以满足您的情况... 顺便说一句,clock(3)正在使用 CLOCK_PROCESS_CPUTIME_ID
调用 clock_gettime
,所以恕我直言,它应该足够了,而且更简单。
换句话说,我认为避免任何函数调用是您的误解。请记住,函数调用开销比缓存未命中要便宜得多!
参见this answer一个相关的问题(和你的问题一样不清楚);还可以考虑使用 perf(1) , gprof(1) , oprofile(1) , time(1) 。请参阅this .
最后,你应该考虑询问更多optimizations来自你的编译器。您是否考虑过使用 g++ -O3 -flto -march=native
进行编译和链接(带有链接时优化)。
如果您的代码具有数值和 vector 性质(非常明显且可大规模并行),您甚至可以考虑花费月的开发时间将其核心代码(数值 compute kernels )移植到你的GPGPU在 OpenCL或CUDA 。但你确定这样的努力值得吗?更改硬件时,您需要调整和重新开发代码!
您还可以重新设计您的应用程序以使用 multi-threading , JIT compilation和 partial evaluation和 metaprogramming技术,multiprocessing或cloud-computing (使用 inter-process communication ,例如 socket(7) -s,可能使用 0mq 或其他消息传递库)。这可能需要数年的开发。有No Silver Bullet .
(不要忘记考虑开发成本;尽可能首选算法改进。)
关于c++ - 如何在不调用函数的情况下在 Linux 中检索处理器时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47003535/