AoS und SoA - AoS and SoA

In der Berechnung , Array von Strukturen (AOS) , Structure of Arrays (SOA) und Array von Strukturen von Arrays (AoSoA) beziehen Wege zu kontras eine Folge von arrangieren Datensätze in Speicher , in Bezug auf die Verschachtelung und sind von Interesse in SIMD und SIMT- Programmierung.

Struktur von Arrays

Struktur von Arrays ( SoA ) ist ein Layout, das Elemente eines Datensatzes (oder 'struct' in der Programmiersprache C ) in ein paralleles Array pro Feld aufteilt . Die Motivation ist die einfachere Manipulation mit gepackten SIMD-Befehlen in den meisten Befehlssatzarchitekturen , da ein einzelnes SIMD-Register homogene Daten laden kann , die möglicherweise über einen breiten internen Datenpfad (zB 128-Bit ) übertragen werden. Wenn nur ein bestimmter Teil des Datensatzes benötigt wird, müssen nur diese Teile wiederholt werden, sodass mehr Daten auf eine einzelne Cache-Zeile passen. Der Nachteil besteht darin, dass beim Durchlaufen von Daten mehr Cache-Wege erforderlich sind und ineffiziente indizierte Adressierung .

So speichern Sie beispielsweise N Punkte im 3D-Raum mithilfe einer Struktur von Arrays:

struct pointlist3D {
    float x[N];
    float y[N];
    float z[N];
};
struct pointlist3D points;
float get_point_x(int i) { return points.x[i]; }

Array von Strukturen

Array of Structures ( AoS ) ist das entgegengesetzte (und konventionellere) Layout, bei dem Daten für verschiedene Felder verschachtelt sind. Dies ist oft intuitiver und wird von den meisten Programmiersprachen direkt unterstützt .

So speichern Sie beispielsweise N Punkte im 3D-Raum mithilfe eines Arrays von Strukturen:

struct point3D {
    float x;
    float y;
    float z;
};
struct point3D points[N];
float get_point_x(int i) { return points[i].x; }

Array von Strukturen von Arrays

Array of Structures of Arrays ( AoSoA ) oder Tiled Array of Structs ist ein Hybridansatz zwischen den vorherigen Layouts, bei dem Daten für verschiedene Felder unter Verwendung von Kacheln oder Blöcken mit einer Größe gleich der SIMD-Vektorgröße verschachtelt werden. Dies ist oft weniger intuitiv, kann aber den Speicherdurchsatz des SoA-Ansatzes erreichen und ist gleichzeitig freundlicher für die Cache-Lokalität und die Load-Port-Architekturen moderner Prozessoren.

Um beispielsweise N Punkte im 3D-Raum unter Verwendung eines Arrays von Strukturen von Arrays mit einer SIMD-Registerbreite von 8 Gleitkommazahlen (oder 8×32 = 256 Bits) zu speichern:

struct point3Dx8 {
    float x[8];
    float y[8];
    float z[8];
};
struct point3Dx8 points[(N+7)/8];
float get_point_x(int i) { return points[i/8].x[i%8]; }

Abhängig von der tatsächlichen SIMD-Registerbreite kann eine andere Breite erforderlich sein. Die inneren Arrays können durch SIMD-Typen ersetzt werden, beispielsweise float32x8für Sprachen mit einer solchen Unterstützung.

Alternativen

Es ist möglich, eine Teilmenge einer Struktur (anstatt jedes einzelne Feld) in ein paralleles Array aufzuteilen  – und dies kann die Referenzlokalität sogar verbessern, wenn verschiedene Teile von Feldern zu verschiedenen Zeiten im Programm verwendet werden (siehe Datenorientiertes Design ).

Einige SIMD- Architekturen stellen gestaffelte Lade-/Speicheranweisungen bereit , um homogene Daten aus dem SoA-Format zu laden. Eine weitere Option, die in einigen Cell- Bibliotheken verwendet wird, besteht darin, Daten aus dem AoS-Format beim Laden von Quellen in Register zu entschachteln und beim Schreiben von Ergebnissen zu verschachteln (erleichtert durch das superskalare Problem von Permuten ). Einige Bibliotheken für Vektormathematik richten 4D- Gleitkommavektoren mit dem SIMD-Register aus, um den zugehörigen Datenpfad und die zugehörigen Anweisungen zu nutzen, während sie dennoch Programmierkomfort bieten, obwohl dies nicht auf SIMD-Einheiten mit mehr als vier Spuren skaliert werden kann.

4D-Vektoren

AoS vs. SoA stellt eine Wahl dar, wenn man 3D- oder 4D-Vektordaten auf Maschinen mit vierspuriger SIMD-Hardware in Betracht zieht. SIMD-ISAs sind normalerweise für homogene Daten ausgelegt, einige bieten jedoch eine Punktproduktanweisung und zusätzliche Permuten, wodurch der AoS-Fall einfacher zu handhaben ist.

Obwohl sich die meisten GPU- Hardware von 4D-Anweisungen zu skalaren SIMT- Pipelines bewegt hat , können moderne Rechenkerne , die SoA anstelle von AoS verwenden, aufgrund der Speicherzusammenführung immer noch eine bessere Leistung bieten.

Software-Unterstützung

Die meisten Sprachen unterstützen das AoS-Format natürlicher, indem sie Datensätze und verschiedene abstrakte Array- Datentypen kombinieren .

SoA findet man meist in Sprachen, Bibliotheken oder Metaprogrammierungswerkzeugen , die zur Unterstützung eines datenorientierten Designs verwendet werden . Beispiele beinhalten:

  • Die SIMD-orientierten Funktionen der experimentellen Programmiersprache Jai sind ein neuer Versuch, SoA-Unterstützung auf Sprachebene bereitzustellen.
  • Der „Datenrahmen“ von R und Python NumPy und Pandas, Julia ‚s StructsOfArrays.jlsind Beispiele von Schnittstellen für den Zugriff SoA wie AOS;
  • Codegeneratoren für die Sprache C, einschließlich Datadraw und der X-Makro- Technik.

Die automatisierte Erstellung von AoSoA ist komplexer. Ein Beispiel für AoSoA in der Metaprogrammierung findet sich in der in C++ geschriebenen Cabana-Bibliothek von LANL ; es nimmt standardmäßig eine Vektorbreite von 16 Spuren an.

Verweise