Das ist eine ziemlich theoretische Frage, aber ich bin sehr interessiert daran und würde mich freuen, wenn jemand etwas Expertenwissen dazu hat, das er oder sie bereit ist zu teilen.Wieso ist die Methode means() so viel schneller als sum()?
Ich habe eine Matrix von Schwimmern mit 2000 Zeilen und 600 Spalten und möchte den Mittelwert der Spalten aus jeder Zeile subtrahieren. Ich habe die folgenden zwei Linien getestet und deren Laufzeit im Vergleich:
MatrixXf centered = data.rowwise() - (data.colwise().sum()/data.cols());
MatrixXf centered = data.rowwise() - data.colwise().mean();
Ich dachte, mean()
würde durch die Anzahl der Zeilen etwas anderes aus der Division der Summe jeder Spalte nicht tun, aber während der Ausführung der ersten Zeile nimmt 12,3 Sekunden auf meinem Computer, die zweite Zeile endet in 0,09 Sekunden.
Ich verwende Eigen version 3.2.6
, die derzeit die neueste Version ist, und meine Matrizen werden in Zeile-Haupt-Reihenfolge gespeichert.
Weiß jemand etwas über die Interna von Eigen
, die diesen enormen Leistungsunterschied erklären könnten?
Edit: ich diese data
im Code hinzufügen soll über tatsächlich vom Typ Eigen::Map< Eigen::MatrixXf<Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> >
und Karten Eigens Funktionalität zu einem rohen Puffer.
Edit 2: Wie GuyGreer vorgeschlagen, werde ich einige Beispiel-Code zur Verfügung stellen, um meine Ergebnisse zu reproduzieren:
#include <iostream>
#include <chrono>
#include <Eigen/Core>
using namespace std;
using namespace std::chrono;
using namespace Eigen;
int main(int argc, char * argv[])
{
MatrixXf data(10000, 1000), centered;
data.setRandom();
auto start = high_resolution_clock::now();
if (argc > 1)
centered = data.rowwise() - data.colwise().mean();
else
centered = data.rowwise() - (data.colwise().sum()/data.rows());
auto stop = high_resolution_clock::now();
cout << duration_cast<milliseconds>(stop - start).count() << " ms" << endl;
return 0;
}
Compile mit:
g++ -O3 -std=c++11 -o test test.cc
das resultierende Programm Laufen ohne Argumente, so dass sum()
verwendet wird, dauert 126 Sekunden auf meinem Rechner, während test 1
mitläuftdauert nur 0,03 Sekunden!
bearbeiten 3: Wie es (siehe Kommentare) stellte sich heraus, ist es nicht sum()
, die so lange dauert, aber die Teilung des resultierenden Vektors durch die Anzahl der Zeilen. Die neue Frage lautet also: Warum benötigt Eigen mehr als 2 Minuten, um einen Vektor mit 1000 Spalten durch einen einzelnen Skalar zu teilen?
Führen Sie die beiden Berechnungen im gleichen Lauf nacheinander aus? Wenn dies der Fall ist, könnte es sich um ein Caching-Problem handeln. Tauschen Sie die Reihenfolge um. – toth
Nein, ich habe sie separat getestet. – Callidior
Ich habe noch nie Eigen verwendet und kann Ihnen daher nicht helfen, aber ich denke, es wäre hilfreich für Menschen, wenn Sie einen End-to-End-Test durchführen würden, der zeigt, wonach Sie fragen. Auf diese Weise können sich die Leute besser selbst überprüfen, was vor sich geht. – SirGuy