4

にのみ収まる入力の問題については、データレイアウトStructs of ArraysSoAArray of Structs )が(AoS)またはArray of PointersAoP )よりも常に高速であるかどうか疑問に思いRAMましたC/JAVA

数日前、私は分子動力学アルゴリズム(C)のパフォーマンスを改善していました。このアルゴリズムで要約すると、粒子間の力と位置に基づいて粒子間の力の相互作用が計算されます。

元の粒子は、9つの異なるdoubleを含む構造体で表されていました。3つは粒子の力(Fx、Fy、Fz)、3つは位置、3つは速度です。アルゴリズムには、すべてのパーティクルへのポインタを含む配列がありました(AoP)。キャッシュの使用を改善するために、レイアウトをAoPからSoAに変更することにしました。

これで、9つの配列を持つ構造体ができました。各配列には、各粒子の力、速度、位置(x、y、z)が格納されています。各パーティクルには、独自の配列インデックスによってアクセスされます。

パフォーマンス(RAMにのみ収まる入力の場合)が約1.9倍向上したので、通常AoPまたはAoSからSoAに変更すると、常にパフォーマンスが向上するのではないかと思いました。そうでない場合は、どのタイプのアルゴリズムでこれを行うのでしょうか。発生しません。

4

2 に答える 2

8

すべてのフィールドがどれだけ役立つかに大きく依存します。1つのフィールドを使用すると、すべてのフィールドを使用する可能性が高いデータ構造がある場合、構造体の配列は、必要になる可能性のあるすべてのものをまとめて保持するため、より効率的です。

可能なフィールドのほんの一部を選択するだけでよい時系列データがあるとします。イベントや特定の時点に関するあらゆる種類のデータがあるかもしれませんが、必要なのはそのうちの3〜5つだけです。この場合、配列の構造はより効率的です。これは、a)使用しないフィールドをキャッシュする必要がないためb)値に順番にアクセスすることが多いためです。つまり、フィールド、その次の値、およびその次の値が便利です。

このため、時系列情報は列のコレクションとして保存されることがよくあります。

于 2012-10-30T16:02:18.880 に答える
3

これは、データにどの程度正確にアクセスするかによって異なります。SoAまたはAoSのいずれかで、データにアクセスしたときにハードウェアで正確に何が起こるかを想像してみてください。

あなたの質問について推論するには、次のことを検討する必要があります-

  1. キャッシュがない場合、メモリアクセスレイテンシがデータのすべての要素で等しいと仮定すると、パフォーマンスは同じである必要があります。
  2. キャッシュを使用すると、連続するアドレスの場所にアクセスすると、パフォーマンスが確実に向上します。これはあなたの場合に正確に有効です。AoSを使用している場合、場所はメモリ内で連続していないため、そこでパフォーマンスをいくらか失う必要があります。
  3. のようなデータのforループにアクセスしている必要がありますfor(int i=0;i<1000000;i++) Fx[i] = 0。したがって、データの量が膨大な場合は、パフォーマンス上のわずかなメリットを簡単に確認できます。データが小さければ、これはそれほど重要ではありません。
  4. 最後に、使用しているDRAMについてもわかりません。連続したデータにアクセスすると、いくつかの利点があります。たとえば、そのような理由を理解するには、wikiを参照してください。
于 2012-10-30T16:09:03.363 に答える