2011-11-28 6 views
10

SSEのパフォーマンスを測定するためにオンラインで採用しました。このクロックダンプはIntel i3に適していますか?

#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命令がより速いことを示しています)。 しかし私のi3 CPUでは、アライメントの合っていない命令がテストの70%高速化されています。

あなたはこのクロックティックの測定値がi3 CPUに適していないと思いますか?

+0

私は、VCがインラインasmで 'RDTSC'命令をサポートしていることは確かです。また、上位32ビットについて気にしないでください。 '__declspec(naked)'を使用するか、さらに適切な方法で値を返すべきです。私は['QueryPerformanceCounter'](http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904/(v = vs.85 \))を使いたいと思っています。aspx)またはそれに類する機能(周波数スケーリング/マルチコアプロセッサなどの問題に注意してください)。 – user786653

+0

RDTSCはシリアル化命令ではなく、順不同で実行できます。直接使用することを主張する場合は、通常、CPUIDを使用してシリアル化を強制します(これは、ユーザーモードで実行できる少数のシリアル化命令の1つです)。 –

+0

私はQueryPerformanceCounterも持っています。結果によってはあまり信頼できません。 n×n行列乗算の場合、n = 10000以上、時間はわずか0.3秒かかりますか?私はそれがまったく正確ではないと思っています(コンソールでは結果を見るのに2秒以上かかります)ので、私は時計ティックに向いています。 私は今RDTSCを試してみるつもりです。ありがとう。 – CppLearner

答えて

4

QueryPerformanceCounter(少なくともWindows版)は、インラインアセンブリよりもはるかに優れています。インラインアセンブリを使用する理由がわかりません(インラインアセンブリをサポートしていないVisual Studioでx64にコンパイルすると問題が発生します)。

2

他にも気付いたように、QueryPerformanceCounterを使用する必要があります。

しかし、実際にアセンブラを使用する場合は、組み込みの__rdtscを使用するのが最適です。

あなたが固有を使用したくない場合は、これが最良のaproach次のようになります。私の知識のVisual Cの++について

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

はとにかくインラインアセンブラを使用している任意の関数のインラインを行うことを拒否しています。 __declspec(naked)を使用すると、コンパイラにレジスタの使用法を正しく処理させることができます。

しかし、このように組み込み関数を使用すると、コンパイラはどのレジスタが使用され、適切な方法でインライン展開されているかを知ることができます。

1

0F31はRDTSC命令であり、短いコードのパフォーマンスを測定するのに役立ちます。 i3 CPUの場合でも。タスクの切り替えやスレッドを別のコアに移行しても問題がなければ、RDTSCを使用しても問題ありません。多くの場合、CPUIDを使ってシリアル化を強制するより正確な結果が得られます。

測定したところ、i3では、不整合なSSEがより速く動作する可能性があります。最新のIntelプロセッサ(NehalemおよびSandy Bridgeアーキテクチャ)は、不整合メモリオペランドを非常に効率的に処理できます。確かに、彼らは決して整列した命令を上回ることはありませんが、あなたのテストでパフォーマンスに影響を与えるいくつかの要因がある場合、整列した命令は遅く動作するように見えるかもしれません。

編集:

http://www.agner.org/optimize/#testpを参照してください。 RDTSC命令の使用例です。

0

QueryPerformanceCounter()は、Windowsで高頻度のタイマーを取得する最も簡単な方法です。しかし、それはシステムコールであるため、少しオーバーヘッドがあります。— about½ μ s。非常に高速なイベントをタイミングしている場合や、非常に高い精度が必要な場合は、問題になる可能性があります。

精度が250ナノ秒を超える場合は、the rdtsc intrinsicを使用してハードウェアカウンタを直接取得できます。私のi7では約10nsの遅延があります。

関連する問題