4

私のコードの内側のループがハードウェア設計の障壁にぶつかっているのか、それとも私の側の障壁を理解していないのかを把握しようとしています。もう少しありますが、私が答えることができる最も簡単な質問は次のとおりです。

次のコードがある場合:

float px[32768],py[32768],pz[32768];
float xref, yref, zref, deltax, deltay, deltaz;

initialize_with_random(px);
initialize_with_random(py);
initialize_with_random(pz);

for(i=0;i<32768-1;i++) {
  xref=px[i];
  yref=py[i];
  zref=pz[i];
  for(j=0;j<32768-1;j++ {
    deltx=xref-px[j];
    delty=yref-py[j];
    deltz=zref-pz[j];
  } }

コード (アセンブリ、組み込み関数など) を完全に制御できるが、アーキテクチャ以外のランタイム環境を制御できない (つまり、マルチユーザー環境に依存しているため、OS カーネルが特定のプロセスに時間を割り当てる方法については何もできません)。

現在、コードで 3 倍のスピードアップが見られます。SSE を使用すると、3 倍のスピードアップが示すよりもはるかに多くのベクトルの深さが得られると考えていました (おそらく、3 倍のスピードアップは、理論上の最大値が 4 倍であることを示しています)。スループット)。(コンパイラがそれらを自動昇格させるほど賢くなかった場合に備えて、deltx/delty/deltz を配列にするなどのことを試しましたが、それでも 3 倍の速度しか見られません。) Intel C コンパイラをベクトル化に適切なコンパイラ フラグがありますが、明らかに組み込み関数はありません。

4

4 に答える 4

4

CPUによって異なります。しかし、理論上の最大値は4倍を超えることはありません。クロックサイクルごとに複数のSSE命令を実行できるCPUを知りません。つまり、サイクルごとに最大4つの値を計算できます。

ほとんどのCPUは、サイクルごとに少なくとも1つの浮動小数点スカラー命令を実行できるため、この場合、理論上最大で4倍のスピードアップが見られます。

ただし、実行しているCPUの特定の命令スループットを調べる必要があります。

ただし、3倍の実用的なスピードアップはかなり良いです。

于 2009-09-23T15:58:49.567 に答える
2

どういうわけか、内側のループをインターリーブする必要があると思います。3成分ベクトルは一度に実行されますが、それは一度に3つの操作だけです。4に到達するには、最初のベクトルから3つのコンポーネントを実行し、次のベクトルから1つのコンポーネントを実行し、次に2と2を実行します。一度に4つのコンポーネントのデータをロードして処理するある種のキューを確立し、後でそれを分離すると、それが機能する可能性があります。

編集:内部ループを展開して、反復ごとに4つのベクトルを実行できます(配列サイズが常に4の倍数であると想定)。それは私が上で言ったことを達成するでしょう。

于 2009-09-23T15:59:34.933 に答える
1

考えてみてください:フロートの幅はどれくらいですか?SSEx命令の幅はどれくらいですか?この比率は、ある種の妥当な上限を与えるはずです。

また、異常なパイプは、高速化の適切な見積もりを取得することに大混乱をもたらすことにも注意する価値があります。

于 2009-09-23T16:00:07.293 に答える
1

ループ タイリングを検討する必要があります。内側のループで値にアクセスする方法が、L1 データ キャッシュで多くのスラッシングを引き起こしている可能性があります。おそらくすべてが 384 KB の L2 に収まるので、それほど悪くはありませんが、L1 キャッシュ ヒットと L2 キャッシュ ヒットの間には桁違いの違いがあるため、これは大きな違いになる可能性があります。

于 2009-10-10T20:05:23.903 に答える