2012-09-16 10 views
7

Por alguna razón, mi código puede realizar intercambios en dobles más rápido que en los enteros. No tengo idea de por qué esto estaría sucediendo.Intercambios de rendimiento enteros contra dobles

En mi máquina, el bucle de intercambio doble completa 11 veces más rápido que el bucle de intercambio entero. ¿Qué propiedad de dobles/enteros los hace funcionar de esta manera?

configuración de prueba

  • Visual Studio 2012 x64
  • CPU Core i7 950
  • Construir como Release y ejecutar exe directamente, VS depuración engancha cosas sesgar

Salida:

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; 
} 

Parece que sólo se optimiza VS uno de los bucles como se explica de alto horno.

Cuando desactivar todas las optimizaciones del compilador y tengo mi código de canje en línea dentro de los bucles, que tiene los siguientes resultados (también cambié mi temporizador para std :: :: crono high_resolution_clock):

Process time for ints 1449 ms

Process time for doubles 1248 ms

+4

¿Cuál es la salida? Soy curioso. Además, ¿máquina de 32 bits o de 64 bits? ¿Código de 32 bits o de 64 bits? ¿Compilador? OS? – nneonneo

+3

¿Cuantos segundos estamos hablando para cada uno aquí? –

+1

¿Cuál * es * su máquina? Ejecuté su programa con algunas optimizaciones diferentes aquí, y no obtuve nada como lo que está viendo. Comportamiento de la caché tal vez? –

Respuesta

10

Puede encontrar la respuesta mirando el ensamblaje generado.

Usando Visual C++ 2012 (versión de versión de 32 bits) el cuerpo de swap_i es tres instrucciones pero el cuerpo de swap_d está completamente optimizado en un bucle vacío. El compilador es lo suficientemente inteligente como para ver que un número par de swaps no tiene ningún efecto visible. No sé por qué no hace lo mismo con el ciclo int.

Simplemente cambiando #define N 2000000000 a #define N 2000000001 y la reconstrucción hace que el cuerpo swap_d realice el trabajo real. Los últimos tiempos están cerca de mi máquina, con swap_d siendo aproximadamente un 3% más lento.

+0

¡esta es una muy buena respuesta! –

Cuestiones relacionadas