2016-03-30 20 views
1

MSVC v140でコンパイルされた小さなC++プログラムを逆アセンブルし、コード設計がパフォーマンスにどのように影響するかをよりよく理解するために、1命令あたりのサイクル数を見積もっています。私は"Data-Oriented Design and C++"のマイク・アクトンのCppCon 2014講演、特に私がリンクした部分に従っています。それに命令あたりのサイクル数の見積もり

、彼はこれらの行を指摘する:

movss 8(%rbx), %xmm1 
movss 12(%rbx), %xmm0 

彼はその後、これらの2×32ビットの読み取りと主張しているので、おおよそ〜200サイクルを要する同じキャッシュラインにおそらくあります。

Intel 64 and IA-32 Architectures Optimization Reference Manualは、特に「付録C - 命令のレイテンシとスループット」です。しかし、のC-15ページの「表C-16。ストリーミングSIMD拡張単精度浮動小数点命令」はmovssが1サイクルであることを示していますもしそうなら、私はこの物をどのように読みますか?)

私はtheoretical prediction of execution timeが決して正しいとは限りませんが、これは学ぶことが重要であることを知っています。 これらの2つのコマンドはどのように200サイクルになりますか?このスニペットを超えて実行時間についての理由を知る方法を教えてください。

私はCPUパイプライニングでいくつかのことを読み始めました。おそらくサイクルの大部分がそこに集められていますか?

PS:実際にここでハードウェアパフォーマンスカウンタを測定することには興味がありません。私はちょうど合理的な視力がASMとサイクルを読む方法を学ぶために探しています。

+1

あなたはAgner Fogの仕事を見ましたか? http://www.agner.org/optimize/instruction_tables.pdf –

+2

サイクルはもうカウントできません。今は長い間そうではありません。パイプライン化、キャッシュ、分岐予測など...パイプライン化は、工場のような組み立てラインに過ぎません。あなたは1つのことを構築するために117のステップまたはステーションを持っているかもしれませんが、それぞれが30秒かかるかもしれませんが、それは生産ラインのために1時間に1つではなく30秒ごとに生成される1つのアイテムを理論的に得ることを意味します。それは彼らがバックエンドからどれくらい早く出てくるかです。 –

+0

ほとんどすべての命令がEXECUTEに1クロックかかる場合は、キャッシュミスを介して比較的遅い時間にフェッチするのに15~1000クロックかかることがありますが、他のすべてのステップはパイプラインには影響しませんが、パイプラインの1ステップ分に1クロックかかる。その後、レジスタや低速メモリなどの結果を保存して、次のものをすべて保存してください。 –

答えて

2

すでに指摘したように、MOVSS命令の理論的なスループットとレイテンシは1サイクルです。あなたは正しい文書(Intel Optimization Manual)を見ていました。 Agner Fog(コメントに記載)は、Intruction TablesのインテルCPU(AMDはレイテンシが高い)で同じ数値を測定しました。

これは最初の問題につながります。具体的なマイクロアーキテクチャはどのような調査をしていますか?同じベンダーであっても、これは大きな違いをもたらす可能性があります。 Agner FogはMOVSSがソースとデスティネーション(レジスタとメモリ)によってAMD Bulldozerに2〜6cyレイテンシを持つと報告しています。これは、コンピュータアーキテクチャのパフォーマンスを検討する際に留意することが重要です。

200cyは、おそらくコメントでdwelchであると指摘されているように、おそらくキャッシュミスです。最適化マニュアルから任意のメモリアクセス命令の数値は、すべてデータが第1レベルのキャッシュ(L1)にあることを前提としています。これまでの手順でデータに触れたことがない場合は、キャッシュライン(IntelとAMD x86の64バイト)をメモリから最後のレベルのキャッシュにロードし、そこから2番目のレベルのキャッシュに、最後にL1に、そして最後に(1サイクル以内に)XMMレジスタに格納します。 L3-L2とL2-L1間の転送には、現在のインテルマイクロアーキテクチャ上でキャッシュ・ライン当たり2サイクルのスループット(レイテンシではありません)があります。そして、メモリ帯域幅は、L3とメモリとの間のスループットを推定するために使用することができる(例えば、2GHzのCPU、達成可能なメモリ帯域幅が40GB/sの場合、キャッシュライン当たり3.2サイクルのスループットを有する)。キャッシュラインまたはメモリブロックは、通常、最小ユニットキャッシュであり、メモリは動作可能であり、マイクロアーキテクチャ間で異なり、キャッシュレベル(L1、L2など)に応じてアーキテクチャ内でも異なることさえあります。

これはすべてスループットであり、レイテンシではありません。上で説明した内容を見積もるのには役立ちません。これを確認するには、サイクルの正確な測定値を得るために命令を何度も実行する必要があります(少なくとも1/10秒間)。命令を変更することで、レイテンシ(命令間の依存関係を含める)またはスループット(前の命令の結果とは独立した命令の入力)を測定するかどうかを決定できます。キャッシュとメモリアクセスを測定するには、アクセスがキャッシュになるかどうかを予測する必要がありますが、これはlayer conditionsを使用して行うことができます。

Intel CPUの命令実行(レイテンシとスループットの両方)を見積もるツールは、Intel Architecture Code Analyzerであり、Haswellまでの複数のマイクロアーキテクチャをサポートしています。レイテンシの予測は、スループットよりレイテンシを見積もることがずっと困難なため、塩の粒で行われます。

+0

一般に、IACAは塩の穀物で取られなければならない。キャッシュミスは想定されておらず、モデルの仕組みにはいくつかの制限があります。 IDKではなぜスループットよりレイテンシを見積もるのが難しいと言われていますか?実行ポートが同じサイクルで2つの結果を生成しようとするライトバックの競合を避けるという点で、アウトオブオーダーのスケジューラの仕事がはるかに容易になるため、ほぼすべての命令のレイテンシは固定されています。とにかく、IACAはキャッシュミスをシミュレートしないので、レイテンシーの厄介なことは、インプットの準備ができ次第insnの実行を停止させるリソースの競合だけです。 –

+0

あなたの権利。すべてのデータがL1で利用可能であると仮定した場合、コア内のレイテンシは、スループットよりも推定するのが難しくありません。しかし、それが他のキャッシュ・レベルまたはメモリーからの負荷に依存すると、スループットよりもはるかに離れていることを予測することは非常に困難になります。これは、レイテンシの概念のために、単一の遅延は全体のレイテンシを増加させるが、単一の遅延は総命令数に目立つだけのスループットを減少させることに起因する。 はい、IACAの予測は常に塩の塊で行われなければなりませんが、スループットの性質はエラーをより緩和します。 – como

+0

したがって、IACAのレイテンシ数はスループット数より現実に合致する可能性が低いと言います。あなたがL3ミスを多用していない限り、それはある意味があります。メモリレイテンシがクリティカルパスの一部でない場合、L3でヒットしたL2ミスでさえもスループットにあまり影響を与えないかもしれないが、メインメモリレイテンシはパイプラインをストールさせスループットにも影響する。 –

関連する問題