Vc befindet sich jetzt im Wartungsmodus und wird nicht mehr aktiv weiterentwickelt. Wir prüfen jedoch weiterhin Pull-Requests mit Bugfixes aus der Community.
Möglicherweise möchten Sie zu std-simd wechseln. GCC 11 enthält eine experimentelle Version von std::simd
als Teil von libstdc++, die auch mit clang funktioniert. Funktionen, die in Vc 1.4 vorhanden sind, aber nicht in std-simd vorhanden sind, werden schließlich in Vc 2.0 umgewandelt, was dann von std-simd abhängt.
Neuere Generationen von CPUs und insbesondere GPUs erfordern für volle Effizienz datenparallele Codes. Datenparallelität erfordert, dass die gleiche Abfolge von Operationen auf verschiedene Eingabedaten angewendet wird. CPUs und GPUs können so die notwendige Hardware für die Befehlsdekodierung und -planung zugunsten von mehr Rechen- und Logikeinheiten reduzieren, die dieselben Befehle synchron ausführen. Auf CPU-Architekturen wird dies über SIMD-Register und -Anweisungen implementiert. Ein einzelnes SIMD-Register kann N Werte speichern und ein einzelner SIMD-Befehl kann N Operationen für diese Werte ausführen. Auf GPU-Architekturen laufen N Threads perfekt synchron und werden von einem einzigen Befehlsdecoder/Scheduler gespeist. Jeder Thread verfügt über lokalen Speicher und einen bestimmten Index, um die Offsets im Speicher für Lade- und Speichervorgänge zu berechnen.
Aktuelle C++-Compiler können Skalarcodes automatisch in SIMD-Anweisungen umwandeln (Auto-Vektorisierung). Allerdings muss der Compiler eine intrinsische Eigenschaft des Algorithmus wiederherstellen, die verloren ging, als der Entwickler eine rein skalare Implementierung in C++ schrieb. Folglich können C++-Compiler keinen bestimmten Code in seine effizienteste datenparallele Variante vektorisieren. Insbesondere größere datenparallele Schleifen, die sich über mehrere Funktionen oder sogar Übersetzungseinheiten erstrecken, werden oft nicht in effizienten SIMD-Code umgewandelt.
Die Vc-Bibliothek stellt den fehlenden Link bereit. Seine Typen ermöglichen die explizite Angabe datenparalleler Operationen für mehrere Werte. Die Parallelität wird also über das Typsystem hinzugefügt. Konkurrierende Ansätze begründen die Parallelität durch neue Kontrollstrukturen und damit eine neue Semantik innerhalb des Körpers dieser Kontrollstrukturen.
Vc ist eine kostenlose Softwarebibliothek zur Erleichterung der expliziten Vektorisierung von C++-Code. Es verfügt über eine intuitive API und bietet Portabilität zwischen verschiedenen Compilern und Compilerversionen sowie Portabilität zwischen verschiedenen Vektorbefehlssätzen. Somit kann eine mit Vc geschriebene Anwendung kompiliert werden für:
Nachdem Intel die MIC-Unterstützung mit ICC 18 eingestellt hatte, entfernte Vc 1.4 auch die Unterstützung dafür.
std::vector<Particle>
simdize
d-Iteration über viele std::vector<float>
zeigt. Beachten Sie, wie wichtig das Flag -march
im Vergleich zum einfachen Flag -mavx2 -mfma
ist.Beginnen wir mit dem Code zur Berechnung eines 3D-Skalarprodukts mithilfe integrierter Gleitkommazahlen:
using Vec3D = std::array< float , 3 >;
float scalar_product (Vec3D a, Vec3D b) {
return a[ 0 ] * b[ 0 ] + a[ 1 ] * b[ 1 ] + a[ 2 ] * b[ 2 ];
}
Mit Vc können wir den Code einfach mit dem Typ float_v
vektorisieren:
using Vc::float_v
using Vec3D = std::array<float_v, 3 >;
float_v scalar_product (Vec3D a, Vec3D b) {
return a[ 0 ] * b[ 0 ] + a[ 1 ] * b[ 1 ] + a[ 2 ] * b[ 2 ];
}
Das Obige wird je nach den Fähigkeiten der Zielhardware auf 1, 4, 8, 16 usw. skalierte Skalarprodukte skaliert, die parallel berechnet werden.
Zum Vergleich: Dieselbe Vektorisierung mit Intel SSE-Intrinsics ist ausführlicher und verwendet Präfixnotation (d. h. Funktionsaufrufe):
using Vec3D = std::array<__m128, 3 >;
__m128 scalar_product (Vec3D a, Vec3D b) {
return _mm_add_ps ( _mm_add_ps ( _mm_mul_ps (a[ 0 ], b[ 0 ]), _mm_mul_ps (a[ 1 ], b[ 1 ])),
_mm_mul_ps (a[ 2 ], b[ 2 ]));
}
Das Obige lässt sich weder auf AVX, AVX-512 usw. skalieren, noch ist es auf andere SIMD-ISAs portierbar.
cmake >= 3.0
C++11-Compiler:
git clone https://github.com/VcDevel/Vc.git
cd Vc
git submodule update --init
$ mkdir build
$ cd build
$ cmake ..
Geben Sie optional ein Installationsverzeichnis an:
$ cmake -DCMAKE_INSTALL_PREFIX=/opt/Vc ..
Fügen Sie optional die Erstellung der Komponententests hinzu:
$ cmake -DBUILD_TESTING=ON ..
Wenn Sie unter Windows mehrere Versionen von Visual Studio installiert haben, können Sie eine auswählen:
$ cmake -G " Visual Studio 16 2019 " ..
Eine Liste möglicher Generatoren finden Sie unter cmake --help
.
$ cmake --build . -j 16
$ cmake --install . # may require permissions
Unter Windows können Sie Vc.sln
auch in Visual Studio öffnen und über die IDE erstellen/installieren.
Die Dokumentation wird über doxygen erstellt. Sie können die Dokumentation erstellen, indem Sie doxygen
im Unterverzeichnis doc
ausführen. Alternativ finden Sie nächtliche Builds der Dokumentation unter:
Arbeiten Sie an der Integration der Funktionalität von Vc in die C++-Standardbibliothek.
Vc wird unter den Bedingungen der 3-Klausel-BSD-Lizenz veröffentlicht.