Производительность поменять местами целые и двойные

По какой-то причине мой код может выполнять перестановки на двойные числа быстрее, чем на целые числа. Я понятия не имею, почему это будет происходить.

На моей машине цикл двойного обмена завершается в 11 раз быстрее, чем цикл целочисленного обмена. Какое свойство двойных / целых чисел заставляет их работать таким образом?

Испытательная установка

  • Visual Studio 2012 x64
  • процессор Core i7 950
  • Build as 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;
}

Кажется, что VS только оптимизировал один из циклов, как объяснил Blastfurnace.

Когда я отключаю все оптимизации компилятора и вставляю свой код подкачки в циклы, я получаю следующие результаты (я также переключил свой таймер на std :: chrono :: high_resolution_clock):

Process time for ints 1449 ms

Process time for doubles 1248 ms

7

Решение

Вы можете найти ответ, посмотрев на сгенерированную сборку.

Используя Visual C ++ 2012 (32-разрядная сборка выпуска), тело swap_i это три mov инструкции, но тело swap_d полностью оптимизирован под пустой цикл. Компилятор достаточно умен, чтобы видеть, что четное количество перестановок не имеет видимого эффекта. Я не знаю, почему это не делает то же самое с int петля.

Просто меняется #define N 2000000000 в #define N 2000000001 и восстановление вызывает swap_d орган для выполнения реальной работы. Последние времена близки на моей машине с swap_d быть примерно на 3% медленнее.

10

Другие решения

Других решений пока нет …