2016-01-01 1 views
1

j'ai écrit la référence suivante:résultats des benchmarks étranges

#include <iostream> // cout 
#include <math.h> // pow 
#include <chrono> // high_resolution_clock  

using namespace std; 
using namespace std::chrono; 

int64_t calculate(int); 

int main() 
{ 
    high_resolution_clock::time_point t1, t2; 

    // Test 1 
    t1 = high_resolution_clock::now(); 
    calculate(200); 
    t2 = high_resolution_clock::now(); 

    cout << "RUNTIME = " << duration_cast<nanoseconds>(t2 - t1).count() << " nano seconds" << endl; 

    // Test 2 
    t1 = high_resolution_clock::now(); 
    calculate(200000); 
    t2 = high_resolution_clock::now(); 

    cout << "RUNTIME = " << duration_cast<nanoseconds>(t2 - t1).count() << " nano seconds" << endl; 
} 

int64_t calculate(const int max_exponent) 
{ 
    int64_t num = 0; 

    for(int i = 0; i < max_exponent; i++) 
    { 
     num += pow(2, i); 
    } 

    return num; 
} 

Lors de l'exécution de cette référence sur le ODROID XU3 la sortie suivante est produite (8 courses):

RUNTIME TEST 1 = 1250 nano seconds 
RUNTIME TEST 2 = 1041 nano seconds 

RUNTIME TEST 1 = 1292 nano seconds 
RUNTIME TEST 2 = 1042 nano seconds 

RUNTIME TEST 1 = 1250 nano seconds 
RUNTIME TEST 2 = 1083 nano seconds 

RUNTIME TEST 1 = 1292 nano seconds 
RUNTIME TEST 2 = 1083 nano seconds 

RUNTIME TEST 1 = 1209 nano seconds 
RUNTIME TEST 2 = 1084 nano seconds 

RUNTIME TEST 1 = 1166 nano seconds 
RUNTIME TEST 2 = 1083 nano seconds 

RUNTIME TEST 1 = 1292 nano seconds 
RUNTIME TEST 2 = 1042 nano seconds 

RUNTIME TEST 1 = 1166 nano seconds 
RUNTIME TEST 2 = 1250 nano seconds 

RUNTIME TEST 1 = 1250 nano seconds 
RUNTIME TEST 2 = 1250 nano seconds 

Le second exposant est 1000 fois plus le premier. Pourquoi le deuxième appel finit-il parfois plus vite?

J'ai utilisé GCC (4.8) en tant que compilateur avec le drapeau -Ofast.

Mise à jour: Je pourrais reproduire un comportement similaire sur mon i7 4770k.

+0

Quelles sont les options du compilateur? –

+0

Et quelle version de gcc? –

+0

(Je devrais ajouter que je ne peux pas reproduire le résultat ci-dessus, mais mon gcc est 4.9.2 qui est un bon an. Clang génère des résultats plus rapides, mais la différence entre les deux appels et c'est la version de clang + llvm de juste avant Noël) –

Répondre

6

La réponse courte est "élimination du code mort". Le compilateur voit que vous n'utilisez jamais le résultat de l'appel de la fonction (et la fonction n'a pas d'effets secondaires), donc il élimine simplement l'appel de la fonction. Imprimez le résultat de la fonction et les choses changent un peu.

Par exemple:

Ignore: -9223372036854775808 RUNTIME = 0 nano seconds 
Ignore: -9223372036854775808 RUNTIME = 23001300 nano seconds 

Code modifié, au cas où vous soins:

#include <iostream> // cout 
#include <math.h> // pow 
#include <chrono> // high_resolution_clock  

using namespace std; 
using namespace std::chrono; 

int64_t calculate(int); 

int main() { 
    high_resolution_clock::time_point t1, t2; 

    // Test 1 
    t1 = high_resolution_clock::now(); 
    auto a = calculate(200); 
    t2 = high_resolution_clock::now(); 
    std::cout << "Ignore: " << a << "\t"; 

    cout << "RUNTIME = " << duration_cast<nanoseconds>(t2 - t1).count() << " nano seconds" << endl; 

    // Test 2 
    t1 = high_resolution_clock::now(); 
    auto b = calculate(200000); 
    t2 = high_resolution_clock::now(); 
    std::cout << "Ignore: " << b << "\t"; 

    cout << "RUNTIME = " << duration_cast<nanoseconds>(t2 - t1).count() << " nano seconds" << endl; 
} 

int64_t calculate(const int max_exponent) { 
    int64_t num = 0; 

    for (int i = 0; i < max_exponent; i++) { 
     num += pow(2, i); 
    } 

    return num; 
} 

De là, vous avez le petit détail que vous déborde la portée d'un int64_t (plusieurs fois) donnant behavior- non définie -mais au moins avec cela il y a un espoir raisonnable que les temps imprimés reflètent le temps nécessaire pour effectuer les calculs spécifiés.

-2

Cela arrive probablement avec l'aide du cache de votre CPU Ou, très probablement, c'est l'optimisation d'un compilateur. Essayez de désactiver l'optimisation avec -O0 et comparez les résultats. Je l'ai répété sur ma machine avec et sans "-O0" et j'ai obtenu un résultat vraiment différent.

+0

Ceci est plus d'un commentaire qu'une réponse. –

+0

@WaiHaLee: D'accord, même si l'utilisateur n'a pas assez de rep pour laisser un commentaire. – Cornstalks