2016-05-22 16 views
0

Ich möchte sicherstellen, dass SSE für Arithmetik auf meinen 3D (96 Bit) Float-Vektoren verwendet wird. Ich habe jedoch widersprüchliche Ansichten darüber gelesen, was notwendig ist.SSE-Ausrichtung des 3D-Vektors

Einige Artikel/Beiträge sagen, ich brauche einen 4D Vektor und "Ignoriere" das vierte Element, einige sagen, ich muss meine Klasse mit Dingen wie __declspec(align(16)) dekorieren und überschreiben den new Operator, und einige sagen, der Compiler ist schlau genug richten Sie die Dinge für mich aus (ich hoffe wirklich, dass das wahr ist!).

ich die Bibliothek Eigen verwende, aber feststellen, dass die „unsupported“ AlignedVector3 Klasse nicht für den Zweck geeignet ist (beispielsweise eine Division durch Null Fehler bei der komponentenweisen Teilung zu tun, enthält lpNorm Funktion die Dummy vierte Element).

Viele der Artikel, die ich gelesen habe, sind jetzt einige Jahre alt, also hoffe ich, dass moderne Compiler/SSE-Versionen/CPUs nur die Daten für mich ausrichten oder mit nicht 16 Byte ausgerichteten Daten arbeiten können. Jedes aktuelle Wissen darüber wird sehr geschätzt!

+3

CPUs können nicht einfach losgehen und anfangen, die Dinge selbst zu justieren, sie tun nur, was der Code ihnen sagt.Wenn möglich, stoppe diese Idee und benutze stattdessen SIMD über die separaten Koordinaten, so dass du die 4. Spur nicht verschwenden musst (und im Allgemeinen funktioniert fast alles besser so, SIMD-Vektoren sind nicht als Linalg-Vektoren gedacht) – harold

+0

Danke für den Kommentar (verstehe nicht, warum diese Frage abgelehnt wurde ...). Wie auch immer, ich bin nicht sicher, was Sie mit "SIMD über die einzelnen Koordinaten zu verwenden" meinen - meinst du Bulk Verarbeitung mehrerer 3D-Vektoren (das wäre auch cool, wenn es möglich ist)? Ich habe gerade auch den C++ 11 'alignas (16)' Decorator entdeckt. Ich habe es hinzugefügt, um meine generisch-dimensionale Vektorklasse zu umbrechen, und es hat keinen Absturz verursacht - aber natürlich wird kein Proof-SIMD verwendet. – Dave

+0

Ja, Massenverarbeitung, vielleicht 3 Zeiger (x, y, z) in einen Block mit _aligned_malloc. Sie können bei Bedarf auch unausgerichtet laden/speichern. Dieser ganze deklarative Alignment-Deal funktioniert nicht wirklich gut in C++ - Sachen, zum Beispiel, wenn Sie diesen Typ in einen Container setzen, wird er immernoch brechen, wenn Sie nicht einen benutzerdefinierten Allocator verwenden. – harold

Antwort

1

Eigentlich benutzen wir SIMD bei der Arbeit und vielleicht kann ich Ihnen mein Feedback geben. Das Alignement ist etwas, um das Sie sich im Umgang mit SIMD kümmern müssen, um die Ausrichtung der Cache-Zeilen zu gewährleisten. Allerdings bin ich nicht sicher, ob es immer noch einen Absturz verursachen wird, wenn es nicht ausgerichtet ist oder wenn die CPU in der Lage ist, trotzdem zu verwalten (wie nicht ausgerichtete skalare Typen in der alten Zeit, es verursachte Absturz, jetzt wird die CPU es verarbeiten, aber es verlangsamt Down-Performances). Vielleicht können Sie hier SSE, intrinsics, and alignment Es scheint, gute Antworten für den Alignment Teil der Frage zu haben.

Für die Tatsache, dass Sie es als 3D-Vektor verwenden, auch wenn es physisch ein 4D-Vektor ist, ist es keine wirklich gute Übung, weil Sie nicht die ganze Leistung von SIMD-Anweisungen profitieren. Der beste Weg für die Übereinstimmung ist die Verwendung von Struktur von Arrays (SOA).

Anmerkung: Ich gehe davon aus 128 Bit-SIMD-Register zugeordnet 4 skalare Typen (int oder float)

Zum Beispiel, wenn Sie 4 3D-Punkte (oder Vektoren), nach dem Weg, haben Sie 4 4D Vektoren ignorieren die 4. Komponente jedes Punktes. Insgesamt stehen Ihnen 4 * 4 Werte zur Verfügung.

Mit SOA haben Sie 3 SIMD 128 Bits (12 Werte) Register und Sie werden Ihre Punkte auf folgende Weise speichern. SIMD

  • r1: x x x x
  • r2: y y y y
  • r3: z z z z

Auf diese Weise kann das gesamte SIMD-Register und somit Gewinn bei maximal SIMD Vorteilen füllen. Die andere Sache ist, dass viele der Berechnungen, die Sie machen müssen (Beispiel fügen Sie 2 Gruppen von 4 Vektoren hinzu), nur 3 SIMD-Anweisungen. Es ist ein bisschen schwierig zu verwenden und zu verstehen, aber wenn Sie das tun, ist der Gewinn groß.

Natürlich können Sie es nicht in allen Fällen so verwenden, so dass Sie auf die ursprüngliche Lösung des Ignorierens des letzten Wertes zurückgreifen.

+1

16 ** Bytes **. Unaligned kann abstürzen, wenn Sie '_mm_load_ps' verwenden (sogar mit AVX anstelle von SSE), aber nicht, wenn Sie' _mm_loadu_ps' verwenden. –

+0

Scalar unaligned hat noch nie auf x86 Fehler gemacht. Vielleicht erinnern Sie sich daran, in der Vergangenheit mit einer anderen Architektur gearbeitet zu haben. Ich erinnere mich, dass ich meinen Code-Fehler auf den Solaris-Boxen mit SPARC-CPUs in der Schule hatte. –

+1

Ja, noch besser ein AoSoA. Siehe http://compilers.cs.uni-saarland.de/papers/leissa_vecimp_tr.pdf –