2013-10-02 16 views
6

Sto per rendere il mio codice più generalizzato utilizzando std::tuple in molti casi incluso un singolo elemento. Intendo ad esempio tuple<double> anziché double. Ma ho deciso di verificare le prestazioni di questo caso particolare.Prestazioni della tupla C++ 11

Ecco semplice test benchmark delle prestazioni:

#include <tuple> 
#include <iostream> 

using std::cout; 
using std::endl; 
using std::get; 
using std::tuple; 

int main(void) 
{ 

#ifdef TUPLE 
    using double_t = std::tuple<double>; 
#else 
    using double_t = double; 
#endif 

    constexpr int count = 1e9; 
    auto array = new double_t[count]; 

    long long sum = 0; 
    for (int idx = 0; idx < count; ++idx) { 
#ifdef TUPLE 
     sum += get<0>(array[idx]); 
#else 
     sum += array[idx]; 
#endif 
    } 
    delete[] array; 
    cout << sum << endl; // just "external" side effect for variable sum. 
} 

ed eseguire risultati:

$ g++ -DTUPLE -O2 -std=c++11 test.cpp && time ./a.out 
0 

real 0m3.347s 
user 0m2.839s 
sys  0m0.485s 

$ g++ -O2 -std=c++11 test.cpp && time ./a.out 
0 

real 0m2.963s 
user 0m2.424s 
sys  0m0.519s 

Ho pensato che tupla è modello statico-compilato rigorosa e tutti ottenere <> funzioni stanno lavorando solo al solito accesso variabile in quel caso. Le dimensioni dell'allocazione di memoria BTW in questo test sono le stesse. Perché si verifica questa differenza di orario di esecuzione?

MODIFICA: problema nell'inizializzazione della tupla <> oggetto. Per rendere test più accurato di una riga deve essere cambiato:

 constexpr int count = 1e9; 
- auto array = new double_t[count]; 
+ auto array = new double_t[count](); 

    long long sum = 0; 

Dopo di che si può osservare risultati simili:

$ g++ -DTUPLE -g -O2 -std=c++11 test.cpp && (for i in $(seq 3); do time ./a.out; done) 2>&1 | grep real 
real 0m3.342s 
real 0m3.339s 
real 0m3.343s 

$ g++ -g -O2 -std=c++11 test.cpp && (for i in $(seq 3); do time ./a.out; done) 2>&1 | grep real 
real 0m3.349s 
real 0m3.339s 
real 0m3.334s 
+3

Avete controllato l'uscita dell'assieme? – balki

+1

L'hai eseguito molte volte per assicurarti di ottenere risultati coerenti? –

+0

Quanto velocemente il tuo computer impiega così tanto tempo per essere eseguito sul mio – aaronman

risposta

11

La tupla tutti i valori di default Construct (quindi tutto è 0) doppie non si ottiene di default inizializzato.

Nell'assemblaggio generato, il seguente ciclo di inizializzazione è presente solo quando si utilizzano le tuple. Altrimenti sono equivalenti.

.L2: 
    movq $0, (%rdx) 
    addq $8, %rdx 
    cmpq %rcx, %rdx 
    jne .L2 
+0

Confermato in assemblea. Fa due cicli, un azzeramento e una somma. 'double' based ne fa uno solo. – zch

+0

@zch se vuoi puoi modificare la mia risposta, non proprio in un'audizione di lettura assemblea – aaronman

+6

Ottima osservazione. L'OP dovrebbe scrivere 'new double_t [count]();' per un confronto equo. –