Stavo testando gli algoritmi e mi sono imbattuto in questo strano comportamento, quando std::accumulate
è più veloce di un semplice ciclo for
.Perché si accumula più velocemente di un semplice ciclo?
Guardando l'assemblatore generato non sono molto più saggio :-) Sembra che il ciclo for
sia ottimizzato in istruzioni MMX, mentre si accumula si espande in un ciclo.
Questo è il codice. Il comportamento si manifesta con -O3
livello di ottimizzazione, gcc 4.7.1
#include <vector>
#include <chrono>
#include <iostream>
#include <random>
#include <algorithm>
using namespace std;
int main()
{
const size_t vsize = 100*1000*1000;
vector<int> x;
x.reserve(vsize);
mt19937 rng;
rng.seed(chrono::system_clock::to_time_t(chrono::system_clock::now()));
uniform_int_distribution<uint32_t> dist(0,10);
for (size_t i = 0; i < vsize; i++)
{
x.push_back(dist(rng));
}
long long tmp = 0;
for (size_t i = 0; i < vsize; i++)
{
tmp += x[i];
}
cout << "dry run " << tmp << endl;
auto start = chrono::high_resolution_clock::now();
long long suma = accumulate(x.begin(),x.end(),0);
auto end = chrono::high_resolution_clock::now();
cout << "Accumulate runtime " << chrono::duration_cast<chrono::nanoseconds>(end-start).count() << " - " << suma << endl;
start = chrono::high_resolution_clock::now();
suma = 0;
for (size_t i = 0; i < vsize; i++)
{
suma += x[i];
}
end = chrono::high_resolution_clock::now();
cout << "Manual sum runtime " << chrono::duration_cast<chrono::nanoseconds>(end-start).count() << " - " << suma << endl;
return 0;
}
Per quanto mi piacerebbe provare a rispondere a questo. Non posso perché VS2010 non ha '' ... :( –
Mysticial
Questo è il motivo per cui tutti dicono di preferire gli algoritmi standard oltre a quelli propri. –
Per "ciclo" intendi "loop"? come ciclo del processore, ma se sostituisco "cycle" con "loop", la domanda ha molto più senso. – Mysticial