Maximalwert in einem __m128i-Vektor mit SSE erhalten?

Lesezeit: 4 Minuten

Shanes Benutzeravatar
Shane

Ich habe gerade angefangen, SSE zu verwenden, und bin verwirrt, wie ich den maximalen ganzzahligen Wert (max) von a __m128i. Zum Beispiel:

__m128i t = _mm_setr_ps(0,1,2,3);
// max

Herumsuchen führte mich zu MAXPS Anleitung, aber ich kann nicht finden, wie man das mit verwendet "xmmintrin.h".

Gibt es auch eine Dokumentation für "xmmintrin.h" die Sie empfehlen würden, anstatt in die Header-Datei selbst zu schauen?

  • Die Mischvorgänge, die Sie benötigen, sind die gleichen wie für eine horizontale Summe oder so ziemlich jede andere horizontale Reduktion. Unter stackoverflow.com/questions/6996764/… finden Sie einige optimierte Versionen für Float, Integer und Double mit SSE2, SSE3 und AVX. Auch Diskussion darüber, welche Shuffles auf welchen CPUs optimal sind.

    – Peter Cordes

    9. September 2017 um 2:36 Uhr

  • Diese Frage scheint in Bezug auf Float vs. Integer verwirrt zu sein. __m128i ist ein ganzzahliger Vektor. *_ps Und MAXPS sind Einzelschwimmer verpackt. Informationen zur Dokumentation finden Sie im SSE-Tag-Wiki für Links und viele weitere Links unter stackoverflow.com/tags/x86/info. Eine sehr gute Ressource ist Intels Intrinsic Search/Finder die Details darüber enthält, was jeder tut, aber nicht so detailliert wie in der asm-Bedienungsanleitung.

    – Peter Cordes

    9. September 2017 um 2:39 Uhr


Falls es jemanden interessiert und da Intrinsic heutzutage der richtige Weg zu sein scheint, hier eine Lösung in Bezug auf Intrinsic.

int horizontal_max_Vec4i(__m128i x) {
    __m128i max1 = _mm_shuffle_epi32(x, _MM_SHUFFLE(0,0,3,2));
    __m128i max2 = _mm_max_epi32(x,max1);
    __m128i max3 = _mm_shuffle_epi32(max2, _MM_SHUFFLE(0,0,0,1));
    __m128i max4 = _mm_max_epi32(max2,max3);
    return _mm_cvtsi128_si32(max4);
}

Ich weiß nicht, ob das besser ist:

int horizontal_max_Vec4i(__m128i x) {
    int result[4] __attribute__((aligned(16))) = {0};
    _mm_store_si128((__m128i *) result, x);
    return max(max(max(result[0], result[1]), result[2]), result[3]); 
}

Benutzeravatar von Paul R
Paul R

Wenn Sie horizontale Operationen an Vektoren durchführen müssen, insbesondere wenn es sich innerhalb einer inneren Schleife befindet, dann ist es so normalerweise ein Zeichen dafür, dass Sie Ihre SIMD-Implementierung falsch angehen. SIMD operiert gerne elementweise auf Vektoren – “vertikal” wenn man so will, nicht horizontal.

Was die Dokumentation betrifft, so gibt es a sehr nützliche Referenz auf intel.com das alle Opcodes und Intrinsics für alles von MMX über die verschiedenen Varianten von SSE bis hin zu AVX und AVX-512 enthält.

  • Vielen Dank für den Link. Der horizontale Teil ist nur für eine Schleifenbedingung, aber ich werde meinen Ansatz überarbeiten

    – Shane

    26. März 2012 um 20:23 Uhr

  • Der Link lautet derzeit: software.intel.com/sites/landingpage/IntrinsicsGuide

    – Mark Lakata

    5. Dezember 2014 um 0:09 Uhr

  • @MarkLakata: Danke – Antwort aktualisiert – Ich vermisse den alten Offline-Leitfaden – Neben der Arbeit ohne Internetverbindung war es auch nützlich, dass Sie die Daten für andere Zwecke kratzen konnten. Aber egal – die neue Online-Version ist immer noch gut.

    – PaulR

    5. Dezember 2014 um 7:28 Uhr

Benutzeravatar von Jens Björnhager
Jens Björnhager

Entsprechend diese Seitegibt es kein horizontales Maximum, und Sie müssen die Elemente vertikal testen:

movhlps xmm1,xmm0         ; Move top two floats to lower part of xmm1
maxps   xmm0,xmm1         ; Get the maximum of the two sets of floats
pshufd  xmm1,xmm0,$55     ; Move second float to lower part of xmm1
maxps   xmm0,xmm1         ; Get the maximum of the two remaining floats

Umgekehrt das Minimum zu erhalten:

movhlps xmm1,xmm0
minps   xmm0,xmm1
pshufd  xmm1,xmm0,$55
minps   xmm0,xmm1

  • pshufd zwischen maxps Anweisungen haben auf vielen CPUs (einschließlich Intel) eine zusätzliche Latenz. SSE3 movshdup dupliziert den oberen Float in jeder Hälfte des Registers, sodass Sie ihn verwenden können, um eine Movaps-Kopie zu vermeiden.

    – Peter Cordes

    9. September 2017 um 1:54 Uhr

  • @PeterCordes, könnten Sie Ihre eigene optimierte Lösung schreiben? Wäre es anders, wenn es ein Float-Vektor wäre? Danke schön.

    – Royi

    10. Oktober 2017 um 23:05 Uhr


  • @ Royi: diese Antwort Ist für einen Vektor von float (da die Frage falsch betitelt oder in Bezug auf Float vs. Integer verwechselt ist, siehe meine Kommentare zur Frage). Optimiert für welche Mikroarchitektur(en) und mit welchem ​​SSE-Level? SSE3? Oder auf SSE2 beschränkt? Oder AVX2? Siehe stackoverflow.com/questions/6996764/… (aber ersetzen add mit max) für verschiedene optimierte Float- und Integer-Shuffles.

    – Peter Cordes

    10. Oktober 2017 um 23:18 Uhr


  • Sagen wir SSE4. Optimiert für Haswell und höher. Danke schön. PS Ich meinte die Verwendung von SSE Intrinsics, ist das nicht die obige Assembly?

    – Royi

    10. Oktober 2017 um 23:48 Uhr


  • @PeterCordes, ich habe es so verwendet, wie es hier gezeigt werden kann – codereview.stackexchange.com/questions/177658. Ist es das, was du meintest? Irgendeine Idee, warum es immer noch so langsam ist?

    – Royi

    11. Oktober 2017 um 0:58 Uhr

Es gibt keinen horizontalen maximalen Opcode in SSE (zumindest bis zu dem Punkt, an dem ich aufgehört habe, neue SSE-Anweisungen zu verfolgen).

Sie stecken also fest, indem Sie etwas mischen. Was Sie am Ende haben, ist …

movhlps %xmm0, %xmm1            # Move top two floats to lower part of %xmm1
maxps   %xmm1, %xmm0            # Get minimum of sets of two floats
pshufd  $0x55, %xmm0, %xmm1     # Move second float to lower part of %xmm1
maxps   %xmm1, %xmm0            # Get minimum of all four floats originally in %xmm0

http://locklessinc.com/articles/instruction_wishlist/

MSDN hat die intrinsischen und Makrofunktionszuordnungen dokumentiert

http://msdn.microsoft.com/en-us/library/t467de55.aspx

1444080cookie-checkMaximalwert in einem __m128i-Vektor mit SSE erhalten?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy