2016-06-05 10 views
2

Gibt es Anweisungen in SSE/SSE2 in der Lage, max/min in 4 ganzen 32-Bit zu finden? Ich habe versucht, etwas zu suchen, aber ich fand nur Anweisungen für 16/8 Bit. Vielen Dank im Voraus.Finden Sie max unter 32 Bit Ganzzahlen

https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=max&expand=4465,4463,3278&techs=SSE,SSE2

+3

Suchen Sie eine horizontale Operation? Oder 4 gepackte Max-Operationen parallel, wie 'pmaxsd'? Wenn Sie ein horizontales Maximum mit SSE2 benötigen, speichern Sie es einfach im Speicher und verwenden Sie Skalar. Mit SSE4.1 wäre dann das Shuffling wie für eine horizontale Summe am schnellsten. Horizontale Operationen sind langsam. Wenn Ihr Algorithmus viele benötigt, verwenden Sie SIMD falsch. Weitere Informationen finden Sie im [SSE-Tag-Wiki] (http://stackoverflow.com/tags/sse/info). –

+0

"Suchen Sie eine horizontale Operation?" Ich suche nach Operationen parallel. Ok, Sie schlagen vor, im Speicher zu speichern und skalare Operationen zu verwenden. (im Falle von horizontal). Aber warum schlägst du vor? Schließlich hat die Verwendung von SIMD keinen Vorteil. Meinst du, dass die horizontale Operation so schnell wie "Speichern in den Speicher und vergleichen Sie in" normalen "(skalaren) Weg? – Gilgamesz

+0

Wenn Sie genau 4 Nummern, anstatt 1000 Nummern, gibt es nicht viel Nutzen von SIMD. (Es sei denn Ihre Zahlen sind 16bit ohne Vorzeichen, so dass Sie den speziellen Zweck ['PHMINPOSUW'] (http://www.felixcloutier.com/x86/PHMINPOSUW.html) verwenden können. Horizontal bedeutet" innerhalb eines einzelnen Vektors ", im Gegensatz zu was SIMD ist gut bei (zB füge a [0] zu b [0] hinzu, a [1] zu b [1] usw.) Wenn du ein horizontales Maximum von 4 Elementen ohne SSE4.1 finden musst, dann wahrscheinlich Skalar –

Antwort

5

Der beste Weg ohne SSE4.1 scheint ein 32-Bit-Vergleich zu sein, und dann verwenden Sie diese Maske zu mischen: AND(mask, x) OR ANDN(mask, y).

Agner Fog's vector class library hat a function for it:

// function max: a > b ? a : b 
static inline Vec4i max(Vec4i const & a, Vec4i const & b) { 
#if INSTRSET >= 5 // SSE4.1 supported 
    return _mm_max_epi32(a,b); 
#else 
    __m128i greater = _mm_cmpgt_epi32(a,b); 
    return selectb(greater,a,b); 
#endif 
} 

Ich habe einige meist-ungetestet und noch nicht fusionierten Änderungen für diese Bibliothek on github. Die meisten meiner Änderungen sind signifikante Verbesserungen für die wenigen Funktionen, die ich mir angesehen habe (ganzzahlige horizontale Summen, Vierwort-Rechenkorrektur, Vierfach-Multiplikation). (Test/Feedback willkommen!)

Aber eine Menge des vorhandenen Codes ist ziemlich gut, also würde ich definitiv empfehlen, diese Wrapper-Klassen zu verwenden. Sie fügen keinen Overhead hinzu, wenn Sie mit aktivierten Optimierungen bauen, und sie machen die Syntax viel einfacher. z.B. a+b anstelle von _mm_add_epi32(a,b).

+0

Vielleicht sind horizontale Operationen tief liegende Früchte.Ich meine, sie sind keine Operationen, die man normalerweise in einer kritischen Schleife habenwürde, deshalb ist ihre Optimierung nicht so wichtig.haben Sie kritische Funktionen in der VCL gefunden, die optimiert werden müssen? Der schwierigste Teil der VCL sind Permutionen und Mischungen, siehe zum Beispiel [http://agner.org/optimize/vectorclass/r ead.php? i = 120). Ich denke, das ist der schwierigste Bereich, den man mit einer allgemeinen Klasse implementieren kann. –

+1

@Zboson: yeah, es stellt sich heraus, dass die gesamte VCL immer 'vpblendvb' verwendet (2 Ups und eine Maske aus dem Speicher benötigt), sogar für kompilierzeitkonstante Mischungen. Als nächstes auf meiner Liste ist es, die Vorlagen so zu fixieren, dass sie viel schneller 'vpblendd' oder' plblendw' verwenden, wenn möglich.Ich habe auch eine Beschleunigung für 'operator >> (Vec2q)' (emuliert das fehlende 'psarq'), wo ich wesentlich besser für die 128b-Version getan habe, als nur Variable-Blend zu Sofort-Blend zu ändern. –

+0

[Hier] (https://stackoverflow.com/questions/34122605/how-to-optimize-simd-transpose-function-8x4-4x8/34207876#34207876) ist ein weiteres interessantes Beispiel. Ich habe es schließlich richtig gemacht, aber das Problem ist, dass ich mehrere Varianten ausprobieren musste, bevor die VCL idealen Code anstelle von schlechtem Code produzierte. –

2

Vielleicht tut PMAXSD den Trick?

Vergleicht gepackte vorzeichenbehaftete dword-Ganzzahlen im Zieloperanden (erster Operand) und dem Quelloperanden (zweiter Operand) und gibt das Maximum für jeden gepackten Wert im Zieloperanden zurück.

Es erfordert jedoch SSE 4.1 und/oder AVX-Unterstützung.

Verwandte Themen