这个时钟是否适用于Intel i3?

时间:2011-11-28 18:20:35

标签: c++ performance intel performancecounter

我在线采用衡量SSE表现的方法。

#ifndef __TIMER_H__
#define __TIMER_H__

#pragma warning (push)
#pragma warning (disable : 4035)    // disable no return value warning

__forceinline  unsigned int GetPentiumTimer()
{
    __asm
    {
        xor   eax,eax             // VC won't realize that eax is modified w/out this
                                  //   instruction to modify the val.
                                  //   Problem shows up in release mode builds
        _emit 0x0F                // Pentium high-freq counter to edx;eax
        _emit 0x31                // only care about low 32 bits in eax

        xor   edx,edx             // so VC gets that edx is modified
    }
}

#pragma warning (pop)

#endif

我在Pentium D E2200 CPU上进行了测量,并且工作正常(它显示对齐的SSE指令更快)。 但是在我的i3 CPU上,我得到了70%的测试更快的未对齐指令。

你们认为这种时钟滴答测量不适合i3 CPU吗?

4 个答案:

答案 0 :(得分:4)

QueryPerformanceCounter(至少在Windows上)肯定比内联汇编好得多。我看不出有任何理由在该函数上使用内联汇编(这将使您在Visual Studio上编译x64,而不支持内联汇编)。

答案 1 :(得分:2)

正如其他人注意到的,你应该使用QueryPerformanceCounter。

但是如果你真的想使用汇编程序,那么最好的可能就是使用内在的__rdtsc。

如果你不想使用内在的,那么这将是最好的方法:

unsigned __int64 __declspec(naked) GetPentiumTimer() {
    __asm {
        rdtsc
        ret
    }
}

据我所知,Visual C ++拒绝为任何使用内联汇编程序的函数进行内联。通过使用__declspec(裸),您可以告诉编译器正确处理寄存器使用情况。

但是使用内在函数是最好的,这样编译器就会知道使用了哪些寄存器并以正确的方式内联。

答案 2 :(得分:2)

0F 31,即RDTSC指令,仍然可用于测量短代码的性能。即使是i3 CPU。如果任务切换和迁移线程到不同核心的影响不打扰你,可以使用RDTSC。在许多情况下,您可以获得更精确的结果,强制使用CPUID进行序列化。

对于您的测量,很可能未对准的SSE在i3上运行得更快。最新的英特尔处理器(Nehalem和Sandy Bridge架构)可以非常有效地处理未对齐的内存操作数。当然,它们永远不会胜过对齐指令,但如果其他一些因素会影响测试中的性能,那么对齐的指令似乎运行得更慢。

修改

http://www.agner.org/optimize/#testp。这是RDTSC指令使用的一个很好的例子。

答案 3 :(得分:1)

QueryPerformanceCounter()是在Windows上获取高频计时器的最简单方法。但是,它有一点开销,因为它是一个系统调用 - 大约½μs。如果您计时非常快,或者需要非常高的精度,这可能是一个问题。

如果您需要高于250纳秒的精度,可以使用the rdtsc intrinsic直接获取硬件计数器。我的i7上有大约10ns的延迟。