7

何らかの理由で、私のコードは整数よりも倍精度でスワップを実行できます。なぜこれが起こるのか私にはわかりません。

私のマシンでは、ダブル スワップ ループは整数スワップ ループよりも 11 倍速く完了します。double/integer のどのプロパティが、このように実行するのですか?

テスト設定

  • Visual Studio 2012 x64
  • CPU コア i7 950
  • Release としてビルドし、exe を直接実行します。VS Debug フックは物事をゆがめます

出力:

Process time for ints 1.438 secs

Process time for doubles 0.125 secs

#include <iostream>
#include <ctime>
using namespace std;

#define N 2000000000

void swap_i(int *x, int *y) {
    int tmp = *x;
    *x = *y;
    *y = tmp;
}

void swap_d(double *x, double *y) {
    double tmp = *x;
    *x = *y;
    *y = tmp;
}

int main () {
    int a = 1, b = 2;
    double d = 1.0, e = 2.0, iTime, dTime;
    clock_t c0, c1;

    // Time int swaps
    c0 = clock();
    for (int i = 0; i < N; i++) {
        swap_i(&a, &b);
    }
    c1 = clock();
    iTime = (double)(c1-c0)/CLOCKS_PER_SEC;

    // Time double swaps
    c0 = clock();
    for (int i = 0; i < N; i++) {
        swap_d(&d, &e);
    }
    c1 = clock();
    dTime = (double)(c1-c0)/CLOCKS_PER_SEC;

    cout << "Process time for ints " << iTime << " secs" << endl;
    cout << "Process time for doubles  " << dTime << " secs" << endl;
}

Blastfurnace が説明したように、VS はループの 1 つだけを最適化したようです。

すべてのコンパイラの最適化を無効にして、スワップ コードをループ内にインライン化すると、次の結果が得られました (タイマーも std::chrono::high_resolution_clock に切り替えました)。

Process time for ints 1449 ms

Process time for doubles 1248 ms

4

1 に答える 1

10

生成されたアセンブリを見ることで答えを見つけることができます。

Visual C++ 2012 (32 ビット リリース ビルド) を使用すると、 の本体swap_iは 3 つのmov命令ですが、 の本体swap_dは完全に最適化されて空のループになります。コンパイラは、偶数回のスワップが目に見える効果がないことを確認するのに十分スマートです。intループで同じことをしない理由がわかりません。

体を変え#define N 2000000000#define N 2000000001作り直すだけで、swap_d体は実際の仕事をします。最終的な時間は、私のマシンでswap_dは約 3% 遅くなりました。

于 2012-09-16T02:23:18.153 に答える