コンパイラ

上のループで、添字の計算 i * 4 に強度低減を行ったときの変換として正しいものはどれか。

for (i = 0; i < n; i++)
    sum += a[i * 4];
  1. Ai * 4 を、コンパイル時に計算した定数に置き換える
  2. Bループの回数を4分の1に減らし、本体を4回分並べる
  3. C別の変数を用意し、繰り返しごとに4ずつ足していく
答えと解説を見る

正解:C. 別の変数を用意し、繰り返しごとに4ずつ足していく

強度低減は、重い演算を軽い演算に置き換える最適化です。ループの中で i * 4 を毎回掛け算で求める代わりに、j = 0 から始めて繰り返しごとに j += 4 とすれば、掛け算が足し算に変わります。iが変わるたびに値が変わるので、定数に置き換えることはできません。また、4倍の掛け算はシフト命令(i << 2)に置き換えることもでき、これも強度低減の一種です。本体を4回分並べるのはループ展開です。

  • A. iとともに値が変わるので、定数にはできません。
  • B. 本体を並べるのはループ展開です。
  • C. 正しい。掛け算を、繰り返しごとの足し算に置き換えます。
この分野を解く 分野ページへ

コンパイラのほかの問題

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