c++ - 性能交换整数与 double

标签 c++ compiler-optimization

出于某种原因,我的代码能够比整数更快地执行 double 交换。我不知道为什么会这样。

在我的机器上,双交换循环的完成速度比整数交换循环快 11 倍。 double /整数的什么属性使它们以这种方式执行?

测试设置

  • Visual Studio 2012 x64
  • 核心 i7 950
  • Build as Release 并直接运行 exe,VS Debug hooks skew things

输出:

整数处理时间 1.438 秒

double 处理时间 0.125 秒

#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 似乎只优化了其中一个循环。

当我禁用所有编译器优化并将我的交换代码内嵌在循环中时,我得到了以下结果(我还将我的计时器切换为 std::chrono::high_resolution_clock):

整数处理时间 1449 毫秒

double 处理时间 1248 毫秒

最佳答案

您可以通过查看生成的程序集找到答案。

使用 Visual C++ 2012(32 位发布版本)swap_i 的主体是三个 mov 指令,而 swap_d 的主体是完整的优化为一个空循环。编译器足够聪明,可以看出偶数次的交换没有明显的效果。我不知道为什么它不能对 int 循环做同样的事情。

只需将 #define N 2000000000 更改为 #define N 2000000001 并重建即可使 swap_d 主体执行实际工作。最后一次在我的机器上很接近,swap_d 慢了大约 3%。

关于c++ - 性能交换整数与 double ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12443760/

相关文章:

compiler-construction - 如何用编译器优化这个函数?

c++ - Clang ThreadSanitizer : unlock of an unlocked mutex,和一个原子正在创建数据争用

c++ - 自旋锁与 std::mutex::try_lock

c# - 为什么 Debug 构建中的 C# JIT 汇编代码中的每个方法中都有 cmp + je

c++ - 编译器围绕互斥锁边界重新排序?

assembly - 如果许多编程语言前端的编译器后端相同,那么不同语言的编译目标代码是否相同?

c++ - C++ 中的析构函数

c++ - 如果 Proactor 设计模式在异步 I/O 方面更胜一筹,为什么它在 ASIO 中不是默认的?

c++ - 函数开销会使程序减慢 50 倍吗?

c++ - 初始化对象时丢弃placement new返回值是否可以