2016-05-09 8 views
2

Ich lerne openMP und habe mit meinem begrenzten Wissen meinen Code paralliert. Ich versuche, diesen Code mit OpenMP-Vektorisierungstechniken zu verbessern. Aber während ich durch relevante Lesestoffe ging (link), fand ich, dass es nicht möglich ist, Vektorisierungsoperationen auf langen doppelten Datentypen durchzuführen. Kann jemand Informationen darüber geben, warum dies so ist, und eine andere Lösung als die Verringerung der Präzision vorschlagen?Sind OpenMP-Vektorisierungsoperationen am langen doppelten Datentyp nicht möglich?

Der Inhalt in der Verbindung lautet wie folgt: "Vermeiden Sie Operationen, die nicht in SIMD-Hardware unterstützt werden. Arithmetik mit (80 Bit) langen Doppelungen unter Linux, und der Restoperator"% "sind Beispiele für Operationen, die in SIMD-Hardware nicht unterstützt werden. "

PS Ich benutze den INTEL C++ Compiler 16.0.2, den INTEL XEON Processor mit 128 Bit Vektorregister und Linux. Meine Datentypen sind meistens lang doppelt.

+0

Ich denke, du verwechselst Parallelismus mit Vektor intrinsisch. Ich vermute, dass es möglich ist, diese Operationen zu parallelisieren, auch wenn sie nicht der ISA von Intel zugeordnet sind. Wie auch immer, Sie müssen ein komplettes, lauffähiges Beispiel veröffentlichen. – Mikhail

+0

Da die x86-SIMD-Hardware (SSE über AVX512) nur 32-Bit- und 64-Bit-Float-Operationen unterstützt und keine Integer-Divisionsanweisungen hat. –

+0

Warum verwenden Sie Long Double? –

Antwort

3

Die SIMD-Anweisungen des x86-Befehlssatzes unterstützen nur 32-Bit- und 64-Bit-Fließkommaoperationen (mit eingeschränkter Unterstützung für 16-Bit-Gleitkommazahlen). Zusätzlich gibt es, obwohl es 64-Bit-Zeiten 64-Bit bis 128-Bit-Skalar-Ganzzahl-Befehle gibt (z. B. mulx) keine entsprechenden SIMD-Befehle. Viele Leute haben versucht und versäumt, effiziente 128-Bit-Ganzzahl-x86-SIMD-Arithmetik zu implementieren (es gibt einige Ausnahmen für multiplication und vielleicht addition). Es gibt keine allgemeinen x86-SIMD-Integer-Divisionsanweisungen.

Für Floating-Point-Benutzer haben jedoch mehr Erfolg mit höherer Präzision Gleitkomma SIMD-Operationen mit double-double. Double-Double hat 106 Bits Genauigkeit gegenüber 64 Bits Genauigkeit mit 80-Bit-Double. Aber nicht jeder C++ - Compiler verwendet 80-Bit-Long-Double. Einige verwenden nur Doppel (z. B. MSVC), die nur 54 Bits Genauigkeit und einige 128-Bit-Quad-Präzision, die 113 Bits Genauigkeit hat und Wikipedia behauptet sogar, dass mit einigen Compilern langen Doppel als Doppel-Doppel implementiert ist.

Ich beschrieb einige Details von Doppel-Doppel here. Beachten Sie, dass double-double kein IEEE-Gleitkommatyp ist und einige ungewöhnliche Eigenschaften aufweist. Auch der Bereich von Doppel-Doppel ist der gleiche wie Doppel, so dass es nur die Genauigkeit verbessert.

Wie schnell ist Double-Double im Vergleich zu Long Double? Ich habe das nie getestet. Aber ich fand Doppel-Doppel etwa 10 Mal langsamer als Doppel-Operationen, wenn man eine etwas ausgewogene Mischung von Multiplikations- und Additions-Operationen vornimmt. Und Long Double ist sicherlich langsamer als Double (außer wenn es als Double implementiert ist). Da man aber SIMD mit Double-Double verwenden kann, aber nicht mit dem Long-in-Long-Double, verbessert sich die Geschwindigkeit proportional zur SIMD-Breite. Also 2 Double-Double-Operationen mit SSE2, 4 mit AVX und 8 mit AVX512.

Erwarten Sie nicht, dass OpenMPs simd-Konstruktion double-double implementieren. Sie müssen dies selbst implementieren oder eine Bibliothek finden.