コンパイラ

上のループで、ループ不変式の移動(ループの外への移動)の対象になる計算はどれか。(x、yはループ内で変更されないものとする)

for (i = 0; i < n; i++)
    a[i] = b[i] * (x * y);
  1. Ab[i] * (x * y) 全体
  2. Bx * y
  3. Ca[i] への代入
答えと解説を見る

正解:B. x * y

ループ不変式の移動は、繰り返しのたびに同じ値になる計算をループの前に出して、1回だけ計算する最適化です。xとyはループの中で変わらないので、x * y はどの繰り返しでも同じ値になり、t = x * y をループの前で計算して a[i] = b[i] * t とできます。b[i] はiごとに違う値なので、b[i] * (x * y) 全体は移動できません。a[i] への代入も繰り返しごとに別の要素への書き込みなので、ループの中に残します。

  • A. b[i]は繰り返しごとに変わるので、全体は移動できません。
  • B. 正しい。x * yはどの繰り返しでも同じ値です。
  • C. 代入は要素ごとに必要で、ループに残ります。
この分野を解く 分野ページへ

コンパイラのほかの問題

  1. 上のループで、添字の計算 i * 4 に強度低減を行ったときの変換として正しいものはどれか。
  2. 上のループを、SIMD命令を使ってベクトル化しにくい主な理由はどれか。
  3. 上の関数で、コンパイラが *b の読み込みをループの外に出す最適化を、そのままでは行えない理由はどれか。
  4. コンパイラのレジスタ割り当てで、干渉グラフを塗り分ける(彩色する)方法を使うとき、グラフの節と辺が表すものの組み合わせとして正しいものはどれか。
  5. レジスタ割り当てで「スピル」が起こると、生成されるコードはどうなるか。