2015-03-24 11 views
7

MSVC und ICC unterstützen beide die Eigen- schaften und _addcarryx_u64._addcarry_u64 und _addcarryx_u64 mit MSVC und ICC

Entsprechend Intel's Intrinsic Guide und white paper sollten diese auf adcx bzw. adox abgebildet werden. Wenn man sich jedoch die erzeugte Baugruppe ansieht, wird deutlich, dass sie adc bzw. adcx zugeordnet werden und es gibt keine intrinsische, die auf adox zuordnet.

Zusätzlich erzählt die Compiler AVX2 mit /arch:AVX2 in MSVC oder -march=core-avx2 mit ICC auf Linux macht keinen Unterschied zu ermöglichen. Ich bin mir nicht sicher, wie man ADX mit MSVC und ICC aktiviert.

Die documentation for MSVC Listen _addcarryx_u64 mit der Technologie von ADX, während keine gelistete Technologie hat. Der Link in MSVCs Dokumentation für diese intrinsischen Komponenten geht jedoch direkt auf den Intel Intrinsic-Leitfaden zurück, der der eigenen Dokumentation von MSVC und der generierten Baugruppe widerspricht.

Daraus schließe ich, dass Intels Intrinsic Leitfaden und Whitepaper falsch sind.

Dies macht Sinn für MSVC Sinn es nicht erlaubt Inline-Montage sollte es eine Möglichkeit zur Verwendung adc, die es mit tut.

Einer der großen Vorteile von adcx und adox ist, dass sie auf verschiedene Flags (carry CF und Überlauf OF), und dies ermöglicht es, zwei unabhängige parallele Übertrags-Ketten arbeiten. Da es jedoch keinen intrinsischen für adox gibt, wie ist das möglich? Mit ICC kann mindestens eine Inline-Assembly verwendet werden, dies ist jedoch mit MSVC im 64-Bit-Modus nicht möglich.


Die Dokumentation von Microsoft und Intel (sowohl das Whitepaper als auch die Online-Anleitung) stimmen jetzt überein.

Die intrinsische Dokumentation sagt produziert nur adc. Die _addcarryx_u64 intrinsische kann entweder adcx oder adox produzieren. Mit MSVC 2013 und 2015 produziert jedoch nur adcx. ICC produziert beides.

+0

ADOX und ADCX werden seit Broadwell eingeführt, also wie können Sie es mit AVX2 arbeiten lassen? –

+0

@ LưuVĩnhPhúc, sehr guter Punkt. Wie aktivieren Sie 'ADX' mit MSVC und ICC? In jedem Fall erzeugte der Compiler adcx mit _addcarryx_u64 –

+0

@ LưuVĩnhPhúc, ICC 13.0.1 (was ich von https://gcc.godbolt.org/ verwende) kam Ende 2012 heraus, also unterstützt es wahrscheinlich nicht 'ADX'. ICC ist jetzt bis zu 15.0.2. Ich denke, wenn ADX nicht aktiviert ist, verwenden sowohl MSVC als auch ICC 'adc' mit' _addcarry_u64'. Das würde erklären, was ich beobachte. Die Kompilierung sollte für '_addcarryx_u64' fehlschlagen, wenn' ADX' nicht aktiviert ist (und '_addcarryx_u64' soll meiner Meinung nach' adox' und nicht 'adcx' erzeugen). –

Antwort

2

Sie entsprechen adc, adcx UND adox. Der Compiler entscheidet, welche Anweisungen verwendet werden sollen, je nachdem, wie Sie sie verwenden. Wenn Sie zwei Big-Int-Additionen parallel ausführen, verwendet der Compiler für höheren Durchsatz adcx und adox. Zum Beispiel:

unsigned char c1 = 0, c2 = 0 
for(i=0; i< 100; i++){ 
    c1 = _addcarry_u64(c1, res[i], a[i], &res[i]); 
    c2 = _addcarry_u64(c2, res[i], b[i], &res[i]); 
} 
+0

Ich weiß nicht, wie man 'ADX' mit ICC oder MSVC aktiviert. Ich bin mir nicht sicher, ob ICC 13 dies unterstützt. Vielleicht können Sie die Assembly-Ausgabe für ein Beispiel zu Ihrer Antwort hinzufügen? –

+1

* "Ich weiß nicht, wie man ADX mit ICC aktiviert ..."* - Für GCC, ICC und möglicherweise Clang, verwenden Sie entweder '-march = native' (wenn es eine native CPU-Funktion ist), oder fügen Sie' -madx' Feature-Flag hinzu. Verwandte, siehe [Testfall für adcx und adox] (http (http://stackoverflow.com/q/39320944). Es generiert nicht 'adcx' /' adox' unter GCC 6.1 bei '-O3'. – jww

+0

*" Der Compiler entscheidet, welche Anweisungen zu verwenden, basierend auf wie Sie sie verwenden. . * - Glaubst du, dass ein 4-Wege-Add-mit-Übertrag den Compiler dazu bringen kann, etwas anderes als ein serialisiertes 'adc' zu erzeugen? – jww

2

Verwandte, GCC unterstützt ADOX und ADCX im Moment nicht. "Im Moment" beinhaltet GCC 6.4 (Fedora 25) und GCC 7.1 (Fedora 26). GCC hat die intrinsics effektiv deaktiviert, aber es gibt immer noch Unterstützung, indem __ADX__ im Präprozessor definiert wird. Siehe auch Issue 67317, Silly code generation for _addcarry_u32/_addcarry_u64. Vielen Dank an Xi Ruoyao für das Finden des Problems.

Laut Uros Bizjak auf der GCC-Hilfe-Mailingliste kann GCC never support the intrinsics. Siehe auch GCC does not generate ADCX or ADOX for _addcarryx_u64.

Clang hat seine eigenen Probleme in Bezug auf ADOX und ADCX. Clang 3.9 und 4.0 Absturz beim Versuch, sie zu verwenden. Siehe auch Issue 34249, Panic when using _addcarryx_u64 with Clang 3.9. Laut Craig Topper sollte es in Clang 5.0 behoben werden.

Ich entschuldige mich für die Veröffentlichung der Informationen unter einer MSVC Frage. Dies ist einer der wenigen Treffer bei der Suche nach Informationen zur Verwendung der intrinsics.