Ich habe Algorithmen getestet und in dieses seltsame Verhalten geraten, wenn std::accumulate
schneller ist als ein einfacher for
Zyklus.Warum akkumuliert sich schneller als ein einfacher Zyklus?
Blick auf den generierten Assembler Ich bin nicht viel klüger :-) Es scheint, dass der for
Zyklus in MMX-Anweisungen optimiert ist, während akkumuliert in eine Schleife erweitert.
Dies ist der Code. Das Verhalten manifestiert sich mit -O3
Optimierungsstufe, 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;
}
So gerne würde ich gerne versuchen, dies zu beantworten. Ich kann nicht, weil VS2010 nicht '' hat ... :( –
Mysticial
Das ist, warum jeder sagt, die Standardalgorithmen zu bevorzugen, die Ihre eigenen rollen. –
Durch "Zyklus" meinst du "Schleife"? Ich las das ist als Prozessor-Zyklus, aber wenn ich "Zyklus" durch "Schleife" ersetze, macht die Frage so viel mehr Sinn. – Mysticial