0

私はこのコードを書きました:

inline int a_plus_b_power2(int a, int b) {
  return (a + b) * (a + b); 
}

int main() {
  for(int a = 0; a < 9999999999999; ++a)
    for(int b = 0; b < 999999999999; ++b)
      a_plus_b_power2(a, b);  

  return 0;
}

しかし、なぜこのプログラムのバイナリはこのプログラムと変わらないのですか?

inline int a_plus_b_power2(int a, int b) {
  return (a + b) * (a + b); 
}

int main() {
  for(int a = 0; a < 9; ++a)
    for(int b = 0; b < 9; ++b)
      a_plus_b_power2(a, b);  

  return 0;
}
4

2 に答える 2

6

ループ展開とインライン化する関数を混乱させています:

ループ展開とは、変換を意味します

for (int i = 0; i < 4; i++)
  a(i);

の中へ

a(0); a(1); a(2); a(3);

一方、関数のインライン化は変換を意味します

void a(int i) { cout << i; }

for (int i = 0; i < 4; i++)
  a(i);

の中へ

for (int i = 0; i < 4; i++)
  cout << i;

コンパイラにはループ展開を有効にするオプションがあります(-funroll-loopsgccの関連オプションを見てください)が、本当に一生懸命突っ込んでいない限り、ほとんどのコンパイラは999999999999回の反復を展開することを非常に嫌がります...(結果のバイナリは数テラバイトになります)。

于 2013-03-09T18:30:30.187 に答える
2

インライン関数は、呼び出しごとに 1 回だけ「貼り付け」られます。

どちらの例でも、インライン関数は何度も呼び出されますが、1 回だけ呼び出されます。

私はあなたがこのようなものが欲しいと信じています:

for (unsigned int a = 0; a < 9; ++a)
{
  for (unsigned int b = 0; b < 9; b+= 3) // Incremented by 3 because of 3 calls in loop.
  {
    a_plus_b_power_2(a, b + 0);
    a_plus_b_power_2(a, b + 1);
    a_plus_b_power_2(a, b + 2);
  }
}

上記の例では、コンパイラがループ内でインライン関数内にコードを 3 回貼り付け、バイナリのサイズを大きくする可能性があります。

注: 最適化をオフにすると、コンパイラがループ内でインライン関数をスタンドアロン関数に変換する可能性があるためです。

于 2013-03-09T18:35:19.873 に答える