4

我正在寻找在多核处理器上执行微基准测试的方法。

语境:

几乎与此同时,桌面处理器引入了让性能难以预测的乱序执行,也许并非巧合,它们还引入了特殊指令来获得非常精确的时序。这些指令的示例rdtsc在 x86 和rftbPowerPC 上。这些指令给出的时间比系统调用所允许的更精确,允许程序员对他们的心进行微基准测试,无论好坏。

在具有多个内核的更现代的处理器上,其中一些内核有时会休眠,计数器在内核之间不同步。我们被告知rdtsc不再安全地用于基准测试,但是当我们被解释替代解决方案时,我一定是在打瞌睡。

问题:

一些系统可能会保存和恢复性能计数器,并提供 API 调用来读取正确的总和。如果您知道此调用适用于任何操作系统,请在答复中告知我们。

一些系统可能允许关闭核心,只留下一个运行。我知道 Mac OS X Leopard 在从开发人员工具安装正确的首选项窗格时会这样做。你认为这可以rdtsc安全地再次使用吗?

更多背景:

请假设我在尝试进行微基准测试时知道自己在做什么。如果您认为如果优化的收益不能通过计时整个应用程序来衡量,那么不值得优化,我同意您的观点,但是

  1. 在替代数据结构完成之前,我无法为整个应用程序计时,这需要很长时间。事实上,如果微基准没有希望,我现在可以决定放弃实施;

  2. 我需要在我无法控制截止日期的出版物中提供数据。

4

2 回答 2

3

在 OSX(ARM、Intel 和 PowerPC)上,您要使用mach_absolute_time( )

#include <mach/mach_time.h>
#include <stdint.h>    

// Utility function for getting timings in nanoseconds.
double machTimeUnitsToNanoseconds(uint64_t mtu) {
    static double mtusPerNanosecond = 0.0;
    if (0.0 == mtusPerNanosecond) {
        mach_timebase_info_data_t info;
        if (mach_timebase_info(&info)) {
            // Handle an error gracefully here, whatever that means to you.
            // If you do get an error, something is seriously wrong, so
            // I generally just report it and exit( ).
        }
        mtusPerNanosecond = (double)info.numer / info.denom;
    }
    return mtu * mtusPerNanosecond;
}

// In your code:
uint64_t startTime = mach_absolute_time( );
// Stuff that you want to time.
uint64_t endTime = mach_absolute_time( );
double elapsedNanoseconds = machTimeUnitsToNanoseconds(endTime - startTime);

请注意,无需为此限制为一个核心。操作系统在后台处理所需的修复,以便mach_absolute_time( )在多核(和多插槽)环境中提供有意义的结果。

于 2010-05-08T15:56:35.897 回答
1

内核正在为“rtdsc”返回正确的同步值。如果您有一台多插槽机器,则必须将进程修复到一个插槽。这不是问题。

主要问题是调度程序使数据不可靠。Linux Kernel > 2.6.31 有一些性能 API,但我没有看过。Windows > Vista 在这里做得很好,使用 QueryThreadCycleTime 和 QueryProcessCycleTime。

我不确定OSX,但AFAIK“mach_absolute_time”不会调整预定时间。

于 2010-05-08T16:18:55.363 回答