Wie unter Verwendung von SSE 16-Bit-Ganzzahl durch 255 zu teilen?

8

Ich beschäftige mich mit der Bildverarbeitung. Ich muss den 16-Bit-Integer-SSE-Vektor durch 255 teilen.

Ich kann den Shift-Operator nicht wie _mm_srli_epi16 () verwenden, weil 255 kein Vielfaches von Potenz 2 ist.

Ich weiß natürlich, dass es möglich ist, Integer in Float zu konvertieren, Division durchzuführen und dann die Konvertierung in Integer zurückzusetzen.

Aber vielleicht weiß jemand eine andere Lösung ...

    
Claudio 09.02.2016, 06:28
quelle

3 Antworten

11

Es gibt eine ganzzahlige Approximation der Division durch 255:

%Vor%

Bei Verwendung von SSE2 wird es also so aussehen:

%Vor%

Für AVX2:

%Vor%

Für Altivec (Power):

%Vor%

Für NEON (ARM):

%Vor%     
ErmIg 09.02.2016, 06:38
quelle
6

Wenn Sie ein exakt korrektes Ergebnis für alle Fälle wünschen, folgen Sie dem Rat von Marc Glisse Kommentar zu der Frage Anton verlinkt: SSE Integer Division?

Verwenden Sie die native Vektorsyntax von GNU C, um die Teilung eines Vektors nach dem angegebenen Skalar auszudrücken und zu sehen, was es tut :

%Vor%

Auf die Gefahr der Blähung der Antwort, hier ist es wieder mit intrinsics:

%Vor%

Beachten Sie in der Ausgabe von godbolt, dass gcc intelligent genug ist, die gleiche 16B-Konstante für die set1 im Speicher zu verwenden, und für die, die sie selbst generiert hat, für div255 . AFAIK, das funktioniert wie string-constant merging.

    
Peter Cordes 09.02.2016 08:07
quelle
3

GCC optimiert x/255 mit x ist unsigned short bis DWORD(x * 0x8081) >> 0x17 , was weiter vereinfacht werden kann in HWORD(x * 0x8081) >> 7 und schließlich HWORD((x << 15) + (x << 7) + x) >> 7 .

SIMD-Makros können so aussehen:

%Vor%     
Youka 09.02.2016 06:53
quelle

Tags und Links