Cコードループのパフォーマンス[続き]


83

この質問は、ここでの私の質問に続きます(Mysticalのアドバイスに基づいて):

Cコードループのパフォーマンス


私の質問を続けると、スカラー命令の代わりにパック命令を使用すると、組み込み関数を使用するコードは非常によく似たものになります。

for(int i=0; i<size; i+=16) {
    y1 = _mm_load_ps(output[i]);
    …
    y4 = _mm_load_ps(output[i+12]);

    for(k=0; k<ksize; k++){
        for(l=0; l<ksize; l++){
            w  = _mm_set_ps1(weight[i+k+l]);

            x1 = _mm_load_ps(input[i+k+l]);
            y1 = _mm_add_ps(y1,_mm_mul_ps(w,x1));
            …
            x4 = _mm_load_ps(input[i+k+l+12]);
            y4 = _mm_add_ps(y4,_mm_mul_ps(w,x4));
        }
    }
    _mm_store_ps(&output[i],y1);
    …
    _mm_store_ps(&output[i+12],y4);
    }

このカーネルの測定されたパフォーマンスは、サイクルあたり約5.6 FP操作ですが、スカラーバージョンのパフォーマンスの正確に4倍、つまりサイクルあたり4.1,6 = 6,4 FPopsであると予想されます。

重み係数の動きを考慮に入れると(それを指摘してくれてありがとう)、スケジュールは次のようになります。

スケジュール

movssスカラーの重み値をXMMレジスタに移動し、shufpsこのスカラー値をベクトル全体にコピーするために使用する操作の後に追加の命令がありますが、スケジュールは変更されていないようです。mulps負荷から浮動小数点ドメインへの切り替え待ち時間を考慮に入れると、重みベクトルをしばらくの間使用する準備ができているようです。したがって、これによって余分な待ち時間が発生することはありません。

movaps(移動を詰め、整列)、 addpsmulpsこれはどちらかの余分な遅延を招くべきではありませんので(アセンブリコードで確認)このカーネルで使用されている命令は、そのスカラーバージョンと同じレイテンシー&スループットを持っています。

このカーネルが取得できる最大パフォーマンスがサイクルあたり6.4FP opsであり、サイクルあたり5.6 FP opsで実行されていると仮定して、この8サイクルあたりの追加サイクルがどこで費やされるかを誰かが知っていますか?


ちなみに、実際のアセンブリは次のようになります。

…
Block x: 
  movapsx  (%rax,%rcx,4), %xmm0
  movapsx  0x10(%rax,%rcx,4), %xmm1
  movapsx  0x20(%rax,%rcx,4), %xmm2
  movapsx  0x30(%rax,%rcx,4), %xmm3
  movssl  (%rdx,%rcx,4), %xmm4
  inc %rcx
  shufps $0x0, %xmm4, %xmm4               {fill weight vector}
  cmp $0x32, %rcx 
  mulps %xmm4, %xmm0 
  mulps %xmm4, %xmm1
  mulps %xmm4, %xmm2 
  mulps %xmm3, %xmm4
  addps %xmm0, %xmm5 
  addps %xmm1, %xmm6 
  addps %xmm2, %xmm7 
  addps %xmm4, %xmm8 
  jl 0x401ad6 <Block x> 
…

ですから、今の質問は、「なぜshufps命令は1.6回の反復ごとに1サイクルを追加するのですか?」ということだと思います。それはタフな1 ...だ
Mysticial

は両方ともFPドメインであるため、の出力はopでshufps直接利用できるはずなので、オーバーヘッドがないと予想しmultpsます
Ricky

簡単に見つけることができます。重みベクトルに非正規化された値の値が含まれていないことを確認してください。シャッフル命令なしでループを試してください。有用な結果は得られませんが、どの命令が追加のサイクルを必要とするかを見つけることができます(もちろん、シャッフルが必要だと思います)。
Gunther Piez 2012

@Mystical:ループの反復ごとに0.75サイクルが追加されています。(4サイクルではなく5サイクルを使用することについての私のコメントではありませんでした...:
Gunther Piez 2012

3
1つは、キャッシュ帯域幅の4倍を要求していることです。データサイズはどのくらいですか?それらはL1キャッシュに収まりますか?
ミスティック2012

回答:


3

VtuneでEMONプロファイリング、またはoprofなどの同等のツールを使用してみてください

EMON(イベント監視)プロファイリング=>時間ベースのツールのようですが、問題の原因となっているパフォーマンスイベントを知ることができます。ただし、最初に時間ベースのプロファイルから始めて、飛び出す特定の命令があるかどうかを確認する必要があります。(そしておそらく、そのIPでリタイアメントストールが発生した頻度を示す関連イベント。)

EMONプロファイリングを使用するには、「通常の容疑者」から...までのイベントのリストを実行する必要があります。

ここでは、キャッシュミス、アライメントから始めます。使用しているプロセッサにRFポート制限のカウンタがあるかどうかはわかりませんが、そうすべきですが、ずっと前にEMONプロファイリングを追加しました。また、マイクロアーキテクチャに適したイベントを追加することで、プロセッサがどれだけうまく対応しているかわかりません。

フロントエンド、命令フェッチ、ストールである可能性もあります。とにかく、これらの命令には何バイトありますか?そのためのEMONイベントもあります。


Nehalem VTuneはL3イベントを見ることができないというコメントへの応答:真実ではありません。これが私がコメントに追加していたものですが、適合しませんでした:

実際には、LL3 / L3 $ /いわゆるUncoreのパフォーマンスカウンターがあります。VTuneがそれらをサポートしていなければ、私は非常に驚きます。http://software.intel.com/sites/products/collat​​eral/hpc/vtune/performance_analysis_guide.pdfを参照してくださいVTuneおよびPTUなどの他のツールを指します。実際、LL3イベントがなくても、David Levinthalが言うように、「インテル®Core™i7プロセッサーには、Itanium®プロセッサーファミリーデータEARイベントと非常によく似た「レイテンシーイベント」があります。このイベントは、ロードをサンプリングし、命令の実行とデータの実際の配信の間を循環します。測定されたレイテンシーがMSR0x3f6、ビット15:0にプログラムされた最小レイテンシーよりも大きい場合、カウンターがインクリメントされます。カウンターオーバーフローはPEBSメカニズムを準備します。レイテンシーのしきい値を満たすイベント、測定されたレイテンシー、仮想アドレスまたは線形アドレス、およびデータソースは、PEBSバッファー内の3つの追加レジスターにコピーされます。仮想アドレスは既知の場所にキャプチャされるため、サンプリングドライバは、仮想から物理への変換を実行し、物理アドレスをキャプチャすることもできます。物理アドレスはNUMAのホームロケーションを識別し、原則としてキャッシュ占有率の詳細の分析を可能にします。」彼はまた、35ページでL3CACHE_HIT_UNCORE_HITやL3CACHE_MISS_REMOTE_DRAMなどのVTuneイベントを指しています。数値を調べる必要がある場合もあります。コードを記述し、VTuneの下位レベルのインターフェイスにプログラムしますが、この場合は、きれいなユーザーインターフェイスに表示されると思います。


OK、http: //software.intel.com/en-us/forums/showthread.php?t = 77700&o = d&s = lrでロシアのVTuneプログラマー(私は思う)はUncoreでサンプリングできないことを「説明」しているイベント。

彼は間違っています。たとえば、CPUを1つだけ有効にして、意味のあるサンプリングを行うことができます。また、CPUに戻るときにL3の欠落データをマークする機能があると思います。実際、全体として、L3はデータを返すCPUを認識しているため、確実にサンプリングできます。どのハイパースレッドかわからない場合もありますが、無効にしてシングルスレッドモードにすることもできます。

しかし、かなり一般的であるように、これを行うには、VTuneを使用せずに、VTuneの周囲で作業する必要があるようです。

最初にレイテンシプロファイリングを試してください。それは完全にCPUの内部にあり、VTuneの人々がそれをあまり台無しにした可能性は低いです。

そして、もう一度言いますが、問題はL3ではなくコアにある可能性があります。したがって、VTuneはそれを処理できるはずです。


Levinthalごとに「サイクルアカウンティング」を試してください。


あなたの反応をありがとう。VTuneを使用してアプリケーションを分析していますが、nehalemアーキテクチャの問題は、L3キャッシュoff-coreがコアの一部に属しているため、この部分で使用できるパフォーマンスイベントカウンターがないことです。したがって、キャッシュミスなどを見積もることは困難です。
リッキー

実際には、LL3 / L3 $ /いわゆるUncoreのパフォーマンスカウンターがあります。VTuneがそれらをサポートしていなければ、私は非常に驚きます。software.intel.com/sites/products/collat​​eral/hpc/vtune/を

コメントに収まらないほど多くのことを書き、それを回答に移動して元のコメントをクリーンアップしようとしましたが、コメントは5分間しか編集できません。短いバージョン:VTuneを使用すると、L3キャッシュミスを確認できます。Uncoreをサポートしていなくても、レイテンシプロファイリングを使用します。Uncoreをサポートしています。
Krazy Glew 2012

そして全体として、あなたの問題はL3キャッシュミスではないと思います。おそらくフロントエンドイベントです。
Krazy Glew 2012

@KrazyGlew:あなたの推測は正しいです、彼はロシア連邦出身のロシア人です。ここではLinkedInの上に彼のプロファイルがある- linkedin.com/in/vtsymbal
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.