SSE abs()



  • Gibt es keine Berechnung für den Absolutbetrag in SSE(2)?
    Ich finde irgendwie keine in der MSDN....

    Saturate kann ich eigentlich nicht gebrauchen, weil ich das (richige) Ergebniss der Subtraktion brauche. Vielleicht bin ich ja blind.

    Gruß
    Michael


  • Mod

    für float/double: am besten mit adnnps/andnpd mit einer konstanten, die nur die vorzeichenbits enthält (so kannst du dieselbe konstante auch direkt für vorzeichenwechsel verwenden), siehe dazu auch
    http://www.c-plusplus.net/forum/viewtopic.php?t=94628

    für integer: evtl. PSADBW - falls es ungepackte bytes sind...
    ansonsten schlage ich vor, das ergebnis mit null zu vergleichen, etwa so:

    // ...
    { // asm
        pxor    xmm2, xmm2         // null
        psubd   xmm0, xmm1
        pcmpgtd xmm2, xmm0         // ergebnis ist 0xffffffff, wenn der wert in xmm0 negativ ist, sonst 0
        pxor    xmm0, xmm2
        psubd   xmm0, xmm2         // abs
    }
    

    sinngemäss das ganze für andere integer grössen oder mmx register (ausser 64bit integer, da müsste man noch etwas mehr tun - es gibt nur pcmpgtd, also könnte man dieses benutzen, und dann die maske aus dem höherwertigen teil z.b. mit pshufd in den niederwertigen kopieren)



  • Ich hatte garnicht gesehen, dass im SSE-Wrapper schon ein abs() vorhanden ist. 🕶
    (BTW: Der Wrapper währe doch was für die FAQ. Z.B. hat jeder, der mit SSE zu tun hat irgenwann Probleme mit 'aligned')

    Vorzeichenbit? Habe ich auch dran gedacht, aber ich dachte das Vorzeichenbit gibts nur im Einerkomplement was eigentlich nicht (selten) benutzt wird um Bin-Zahlen zu speichern. Ich kann mich da auch irren(ist schon etwas her); wenn's falsch ist, bitte um Berichtigung 🙂

    \\edit

    PSADDBW war auch mein erster Gedanke, aber bei
    ' r0 := abs(a0 - b0) + abs(a1 - b1) +...+ abs(a7 - b7) '
    ist dann der ganze (parallel) Vorteil von SSE wieder hin, weil dann [a1,a7]=[b1,b7]=0 sein müsste....

    Berechnen will ich übrigens:
    if(|a-b| < |c-b|){...}
    Leider gibts da nicht viel, um den Betrag analytisch aufzulösen..

    Gruß


  • Mod

    wenn es (als integer problem) nicht schon in einen sse2 teil eingebettet ist, kommst du bei dieser bedingung möglicherweise besser, das problem ohne sse2 zu lösen. eine möglich keit wäre noch, die operanden vor der subtraktion mit min und max zu ordnen, so dass der vorzeichenwechsel entfällt; allerdings müsstes du zum testen der bedignung ja trotzdem die differenzen gegenüberstellen, insofern ist die parallelisierbarkeit stark eingeschränkt.

    bei gleitkommazahlen ist das vorzeichen immer ein separates bit und die mantisse selbst vorzeichenlos.
    was den wrapper betrfft, so ist zu beachten, dass das keine wirklich optimale lösung darstellt. wenn man wirklich ein ernsthaftes projekt damit starten wollte, käme man um einen klassenbasierten custom allocator nicht drumherum. die hier dargestellte methode ist extrem schlecht was performance und speicherverbrauch angeht - sie funktioniert lediglich.


Anmelden zum Antworten