19

組み込みシステムと初期の 8/16 ビット PC (6502、68K、8086) をプログラミングしていたとき、各命令の実行にかかる正確な時間 (ナノ秒またはマイクロ秒) をかなりよく把握していました。ファミリによっては、1 (または 4) サイクルが 1 回の「メモリ フェッチ」に相当し、キャッシュを気にする必要がなければ、関係するメモリ アクセスの数に基づいてタイミングを推測できます。

しかし、最近の CPU では混乱します。それらがはるかに高速であることは知っていますが、見出しのギガヘルツ速度は、各命令に必要なクロックのサイクル数を知らなければ役に立たないことも知っています.

したがって、2GHz Core 2 Duo (としましょう) で、2 つのサンプル命令のタイミングを誰かが提供できますか。最良のケースと最悪のケース (キャッシュに何もない/すべてがキャッシュにあると仮定) が役に立ちます。

命令 #1: 1 つの 32 ビット レジスタを 2 番目に追加します。

命令 #2: 32 ビット値をレジスタからメモリに移動します。

編集:私がこれを尋ねる理由は、単純なコードを見て、最も近い桁までの時間を大まかに測定できるようにする「経験則」を開発しようとすることです。

編集#2:興味深い点を含む多くの回答がありますが、(まだ)誰も時間で測定された数字を書き留めていません. 質問に「複雑さ」があることは承知していますが、おいでください: NYC のピアノ調律師の数を見積もることができれば、コードの実行時間を見積もることができるはずです...

次の (ダム) コードを使用します。

int32 sum = frigged_value();

// start timing
 for (int i = 0 ; i < 10000; i++)
 {
   for (int j = 0 ; j < 10000; j++)
   {
     sum += (i * j)
   }
   sum = sum / 1000;
 }

// end timing

実行にかかる時間をどのように見積もればよいでしょうか... 1 フェムト秒ですか? 1ギガ年?

4

15 に答える 15

40

あなたが言及するCore 2 Duoなどの最新のプロセッサは、スーパースカラーパイプラインの両方です. コアごとに複数の実行ユニットがあり、実際にはコアごとに一度に複数の命令を処理しています。これがスーパースカラー部分です。パイプライン化された部分とは、命令が読み込まれて「発行」されてから実行が完了するまでの待ち時間があることを意味します。この時間は、その命令と他の実行ユニットを同時に移動する他の命令との間の依存関係によって異なります。したがって、事実上、特定の命令のタイミングは、その周りにあるものと依存するものによって異なります。これは、特定の命令には、いくつかの要因に基づいて、最良のケースと最悪のケースの実行時間があることを意味します。複数の実行ユニットがあるため、実際にはコアクロックごとに実行を完了する複数の命令を持つことができます。

上記はすべて、CPU コア自体から見たものです。次に、キャッシュとのやり取りと、他のコアとの帯域幅の競合があります。CPUのバス インターフェイス ユニットは、命令とデータをコアに送り、その結果をキャッシュを介してコアからメモリに戻す処理を行います。

一粒の塩で取るべき経験則の大まかな順序:

  • Register to Register 操作の実行には 1コアクロックが必要です。これは、特にこれらの多くが順番に表示されるため、一般的に保守的である必要があります。
  • メモリ関連のロードおよびストア操作の実行には、1メモリ バスクロックが必要です。これは非常に保守的でなければなりません。キャッシュ ヒット率が高いと、CPU コアとキャッシュの間のバスのクロック レートである 2 CPU バスクロックのようになりますが、必ずしもコアのクロックではありません。
于 2009-01-11T16:16:48.197 に答える
14

期待している正確なタイミング情報を、役に立つ方法で提供することはほぼ不可能です。

次の概念は、命令のタイミングに影響します。一部は刻々と変化する可能性があります。

  • マイクロオペレーションの分解
  • オペレーションのパイプライン
  • スーパースカラー実行
  • 順不同の実行
  • SMT / SMPの実行
  • 浮動小数点モード
  • 分岐予測・プリフェッチ
  • キャッシュのレイテンシ
  • メモリレイテンシ
  • クロック速度の調整

上記の概念についてさらに説明が必要な場合は、最新のコンピューター アーキテクチャに関する本を参照してください。

コードの速度を測定する最良の方法は、(驚くべきことに!) 「現実の世界」で期待するのと同じワークロードを同じ条件下で実行するコードの速度を測定することです。

于 2009-01-11T16:37:05.567 に答える
7

それほど単純ではありません。2 つの命令のタイミングは、より大きな一連の命令のパフォーマンスを測定するのにはあまり役立ちません。これは、最新のプロセッサが多くの操作を並行して実行でき、大きなキャッシュを備えているため、「値をメモリに移動する」ことが命令の実行からかなり離れた時間に行われるためです。

したがって、最良のケースはゼロです (他の命令と並行して実行される場合)。しかし、それはどのように役立ちますか?

このWeb ページには、%MIPS/MHz の結果を含むいくつかのベンチマークが表示されます。ご覧のとおり、多くのベンチマークでは、クロック サイクルごとに複数の命令が実行されています。グラフには、キャッシュ サイズとメモリ速度の影響も示されています。

于 2009-01-11T16:01:28.837 に答える
7

あなたが求めている種類の予測は絶望的です。

経験則が必要な場合は、経験則をいくつか示します。

  • レベル 2 キャッシュからワードを取得するのにかかる時間で、プロセッサは少なくとも 10 個の命令を実行できます。したがって、命令数ではなく、メモリ アクセスについて心配する必要があります。レジスタ内の計算はほとんど無料です。

  • RAM からワードを取得するのにかかる時間で、プロセッサは数千の命令を実行できます (この数は、ハードウェアの詳細によって数桁異なります)。これがコールド キャッシュでのみ発生することを確認してください。そうでなければ、他に何も問題はありません。

  • x86 CPU で実行している場合、十分なレジスタがありません。いつでも、コード内に 5 つを超えるライブ変数を含めないようにしてください。または、さらに良いことに、AMD64 ( x86_64) に移行して、レジスターの数を 2 倍にします。16 個のレジスターとパラメーターがレジスターに渡されるため、レジスターについて心配する必要はありません。

毎年、コンパイラーが生成するコードのコストを予測するためにどのような経験則を使用すべきかをアーキテクトに尋ねていた時期がありました。最後に有用な回答を受け取ったのは 1999 年だったので、ここでやめました。現在使用しているコンピューターのリオーダー バッファーのサイズを確認できるかどうかを確認してください)。

于 2009-01-11T20:45:32.757 に答える
7

最新のプロセッサは、さらにトリッキーなことを行います。

順不同の実行。正しい動作に影響を与えずに実行できる場合、プロセッサは、プログラムにリストされている順序とは異なる順序で命令を実行する可能性があります。これにより、実行時間の長い命令のレイテンシを隠すことができます。

改名を登録します。多くの場合、プロセッサには、命令セット内のアドレス指定可能なレジスタ (いわゆる「アーキテクチャ」レジスタ) よりも多くの物理レジスタがあります。これは、下位互換性のためか、単に効率的な命令エンコーディングを有効にするためです。プログラムが実行されると、プロセッサーは、使用するアーキテクチャー・レジスターを、空いている物理レジスターに「名前変更」します。これにより、プロセッサは元のプログラムよりも多くの並列処理を実現できます。

たとえば、EAX と ECX に長い一連の操作があり、その後に EAX と ECX を新しい値に再初期化して別の長い一連の操作を実行する命令が続く場合、プロセッサは両方のタスクに異なる物理レジスタを使用して実行できます。それらを並行して。

インテル P6 マイクロアーキテクチャーは、アウトオブオーダー実行とレジスターの名前変更の両方を行います。Core 2 アーキテクチャは、P6 の最新の派生製品です。

実際にあなたの質問に答えるには、これらすべてのアーキテクチャの最適化に直面して、手動でパフォーマンスを判断することは基本的に不可能です。

于 2009-01-11T16:38:15.297 に答える
5

これはあなたの質問の一部にしか答えていませんが、参照の局所性に関するウィキペディアのこの表が役に立ちました。およそ 2006 倍を使用して、メモリ階層のさまざまなレベルでのメモリへのアクセス速度とメモリ量を示します。

  • CPU レジスタ (8 ~ 32 レジスタ) – 即時アクセス (0 ~ 1 クロック サイクル)
  • L1 CPU キャッシュ (32 KiB ~ 128 KiB) – 高速アクセス (3 クロック サイクル)
  • L2 CPU キャッシュ (128 KiB から 12 MiB) – わずかに遅いアクセス (10 クロック サイクル)
  • メインの物理メモリ (RAM) (256 MiB から 4 GiB) – 低速アクセス (100 クロック サイクル)
  • ディスク (ファイル システム) (1 GiB から 1 TiB) – 非常に遅い (10,000,000 クロック サイクル)
  • リモートメモリ (他のコンピュータやインターネットなど) (事実上無制限) – 速度はさまざま
于 2009-02-21T08:55:31.853 に答える
4

Intel64およびIA-32のマニュアルはこちらからダウンロードできます。

しかし、本当に必要なのはAgnerFogのものです。

彼は多くの追加情報を持っています。たとえば、彼のマニュアル「命令テーブル:IntelおよびAMD CPUの命令レイテンシ、スループット、およびマイクロオペレーションの内訳のリスト」です。

または、クロックサイクルをカウントするためのプログラムをテストします(彼はタイムスタンプカウンターを使用します)。

于 2009-01-26T16:55:48.043 に答える
4

このスレッドにはすでに多くの適切な回答がありますが、これまで言及されていないトピックが 1 つあります。それは、 branch mispredictionです。

最新のプロセッサはすべてパイプライン化されているため、命令デコーダーが「等しい場合はジャンプ」のような命令に遭遇した場合、命令がどの方向にジャンプするかがわからず、推測するだけです。次に、その推測に基づいてパイプラインに命令を送り続けます。予測が正しければ、ジャンプ命令のスループットとレイテンシは実質的にゼロになります。間違った推測を行うと、同じジャンプ命令のスループットとレイテンシが 50 または 100 サイクルになる可能性があります。

同じ命令がループ内で最初に実行されるときは「ゼロ コスト」になり、次に同じ命令が実行されるときは非常に大きなコストになることに注意してください。

于 2009-01-27T05:32:21.433 に答える
3

AMDソフトウェア最適化ガイドをダウンロードすることをお勧めします。

于 2009-01-27T05:38:10.000 に答える
2

2004 年の Alan Kayの興味深い引用:

余談ですが、興味深いベンチマークを提供します。ほぼ同じシステムで、ほぼ同じ方法で最適化すると、Xerox PARC での 1979 年のベンチマークは、今日では 50 倍速く実行されます。ムーアの法則により、その間に 40,000 倍から 60,000 倍の改善が得られました。つまり、CPU アーキテクチャが悪いと失われる効率は約 1,000 倍になります。

これは、CPU パフォーマンスの向上が、実際に作成するソフトウェアに与える影響が比較的少ない領域に焦点を当てているように見えることを意味しているようです。

于 2009-01-11T18:14:33.543 に答える
2

Doug が既に述べたように、最良のケースはゼロです (スーパースケーラ プロセッサ、複数の実行ユニット、L1 キャッシュにデータが既に存在する場合)。

最悪の場合、最大で数ミリ秒かかります (OS がページフォールトを処理し、ディスクからデータ/命令を取得する必要がある場合)。ディスク/スワッピングを除いても、NUMA マシンがあるかどうか、そのトポロジーの種類、データが存在するメモリ ノード、別の CPU からの同時アクセス (バス ロックおよびキャッシュ同期プロトコル) があるかどうかなどによって異なります。

于 2009-01-11T16:15:22.833 に答える
0

一部のプラットフォームでは、最悪のケースが限定されているとは思いません。同じ場所または隣接するメモリ場所を争う複数のコアとプロセッサがある場合、パフォーマンスのあらゆる種類の低下が見られます。キャッシュラインは、プロセッサ間を移動する必要があります。最近のプラットフォームでのメモリ操作の最悪のケースは見たことがありません。

于 2009-01-26T17:32:46.830 に答える