Namensräume
Varianten
Aktionen

SIMD-Bibliothek

Von cppreference.com
 
 
 
 
 

Die SIMD-Bibliothek stellt portable Typen bereit, um explizit Datenparallelität anzugeben und Daten für einen effizienteren SIMD-Zugriff zu strukturieren.

Ein Objekt vom Typ simd<T> verhält sich analog zu Objekten vom Typ T. Während T einen einzelnen Wert speichert und manipuliert, speichert und manipuliert simd<T> mehrere Werte (genannt Breite, aber zur Konsistenz mit dem Rest der Standardbibliothek als size identifiziert; vgl. simd_size).

Jeder Operator und jede Operation auf simd<T> wirkt *elementweise* (außer bei *horizontalen* Operationen, die als solche klar gekennzeichnet sind). Diese einfache Regel drückt Datenparallelität aus und wird vom Compiler zur Generierung von SIMD-Instruktionen und/oder unabhängigen Ausführungsströmen verwendet.

Die Breite der Typen simd<T> und native_simd<T> wird zur Kompilierzeit von der Implementierung bestimmt. Im Gegensatz dazu wird die Breite des Typs fixed_size_simd<T, N> vom Entwickler auf eine bestimmte Größe festgelegt.

Ein empfohlene Vorgehensweise für die hocheffiziente Nutzung 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 alle Typen die gleiche Breite haben und somit umgewandelt werden können. Eine Konvertierung mit nicht übereinstimmender Breite ist nicht definiert, da sie entweder Werte verlieren oder erfinden müsste. Für Größenänderungsoperationen stellt die SIMD-Bibliothek die Funktionen split und concat bereit.

Definiert in Header <experimental/simd>

Inhalt

[edit] Hauptklassen

(Parallelismus TS v2)
Datenparalleler Vektortyp
(class template) [edit]
(Parallelismus TS v2)
Datenparalleler Typ mit dem Elementtyp bool
(class template) [edit]

[edit] ABI-Tags

Definiert im Namensraum std::experimental::simd_abi
(Parallelismus TS v2)
Tag-Typ für die Speicherung eines einzelnen Elements
(typedef) [edit]
(Parallelismus TS v2)
Tag-Typ für die Speicherung einer angegebenen Anzahl von Elementen
(Alias-Vorlage)[edit]
(Parallelismus TS v2)
Tag-Typ, der ABI-Kompatibilität gewährleistet
(Alias-Vorlage)[edit]
(Parallelismus TS v2)
Tag-Typ, der am effizientesten ist
(Alias-Vorlage)[edit]
(Parallelismus TS v2)
die maximale Anzahl von Elementen, die garantiert von Fixed unterstützt wird
(Konstante) [edit]
(Parallelismus TS v2)
ermittelt einen ABI-Typ für den gegebenen Elementtyp und die Anzahl der Elemente
(Klassen-Vorlage) [edit]

[edit] Alignment-Tags

Flag, das die Ausrichtung der Lade-/Speicheradresse auf Elementausrichtung anzeigt
(Klasse) [edit]
Flag, das die Ausrichtung der Lade-/Speicheradresse auf Vektor-Ausrichtung anzeigt
(Klasse) [edit]
(Parallelismus TS v2)
Flag, das die Ausrichtung der Lade-/Speicheradresse auf die angegebene Ausrichtung anzeigt
(Klassen-Vorlage) [edit]

[edit] Where-Ausdruck

(Parallelismus TS v2)
ausgewählte Elemente mit nicht-veränderlichen Operationen
(Klassentemplate)
(Parallelismus TS v2)
ausgewählte Elemente mit veränderlichen Operationen
(Klassentemplate)
(Parallelismus TS v2)
produziert const_where_expression und where_expression
(function template)

[edit] Casts

(Parallelismus TS v2)
elementweiser static_cast
(function template)
elementweiser ABI-Cast
(function template)
(Parallelismus TS v2)
teilt ein einzelnes simd-Objekt in mehrere auf
(function template)
(Parallelismus TS v2)
verkettet mehrere simd-Objekte zu einem einzigen
(function template)

[edit] Algorithmen

(Parallelismus TS v2)
elementweise Min-Operation
(function template)
(Parallelismus TS v2)
elementweise Max-Operation
(function template)
(Parallelismus TS v2)
elementweise MinMax-Operation
(function template)
(Parallelismus TS v2)
elementweise Clamp-Operation
(function template)

[edit] Reduktion

(Parallelismus TS v2)
reduziert den Vektor auf ein einzelnes Element
(function template)

[edit] Maskenreduktion

(Parallelismus TS v2)
Reduktionen von simd_mask zu bool
(Funktions-Vorlage) [edit]
(Parallelismus TS v2)
Reduktion von simd_mask auf die Anzahl der true Werte
(Funktions-Vorlage) [edit]
(Parallelismus TS v2)
Reduktionen von simd_mask auf den Index des ersten oder letzten true Wertes
(Funktions-Vorlage) [edit]

[edit] Traits

(Parallelismus TS v2)
prüft, ob ein Typ ein simd- oder simd_mask-Typ ist
(Klassen-Vorlage) [edit]
(Parallelismus TS v2)
prüft, ob ein Typ ein ABI-Tag-Typ ist
(Klassen-Vorlage) [edit]
(Parallelismus TS v2)
prüft, ob ein Typ ein SIMD-Flag-Typ ist
(Klassen-Vorlage) [edit]
(Parallelismus TS v2)
ermittelt die Anzahl der Elemente eines gegebenen Elementtyps und ABI-Tags
(Klassen-Vorlage) [edit]
(Parallelismus TS v2)
ermittelt eine geeignete Ausrichtung für vector_aligned
(Klassen-Vorlage) [edit]
(Parallelismus TS v2)
Ändert den Elementtyp oder die Anzahl der Elemente von simd oder simd_mask
(Klassen-Vorlage) [edit]

[edit] Mathematische Funktionen

Alle Funktionen in <cmath>, außer den speziellen mathematischen Funktionen, sind für simd überladen.

[edit] 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

[edit] Siehe auch

numerische Arrays, Array-Masken und Array-Slices
(Klassenvorlage) [edit]

[edit] Externe Links

1.  Die Implementierung von ISO/IEC TS 19570:2018 Abschnitt 9 "Data-Parallel Types" — github.com
2.  TS-Implementierungsreichweite für GCC/libstdc++ (std::experimental::simd wird mit GCC-11 ausgeliefert) — gcc.gnu.org