C++ 这个时钟滴答声适合英特尔i3吗?

C++ 这个时钟滴答声适合英特尔i3吗?,c++,performance,intel,performancecounter,C++,Performance,Intel,Performancecounter,我采用在线方式来衡量苏格兰和南方能源公司的业绩 #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

我采用在线方式来衡量苏格兰和南方能源公司的业绩

#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
我在我的奔腾D E2200 CPU上进行了测量,它工作正常(它显示对齐的SSE指令更快)。 但在我的i3cpu上,我得到未对齐指令的速度要快70%


你们认为这种时钟节拍测量不适合i3cpu吗?

(至少在Windows上)肯定比内联汇编好得多。我看不出有任何理由在该函数上使用内联程序集(这将导致在不支持内联程序集的Visual Studio上编译到x64时出现问题)。

正如其他人所注意到的,您应该使用QueryPerformanceCounter

但是如果您真的想使用汇编程序,最好的方法可能是使用内在的rdtsc

如果您不想使用固有的,那么这将是最好的方法:

unsigned __int64 __declspec(naked) GetPentiumTimer() {
    __asm {
        rdtsc
        ret
    }
}
P>我的知识Visual C++拒绝使用内联汇编程序的任何函数来内联。通过使用_declspec(裸体),您可以告诉编译器正确处理寄存器的使用


但使用内部指令将是最好的选择,这样编译器将知道使用了哪些寄存器,并且以正确的方式内联了它。

0F 31,即RDTSC指令,对于测量短代码段的性能可能仍然有用。即使是i3cpu。若任务切换和将线程迁移到不同核心的效果并没有影响到您,那个么可以使用RDTSC。在许多情况下,强制使用CPUID进行序列化会得到更精确的结果

至于您的测量,很可能未对齐的SSE在i3上工作得更快。最新的英特尔处理器(Nehalem和Sandy Bridge体系结构)可以非常高效地处理未对齐的内存操作数。当然,它们的性能永远不会超过对齐指令,但如果其他一些因素影响测试的性能,对齐指令的运行速度可能会较慢

编辑:

看。这是RDTSC指令使用的一个很好的例子。

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


如果需要超过250纳秒的精度,可以使用直接获取硬件计数器。在我的i7上大约有10ns的延迟。

我很确定VC支持内联asm中的
RDTSC
指令。另外,您为什么不关心上面的32位呢?您应该使用
\uu declspec(裸)
,或者更好地以更合适的方式返回值。除此之外,我希望使用或类似的函数(注意频率缩放/多核处理器等方面的问题)。RDTSC不是串行化指令,这意味着它可以/将无序执行。如果您坚持直接使用它,您通常希望使用CPUID强制序列化(这是您可以在用户模式下执行的少数序列化指令之一)。我也有QueryPerformanceCounter。根据结果,它不是很可靠。对于nxn矩阵乘法,n=10000或更高,时间仅需0.3秒?我认为这一点都不准确(在控制台上,查看结果需要2秒以上),所以我转向时钟滴答声。我现在要试试RDTSC。谢谢。如果这是windows平台,我还建议您使用
QueryPerformanceCounter
。如果您想使用原始
rdtsc
,请使用
\u rdtsc()
内部命令
rdtsc
没有输入,所以我想它的延迟时间应该是从问题到输出寄存器就绪的时间。只有在分支未命中或其他前端失速后才有意义,且难以测量。也许你指的是吞吐量?不,MSVC可以内联使用
\uu asm
的函数,如果你不让它们
裸露的话。但是一定要使用
\uu rdtsc
内在的;它可以跨32/64位移植到gcc/clang/ICC。