メモリ階層と性能
上のようにx座標だけを合計する処理を、配列の構造体(各成分を別々の配列にする形)に書き換えると速くなりやすい理由はどれか。
struct P { float x, y, z, mass; };
struct P p[N];
for (i = 0; i < N; i++)
sx += p[i].x;
- A構造体の配列のままだと、コンパイラがxだけを読み出す命令を作れないから
- B別々の配列にすると、浮動小数点の計算がより高い精度になるから
- Cxだけが連続して並び、読み込んだラインに不要な成分が混ざらないから
答えと解説を見る
正解:C. xだけが連続して並び、読み込んだラインに不要な成分が混ざらないから
構造体の配列(AoS)では、x・y・z・massの16バイトが1組で並ぶので、xだけを読む処理でも64バイトのラインの4分の3は使わないデータになります。各成分を別々の配列(SoA)にすればxだけが連続して並び、読み込んだラインをすべて使えて、メモリの通信量が約4分の1になります。SIMDによるベクトル化もしやすくなります。AoSでもxを読む命令は作れ、配列の形を変えても計算の精度は変わりません。
- A. AoSでもxを読む命令は普通に作れます。
- B. データの並べ方を変えても計算の精度は変わりません。
- C. 正しい。必要なxだけが連続し、ラインを無駄なく使えます。