2

問題がある C++ コードの一部を次に示します。

std::bitset<64>a;
std::bitset<64>b;
std::bitset<64>c;
int bit_count=0;
std::vector<int> vec(SIZE,0);
for (i=1;i<NUM;i++)
{
  // I do here some operations on a and b (a and b will have bits that are set)
  c=a^b;
  bit_count=(int) c.count(); // LINE 1
  vec[i]=bit_count; // LINE2 2
}

私の問題は次のとおりです。

  1. LINE 1 と LINE 2 にコメントを付けると、コードは約 1 秒で実行されます。109ms;
  2. LINE2 のみをコメントすると、コードは約実行されます。115 ミリ秒で。
  3. LINE 1 と bit_count=0 をコメントすると、コードは約 130 ミリ秒実行されます。
  4. 両方の行 (LINE 1 と 2) がコメント化されていない場合、コードは約 1 秒で実行されます。350ミリ秒。

LINE1 と LINE2 を使用するとコードが遅くなるのはなぜですか? 納得のいく説明が見つかりません。

vec.push_back(bit_count) も試してみましたが、これも遅いことに注意してください。また、さまざまなキャスト操作を試みましたが、成功しませんでした。

4

1 に答える 1

2

ケース 2 では、bit_count が使用されないため、コンパイラは bit_count を完全に計算しない場合があります (たとえば、XOR を実行するが、カウントは実行しない可能性があります)。

ケース 3 では、割り当てだけがあります。

ケース 4 の場合のみ、bit_count (かなり高価です) を実行する必要があります。

(明確にするために編集: を使用vecしない場合でも、ループ全体が破棄される可能性があります。ただし、そうする必要はありません)


追加情報:

コンパイラは、次のように定義された観察可能な動作のみを保持する必要があります。

  • 揮発性オブジェクトへのアクセス
  • 入出力 (ファイルを含む)
  • 「不明な」コード (外部ライブラリなど) の呼び出し

もちろん、標準的な言い回しはもっと複雑です。この質問には追加の議論があります。

コンパイラを観察するのは、いつも興味深い演習だと思います。ほとんどの場合、分解出力を有効にできます。探究心と、1 時間の「プロセッサのアセンブリの紹介」がベルトの下にあるため、そのような小さな演習は非常に洞察に満ちています

于 2011-11-23T19:38:02.570 に答える