Wie viel Aufwand müssen Sie setzen, um Gewinne zu erhalten von SSE mit?
Frage
Case One
Angenommen, Sie haben eine wenig Klasse:
class Point3D
{
private:
float x,y,z;
public:
operator+=()
...etc
};
Point3D &Point3D::operator+=(Point3D &other)
{
this->x += other.x;
this->y += other.y;
this->z += other.z;
}
Eine naive Verwendung von SSE würde einfach diese Funktion Körper ersetzen mit ein paar intrinsics verwenden. Aber würden wir erwarten, dass diese viel Unterschied machen? MMX verwendet IIRC teuer Zustand cahnges einzubeziehen, tut SSE oder sind sie genau wie andere Anweisungen? Und selbst wenn es keine direkte Overhead „SSE verwenden“, würden die Werte in SSE-Register zu bewegen und wieder wirklich schneller machen wieder heraus?
Case Zwei
Stattdessen Sie arbeiten mit einer weniger OO-basierten Code-Basis. Anstatt ein Array / Vektor von Point3D Objekte, müssen Sie einfach eine große Reihe von Schwimmern:
float coordinateData[NUM_POINTS*3];
void add(int i,int j) //yes it's unsafe, no overlap check... example only
{
for (int x=0;x<3;++x)
{
coordinateData[i*3+x] += coordinateData[j*3+x];
}
}
Was ist die Verwendung von SSE hier? Besser?
Abschließend
Wird versucht, einzelne Vektoroperationen zu optimieren tatsächlich lohnenswert mit SSE, oder ist es wirklich nur wertvoll, wenn Bulk-Operationen zu tun?
Lösung
In der Regel müssen Sie zusätzliche Schritte ergreifen, um das Beste aus SSE (oder jeder anderen SIMD-Architektur) zu erhalten:
-
Datenbedarf 16 Byte ausgerichtet werden (im Idealfall)
-
Daten müssen zusammenhängend sein
-
Sie müssen genügend Daten, um die SIMD-Operation lohnt
machen
-
müssen Sie coalesce so viele Operationen wie Sie können die Kosten von Lasten / Shops
mildern
-
Sie müssen sich der Cache / Speicherhierarchie und seine Auswirkungen auf die Leistung (z Verwendung Tagebau / Fliesen)
sein
Andere Tipps
Es ist wertvoll, wenn Ihr heißt Fall ist, dass Sie eine Menge gleichen Berechnungen auf Datenbereich tun. zum Beispiel berechnen Sie Quadratwurzeln viel viele Gleichungen. Sie können einmal vier Werte in sse Register und Call-Operationen laden. Dadurch wird die Leistung erhöhen, indem 4.
und es gibt Bibliotheken, die alle sse Optimierung in sich haben. nicht neu zu erfinden Fahrrad.
Diese Gamasutra Artikel zeigt, was es nimmt schnell machen SSE -basierte Code. Es deckt Ihr "Fall 1" im Detail.
Der Quellcode ist von den Autoren Homepage .
habe ich versuchte Fall eines bei der Arbeit ein paar Jahre und der Performance-Gewinn war kaum messbar. Am Ende entschied ich es, da alle mit Ausrichtung aller Point3D
auf 16-Byte-Grenzen den Aufwand zu überspringen war es nicht der Mühe wert.
Wie Sie haben richtig geraten SSE am ehesten gerecht wird Bulk-Operationen, bei denen sie eine ziemlich gute Geschwindigkeit bis geben. Bevor Sie gehen Sie vor und nutzen die Check-Spezifika SSE, welchen Code der Compiler bereits generiert. Ich weiß aus Erfahrung, dass zum Beispiel Visual Studio bei Verwendung von SSE-Optimierungen ziemlich gut.