【ループアンローリング】

ループアンローリング とは?

公開:
💡 同じ作業を数回分並べて、周回の回数を減らす

ループの本体を複数回分並べ、1周で処理する量を増やす最適化。繰り返しの制御を減らせる一方、コードサイズが増え、必ず速くなるわけではない。

📌 このページのポイント
10要素を、4個ずつ+余り2個で処理 元の処理:1要素ずつ、10回 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 展開した本体 1周目 2周目 余り 要素の処理回数ではなく、周回の制御を減らす
処理する要素は同じ10個。展開だけでSIMDや並列実行になるわけではない。
ひよこ ひよこ
ループをほどくってどういうこと?
ペンギン先生 ペンギン先生
1周に1要素を処理していた本体を、たとえば4要素分並べることだよ。すると同じ8要素でも、本体を回す回数を8回から2回にできる。要素への処理そのものは8回分残るけれど、周回を管理する手間を減らせるんだ。
ひよこ ひよこ
要素が10個ならどうなるの?
ペンギン先生 ペンギン先生
4個ずつの本体を2周して8個を扱い、残りの2個を別に処理するよ。図もこの例なんだ。余りを忘れたり配列の外まで読んだりしないよう、元の処理と同じ範囲を扱う必要があるね。
ひよこ ひよこ
4個を同時に実行するの?
ペンギン先生 ペンギン先生
展開するだけなら、本体を並べる変換だよ。複数の値を1命令で扱うSIMDや、複数のスレッドへ仕事を分ける並列化とは別なんだ。ただ、並んだ処理からコンパイラが追加の最適化を見つけやすくなる場合はあるよ。
ひよこ ひよこ
自分で全部書き直すと速くなる?
ペンギン先生 ペンギン先生
そうとは限らないよ。コードが大きくなると不利になることもあるし、コンパイラが自動で展開することもある。GCCの説明でも、コードは大きくなるが速くなるとは限らないとされているんだ。まず測定し、元の結果と同じかも確かめたいね。
もっと詳しく知りたい人へ

処理の順番を変えても大丈夫ですか?

副作用や反復間の依存関係を保つ必要があります。特に浮動小数点の加算などは、計算順序を変えると丸め誤差により結果が変わることがあります。単に本体を順番どおり複製することと、演算を並べ替える最適化を区別します。

ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「ループアンローリング」って出てきたら「本体を数回分並べてループの周回数を減らす工夫」と思えればだいたいOK!

参考資料

← 用語集にもどる