2016-06-07 23 views
5

Wie kann ich eine Bibliothek erstellen, die dynamisch zwischen SSE-, AVX- und AVX2-Codepfaden wechselt, abhängig vom Host-Prozessor/Betriebssystem? Ich benutze Agner Fogs VCL (Vector Class Library) und kompiliere mit GCC für Linux.Kompilieren von Multi-Architektur-Code mit Agners Vector Class Library

+0

Klingt wie eine Makefile-Lösung für mich. Sie kennen den Hostprozessor/das Betriebssystem beim Erstellen. Zur Laufzeit nicht nötig. – duffymo

+0

Für diejenigen, die diese Frage lesen, aber nicht auf VCL und GCC beschränkt ist, gibt es eine Reihe von "-axcode" Kompilierungsflags für Intel Compiler, die es ermöglichen, mehrere Codepfade für mehrere Befehlssatzarchitekturen zu generieren (zB für SSE , AVX und AVX-512) in derselben Bibliothek/ausführbaren Datei und zum automatischen (unsichtbaren) Versand zwischen ihnen in der Laufzeit. Sehen Sie sich den unteren Teil dieser Seite an: https://software.intel.com/en-us/blogs/2016/01/13/compiling-for-the-intel-xeon-phi-processor-x200-and-the- intel-avx-512-isa – zam

Antwort

3

Die Montageanleitung cpuid kann Ihnen diese Informationen zur Laufzeit geben. Jemand hat hilfreich eine Bibliothek auf dieser Grundlage nur what you need erstellt.

Sie könnten eine Tabelle für den Funktionsversand erstellen und sie mit den richtigen Codepfadfunktionen füllen, die auf den Ergebnissen der Abfrage mit diesem Code basieren.

UPDATE: (Antwort in den Kommentaren zu hinterfragen)

Um die unterschiedlichen Codepfade in erster Linie zu erstellen, müssen Sie die verschiedenen Codepfade separat kompilieren und sie dann miteinander verknüpfen. Für jeden einzelnen geben Sie die erforderliche Architektur an, indem Sie in Ihrer Kompilierzeile verschiedene Werte des Schalters -march verwenden.

+0

Das Problem ist, dass ich nicht (einfach?) verschiedene Code-Pfade erstellen kann, weil VCL intrinsics (nicht Inline-Assembly) verwendet, die der Compiler in den in den Compiler-Argumenten angegebenen Befehlssatz konvertiert. Ich hätte annehmen sollen, dass ich GCC verwende. –

+0

Siehe aktualisierte Antwort – Smeeheey

+0

Wie kann ich die Funktionsnamen für jeden Aufruf des Compilers mangeln? –

3

Siehe Abschnitt "Befehlssätze und CPU-Versand" in the manual to the Vector Class Library. In diesem Abschnitt Agner schreibt

Die Datei dispatch_example.cpp zeigt ein Beispiel dafür, wie einen CPU Dispatcher zu machen, die die entsprechende Code-Version auswählt.

the source code bis distpatch_example.cpp lesen. Am Anfang der Datei sollten Sie den Kommentar sehen

# Compile dispatch_example.cpp five times for different instruction sets: 
| g++ -O3 -msse2 -c dispatch_example.cpp -od2.o 
| g++ -O3 -msse4.1 -c dispatch_example.cpp -od5.o 
| g++ -O3 -mavx  -c dispatch_example.cpp -od7.o 
| g++ -O3 -mavx2 -c dispatch_example.cpp -od8.o 
| g++ -O3 -mavx512f -c dispatch_example.cpp -od9.o 
| g++ -O3 -msse2 -otest instrset_detect.cpp d2.o d5.o d7.o d8.o d9.o 
| ./test 

Die Datei instrset_detect.cpp. Sie sollten den Quellcode dazu auch lesen. Dies nennt CPUID.

Here ist eine Zusammenfassung einiger, aber nicht aller Fragen und Antworten zu CPU-Dispatchern.

+0

'dispatch_example.cpp' ruft 'insrset_detect' auf, das in' insrset.h' deklariert und in 'insrset_detect.cpp' definiert ist. –

+0

Entschuldigung, vergiss es –