62

特定のアセンブリ命令に必要な CPU サイクルについて説明しているインテルのオンライン ブックがあると聞きましたが、(一生懸命試した後) 見つけることができません。CPUサイクルを見つける方法を教えてください。

以下に例を示します。以下のコードでは、mov/lock は 1 CPU サイクル、xchg は 3 CPU サイクルです。

// This part is Platform dependent!
#ifdef WIN32
inline int CPP_SpinLock::TestAndSet(int* pTargetAddress, 
                                              int nValue)
{
    __asm
    {
        mov edx, dword ptr [pTargetAddress]
        mov eax, nValue
        lock xchg eax, dword ptr [edx]
    }
    // mov = 1 CPU cycle
    // lock = 1 CPU cycle
    // xchg = 3 CPU cycles
}

#endif // WIN32

ところで: ここに私が投稿したコードの URL があります: http://www.codeproject.com/KB/threads/spinlocks.aspx

4

5 に答える 5

30

パイプライン処理、順不同処理、マイクロコード、マルチコア プロセッサなどを考えると、アセンブリ コードの特定のセクションが正確に x CPU サイクル/クロック サイクル/任意のサイクルを要するという保証はありません。

そのような参照が存在する場合、特定のアーキテクチャが与えられた場合にのみ広範な一般化を提供することができ、マイクロコードの実装方法によっては、Pentium M が Core 2 Duo と異なり、AMD デュアル コアとは異なることがわかる場合があります。など

この記事は 2000 年に更新され、以前に書かれたものであることに注意してください。Pentium 4 でさえ、命令タイミングに関して特定するのは困難です。PIII、PII、および元の pentium の方が簡単でした。参照されているテキストは、おそらく、命令タイミングがより明確に定義された初期のプロセッサに基づいていました。

最近では、一般的に統計分析を使用してコードのタイミングを推定しています。

于 2009-03-28T13:00:30.223 に答える
27

最新のCPUで実行されているコードのパフォーマンスを正確に予測することは不可能であるという他の回答の内容は真実ですが、それはレイテンシーが不明であることや、レイテンシーを知ることが役に立たないことを意味するものではありません。

IntelおよびAMDのプロセッサの正確なレイテンシは、AgnerFogの命令表に記載されています。インテル®64およびIA-32アーキテクチャー最適化リファレンス・マニュアル、およびAMDおよびインテルx86プロセッサーの命令レイテンシーとスループット(CanBerkGüderの現在削除されているリンクのみの回答から)も参照してください。AMDはまた、公式の値を記載したPDFマニュアルを自社のWebサイトに掲載しています。

タイトループを(マイクロ)最適化する場合、各命令のレイテンシーを知ることは、コードを手動でスケジュールするのに大いに役立ちます。プログラマーは、コンパイラーができない多くの最適化を行うことができます(コンパイラーは、プログラムの意味を変更しないことを保証できないため)。

もちろん、これには、CPUのパイプラインの深さ、サイクルごとに発行できる命令の数、実行ユニットの数など、CPUに関するその他の多くの詳細を知る必要があります。そしてもちろん、これらの数値はCPUによって異なります。しかし、多くの場合、すべてのCPUで多かれ少なかれ機能するという妥当な平均を思い付くことができます。

ただし、このレベルで数行のコードを最適化するのは大変な作業です。そして、悲観的なものになるのは簡単です。最近のCPUは非常に複雑であり、悪いコードから良いパフォーマンスを得るために非常に懸命に努力しています。ただし、効率的に処理できない場合や、賢くて効率的なコードを作成していると思われる場合もあり、CPUの速度が低下することがわかります。

編集 インテルの最適化マニュアルの表C-13を参照してください。最初の列は命令タイプであり、次に各CPUIDのレイテンシーの列がいくつかあります。CPUIDは、番号が適用されるプロセッサフ​​ァミリを示し、ドキュメントの他の場所で説明されています。レイテンシーは、命令の結果が利用可能になるまでにかかるサイクル数を指定するため、これが探している数値です。

スループットの列には、このタイプの命令のうち1サイクルあたりに実行できる命令の数が表示されます。

この表でxchgを調べると、CPUファミリに応じて、1〜3サイクルかかり、movは0.5〜1サイクルかかることがわかります。これらは、レジスタ間形式の命令用でありlock xchg、メモリ付きではなく、はるかに低速です。さらに重要なのは、レイテンシーと周囲のコードへの影響が非常に変動するため(別のコアとの競合がある場合ははるかに遅くなる)、ベストケースだけを見るのは間違いです。(各CPUIDの意味は調べていませんが、.5はPentium 4用であり、チップの一部のコンポーネントを2倍の速度で実行し、半サイクルで処理できると思います)

この情報を何に使用する予定かはわかりませんが、コードが実行されている正確なCPUファミリがわかっている場合は、レイテンシを合計すると、この一連の命令を実行するために必要な最小サイクル数がわかります。 。

于 2009-03-28T14:02:06.613 に答える
15

CPU サイクルの測定とカウントは、x86 ではもはや意味がありません。

まず、サイクルをカウントしている CPU を自問してみてください。コア-2? アスロン?ペンティアム-M? 原子?これらの CPU はすべて x86 コードを実行しますが、実行時間はすべて異なります。実行は、同じ CPU の異なるステッピング間でも異なります。

サイクル カウントが有効な最後の x86 は Pentium-Pro でした。

また、CPU 内部では、ほとんどの命令がマイクロコードにトランスコードされ、x86 のようには見えない内部実行ユニットによって順不同で実行されることも考慮してください。単一の CPU 命令のパフォーマンスは、内部実行ユニットで使用可能なリソースの量によって異なります。

したがって、命令の時間は、命令自体だけでなく、周囲のコードにも依存します。

とにかく、さまざまなプロセッサのスループット リソースの使用量と命令のレイテンシを見積もることができます。関連情報は、Intel および AMD のサイトにあります。

Agner Fog は、彼の Web サイトに非常に優れた要約を掲載しています。待ち時間、スループット、および uop カウントについては、命令表を参照してください。それらを解釈する方法については、マイクロアーキテクチャ PDF を参照してください。

http://www.agner.org/optimize

ただしxchg、1 つの CPU モデルだけを見ても、-with-memory のパフォーマンスは予測できないことに注意してください。L1D キャッシュでキャッシュ ラインが既にホットで競合がない場合でも、完全なメモリ バリアであることは、その影響が周囲のコード内の他のアドレスへのロードとストアに大きく依存することを意味します。


ところで - サンプルコードはロックフリーのデータ構造の基本的な構成要素であるため: コンパイラの組み込み関数の使用を検討しましたか? win32 では、intrin.h をインクルードして、_InterlockedExchange などの関数を使用できます。

コンパイラは命令をインライン化できるため、実行時間が短縮されます。インライン アセンブラは常に、コンパイラに asm コード周辺の最適化を無効にするように強制します。

于 2009-03-28T13:09:11.047 に答える