2012-03-15 13 views
6

Mientras que juega con el beta VS11 noté algo raro: este código COUTS¿Puede el compilador reordenar el código a través de llamadas a std :: chrono :: system_clock :: now()?

f tomó 0 milisegundos

int main() 
{ 
    std::vector<int> v; 
    size_t length =64*1024*1024; 
    for (int i = 0; i < length; i++) 
    { 
     v.push_back(rand()); 
    } 

    uint64_t sum=0; 
    auto t1 = std::chrono::system_clock::now(); 
    for (size_t i=0;i<v.size();++i) 
     sum+=v[i]; 
    //std::cout << sum << std::endl; 
    auto t2 = std::chrono::system_clock::now(); 
    std::cout << "f() took " 
     << std::chrono::duration_cast<std::chrono::milliseconds>(t2-t1).count() 
       << " milliseconds\n"; 


} 

Pero cuando decido elimine la línea con Couting de la suma entonces imprime un número razonable.

Este es el comportamiento llego con optimizaciones habilitadas, con ellos discapacitados consigo "normal" cout

f() se llevó a 471 milisegundos

Así es este comportamiento compatible con el estándar? Importante: no es que el código muerto se optimice, puedo ver el desfase cuando se ejecuta desde la consola, y puedo ver el pico de la CPU en el Administrador de tareas.

Respuesta

9

Mi conjetura es que esto es optimización de código muerto - y que su pico de carga se debe al trabajo de inicializar el vector no se está optimizando de distancia, pero el cálculo de la variable de sum sin usar es.

Pero cuando decido descomentar la línea con el couting de la suma, imprime un número razonable.

Esto concuerda con mi teoría, sí, cuando se ve obligado a utilizar el resultado del cálculo, el cálculo en sí no puede optimizarse.

Si desea confirmarlo más, haga que su programa diga cuándo está listo y haga una pausa para que presione la tecla Intro, lo que le permitirá esperar que cualquier pico de la CPU se "pase" obviamente antes de presionar volver, lo que hará darle más confianza sobre lo que lo está causando.

+0

Controlado, tienes razón, pero ahora estoy confundido, si es inteligente averiguar que no se usa esa suma ¿por qué está haciendo la inicialización? Supongo que no puede probar que rand() no tenga efectos secundarios ... – NoSenseEtAl

+0

ouch ... ofc no puede probar que rand no tenga efectos secundarios-rand no es una función pura ... tiene estado. :) pero incluso reemplazando rand() todavía no evito la inicialización ... – NoSenseEtAl

+0

@NoSenseEtAl: Bueno, la inicialización funciona usando 'push_back' ... así que supongo que a pesar de que el compilador puede decir que' v 'solo se usa más adelante en formas que puede descartarse, no es feliz asumir que' push_back() 'no tendrá otros efectos secundarios. Sin embargo, no me gustaría decirlo con seguridad. –

Cuestiones relacionadas