c - 高速化 - stream index



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

VtuneやoprofのようなツールでEMONプロファイリングを試してみてください

EMON(Event Monitoring)profiling =>時間ベースのツールのようですが、問題の原因となっているパフォーマンス・イベントを教えてくれます。 しかし、最初に時間ベースのプロファイルで始めて、飛び出す特定の命令があるかどうかを確認する必要があります。 (そしておそらく、そのIPに退職のストールがどのくらいの頻度であったかを伝える関連イベント)。

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

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

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

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

実際、LL3 / L3 $ /いわゆるUncoreのパフォーマンスカウンタがあります。 VTuneがそれらをサポートしていない場合、私は非常に驚くでしょう。 http://software.intel.com/sites/products/collateral/hpc/vtune/performance_analysis_guide.pdf VTuneやPTUなどのツールを参照してhttp://software.intel.com/sites/products/collateral/hpc/vtune/performance_analysis_guide.pdf 。 実際、LL3イベントがなくても、David Levinthal氏は次のように述べています。「インテル®Core™i7プロセッサーは、Itanium®プロセッサー・ファミリーのデータEARイベントと非常によく似たレイテンシ・イベントを持っています。測定されたレイテンシがMSR 0x3f6、ビット15:0にプログラムされた最小レイテンシより大きい場合、カウンタはインクリメントされます。カウンタオーバーフローはPEBSメカニズムをアームし、次のレイテンシしきい値、測定されたレイテンシ、バーチャルまたはリニアアドレス、およびデータソースを満たすイベントは、PEBSバッファ内の3つの追加レジスタにコピーされます。仮想アドレスは既知の場所にキャプチャされるため、サンプリングドライバは、物理アドレスはNUMAホームロケーションを識別し、原則的にキャッシュ占有の詳細の分析を可能にします。 また、35ページで、L3 CACHE_HIT_UNCORE_HITやL3 CACHE_MISS_REMOTE_DRAMなどのVTuneイベントを指摘しています。 場合によっては数値コードを検索してVTuneの低レベルインターフェースにプログラムする必要がありますが、この場合はきれいなユーザーインターフェースで表示されると思います。

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

彼は間違っています。たとえば、CPUを1つだけ有効にし、サンプルを意味のあるものにすることができます。 私は、L3欠損データをCPUに返す際に欠落しているデータをマークする機能があるとも信じています。 実際、全体的にL3はどのCPUにデータを返すのかを知っているので、間違いなくサンプリングすることができます。 あなたはどのハイパースレッドを知ることはできませんが、もう一度、シングルスレッドモードにすることはできません。

しかし、それはむしろ一般的であるように、これを行うにはVTuneの周りで作業しなくてはならないように見えます。

最初にレイテンシプロファイリングを試してください。 これは完全にCPUの中にあり、VTuneの人々はあまりにもそれを混乱させることはまずありません。

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

Levinthalごとに "Cycle Accounting"を試してみてください。

この質問は私の質問で続けられます(神秘的なアドバイスによる):

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);
    }

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

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

movss操作後にスカラー重量値をXMMレジスタに移動し、 shufpsを使用してベクトル全体にこのスカラー値をコピーする余分な命令がありますが、スケジュールが変更されていないように見えます。 ウェイトベクトルは、負荷から浮動小数点ドメインへのスイッチングレイテンシをmulps 、時間の経過とともに、余分なレイテンシが発生しないように、 mulpsに対して使用する準備ができているようです。

このカーネルで使用されている(アセンブリコードでチェックされている) movaps (整列された、パックされた移動)、 addpsmulps命令はスカラーバージョンと同じレイテンシとスループットを持っているので、余分なレイテンシも発生しません。

誰もがこのカーネルが得ることができる最高の性能がサイクル当たり6.4 FPの暴露であると仮定して、8サイクルあたりのこの余分なサイクルが費やされているアイデアを持っていますか?それはサイクルあたり5.6 FPの睡眠で動いていますか?

ところで、実際のアセンブリは次のようになります。

…
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> 
…




assembly