SIMD library
Die SIMD-Bibliothek bietet portable Typen, um Datenparallelismus explizit anzugeben und Daten für effizienteren SIMD-Zugriff zu strukturieren.
Ein Objekt vom Typ
simd<T>
verhält sich analog zu Objekten vom Typ
T
. Während jedoch
T
einen Wert speichert und manipuliert, speichert und manipuliert
simd<T>
mehrere Werte (genannt
width
, aber aus Konsistenzgründen zur restlichen Standardbibliothek als
size
bezeichnet; vergleiche
simd_size
).
Jeder Operator und jede Operation auf
simd<T>
wirkt
elementweise
(außer bei
horizontalen
Operationen, die ausdrücklich als solche gekennzeichnet sind). Diese einfache Regel drückt Datenparallelität aus und wird vom Compiler genutzt, um SIMD-Befehle und/oder unabhängige Ausführungsströme zu generieren.
Die Breite der Typen
simd<T>
und
native_simd<T>
wird zur Compilezeit durch die Implementierung bestimmt. Im Gegensatz dazu ist die Breite des Typs
fixed_size_simd<T, N>
durch den Entwickler auf eine bestimmte Größe festgelegt.
Ein empfohlenes Muster für die effiziente Verwendung einer Mischung verschiedener SIMD-Typen verwendet native_simd und rebind_simd :
#include <experimental/simd> namespace stdx = std::experimental; using floatv = stdx::native_simd<float>; using doublev = stdx::rebind_simd_t<double, floatv>; using intv = stdx::rebind_simd_t<int, floatv>;
Dies stellt sicher, dass die Menge der Typen alle die gleiche Breite haben und somit miteinander konvertiert werden können. Eine Konvertierung mit nicht übereinstimmender Breite ist nicht definiert, da sie entweder Werte verwerfen oder Werte erfinden müsste. Für Größenänderungsoperationen bietet die SIMD-Bibliothek die split und concat Funktionen.
|
Definiert im Header
<experimental/simd>
|
Inhaltsverzeichnis |
Hauptklassen
|
(parallelism TS v2)
|
Datenparalleler Vektortyp
(Klassentemplate) |
|
(parallelism TS v2)
|
Datenparalleler Typ mit dem Elementtyp bool
(Klassentemplate) |
ABI-Tags
|
Definiert im Namespace
std::experimental::simd_abi
|
|
|
(parallelism TS v2)
|
Tag-Typ zur Speicherung eines einzelnen Elements
(Typdefinition) |
|
(parallelism TS v2)
|
Tag-Typ zur Speicherung einer festgelegten Anzahl von Elementen
(Alias-Template) |
|
(parallelism TS v2)
|
Tag-Typ, der ABI-Kompatibilität sicherstellt
(Alias-Template) |
|
(parallelism TS v2)
|
Tag-Typ mit maximaler Effizienz
(Alias-Template) |
|
(parallelism TS v2)
|
Die maximale Anzahl von Elementen, die garantiert von fixed unterstützt wird
(Konstante) |
|
(parallelism TS v2)
|
Ermittelt einen ABI-Typ für einen gegebenen Elementtyp und eine Anzahl von Elementen
(Klassen-Template) |
Ausrichtungstags
|
(parallelism TS v2)
|
Flagge, die die Ausrichtung der Lade-/Speicheradresse auf Elementausrichtung angibt
(Klasse) |
|
(parallelism TS v2)
|
Flagge, die die Ausrichtung der Lade-/Speicheradresse auf Vektorausrichtung angibt
(Klasse) |
|
(parallelism TS v2)
|
Flagge, die die Ausrichtung der Lade-/Speicheradresse auf die spezifizierte Ausrichtung angibt
(Klassentemplate) |
Where-Ausdruck
|
(parallelism TS v2)
|
Ausgewählte Elemente mit nicht-mutierenden Operationen
(Klassen-Template) |
|
(parallelism TS v2)
|
Ausgewählte Elemente mit mutierenden Operationen
(Klassen-Template) |
|
(parallelism TS v2)
|
Erzeugt const_where_expression und where_expression
(Funktions-Template) |
Casts
|
(parallelism TS v2)
|
elementenweises static_cast
(Funktions-Template) |
|
(parallelism TS v2)
|
elementenweises ABI-Cast
(Funktions-Template) |
|
(parallelism TS v2)
|
teilt ein einzelnes simd-Objekt in mehrere auf
(Funktions-Template) |
|
(parallelism TS v2)
|
verkettet mehrere simd-Objekte zu einem einzelnen
(Funktions-Template) |
Algorithmen
|
(parallelism TS v2)
|
elementweise Min-Operation
(Funktions-Template) |
|
(parallelism TS v2)
|
elementweise Max-Operation
(Funktions-Template) |
|
(parallelism TS v2)
|
elementweise MinMax-Operation
(Funktions-Template) |
|
(parallelism TS v2)
|
elementweise Clamp-Operation
(Funktions-Template) |
Reduktion
|
(parallelism TS v2)
|
reduziert den Vektor auf ein einzelnes Element
(Funktions-Template) |
Maskenreduzierung
|
(parallelism TS v2)
|
Reduktionen von
simd_mask
zu
bool
(Funktions-Template) |
|
(parallelism TS v2)
|
Reduktion von
simd_mask
auf die Anzahl der
true
Werte
(Funktions-Template) |
|
(parallelism TS v2)
|
Reduktionen von
simd_mask
auf den Index des ersten oder letzten
true
Wertes
(Funktions-Template) |
Traits
|
(parallelism TS v2)
|
prüft, ob ein Typ ein
simd
oder
simd_mask
Typ ist
(Klassentemplate) |
|
(parallelism TS v2)
|
prüft, ob ein Typ ein ABI-Tag-Typ ist
(Klassentemplate) |
|
(parallelism TS v2)
|
prüft, ob ein Typ ein simd-Flag-Typ ist
(Klassentemplate) |
|
(parallelism TS v2)
|
ermittelt die Anzahl der Elemente eines gegebenen Elementtyps und ABI-Tags
(Klassentemplate) |
|
(parallelism TS v2)
|
ermittelt eine geeignete Ausrichtung für
vector_aligned
(Klassentemplate) |
|
(parallelism TS v2)
|
ändert den Elementtyp oder die Anzahl der Elemente von
simd
oder
simd_mask
(Klassentemplate) |
Mathematische Funktionen
Alle Funktionen in
<cmath>
, außer den speziellen mathematischen Funktionen, sind für
simd
überladen.
Beispiel
#include <experimental/simd> #include <iostream> #include <string_view> namespace stdx = std::experimental; void println(std::string_view name, auto const& a) { std::cout << name << ": "; for (std::size_t i{}; i != std::size(a); ++i) std::cout << a[i] << ' '; std::cout << '\n'; } template<class A> stdx::simd<int, A> my_abs(stdx::simd<int, A> x) { where(x < 0, x) = -x; return x; } int main() { const stdx::native_simd<int> a = 1; println("a", a); const stdx::native_simd<int> b([](int i) { return i - 2; }); println("b", b); const auto c = a + b; println("c", c); const auto d = my_abs(c); println("d", d); const auto e = d * d; println("e", e); const auto inner_product = stdx::reduce(e); std::cout << "inner product: " << inner_product << '\n'; const stdx::fixed_size_simd<long double, 16> x([](int i) { return i; }); println("x", x); println("cos²(x) + sin²(x)", stdx::pow(stdx::cos(x), 2) + stdx::pow(stdx::sin(x), 2)); }
Ausgabe:
a: 1 1 1 1 b: -2 -1 0 1 c: -1 0 1 2 d: 1 0 1 2 e: 1 0 1 4 inner product: 6 x: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 cos²(x) + sin²(x): 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Siehe auch
|
Numerische Arrays, Array-Masken und Array-Slices
(Klassen-Template) |
Externe Links
| 1. | Die Implementierung von ISO/IEC TS 19570:2018 Abschnitt 9 "Data-Parallel Types" — github.com |
| 2. |
TS-Implementierung erreichbar für
GCC/libstdc++
(
std::experimental::simd
wird mit GCC-11 ausgeliefert) — gcc.gnu.org
|