如何在多核处理器上进行基准测试

时间:2010-05-08 15:48:43

标签: assembly benchmarking performancecounter microbenchmark rdtsc

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

上下文

大约在同一时间,台式机处理器引入了无序执行,导致性能难以预测,他们或许并非巧合,还引入了特殊指令来获得非常精确的时序。这些说明的示例是x86上的rdtsc和PowerPC上的rftb。这些指令给出了比系统调用所允许的更精确的时序,允许程序员微观地对其心脏进行基准测试,无论好坏。

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

问题:

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

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

更多背景信息:

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

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

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

2 个答案:

答案 0 :(得分:2)

在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( )幕后所需的修复,以便在多核(和多插槽)环境中提供有意义的结果。

答案 1 :(得分:1)

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

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

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