Loading article…
ループ分割は、コンパイラの最適化手法の一つです。ループを複数のループに分割することで、ループを簡略化したり、依存関係を解消したりします。分割されたループは、同じ本体を持ちながら、インデックス範囲の異なる連続した部分を反復処理します。
ループピーリングは、ループ分割の特殊なケースであり、問題のある最初の(または最後の)数回の反復処理をループから切り離し、ループ本体の外で実行します。
ループが次のように記述されているとします。
int p = 10 ; for ( int i = 0 ; i < 10 ; ++ i ) { y [ i ] = x [ i ] + x [ p ]; p = i ; }p = 10最初の反復処理の場合のみ、他のすべての反復処理では、となることに注意してくださいp = i - 1。コンパイラは、最初の反復処理をループから巻き戻す(または「剥がす」)ことで、このことを利用することができます。
最初の反復処理を終えると、コードは次のようになります。
y [ 0 ] = x [ 0 ] + x [ 10 ]; for ( int i = 1 ; i < 10 ; ++ i ) { y [ i ] = x [ i ] + x [ i - 1 ]; }pこの同等の形式を用いることで、ループ本体内の変数が不要になります。
ループピーリングは、gccバージョン 3.4 で導入されました。より汎用的なループ分割は、GCC 7 で追加されました。[ 1 ]
どうやら「ピーリング」という用語は、キャニングス、トンプソン、スコルニック[ 2 ]が1976年に発表した(人間の)遺伝の計算モデルに関する論文で初めて使用されたようです。そこでは、表現型情報を親に集約する方法を示すためにこの用語が使用されました。その後、この用語は、複雑な家系図上の確率関数に関する彼らの画期的な論文[ 3 ]を含む、彼らの論文で再び使用されました。
コンパイラ技術において、この用語は1980年代後半のVLIWおよびスーパースカラコンパイルに関する論文で初めて登場した。[ 4 ] [ 5 ]