web-dev-qa-db-ja.com

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

この質問は、ここでの私の質問に続きます(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 FPオペレーションであると予想されます。 。

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

schedule

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

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

このカーネルが取得できる最大パフォーマンスがサイクルあたり6.4 FP 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> 
…
83
Ricky

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ごとに「サイクルアカウンティング」を試してください。

3
Krazy Glew