2016-06-05 11 views
0
.loop: 

    movups xmm1, [esi+ecx*4] 
    movaps xmm2, xmm0 
    movaps xmm5, xmm1 

    pcmpgtd xmm2, xmm1 

    andps xmm0, xmm2 
    andnps xmm2, xmm1 
    orps xmm0, xmm2 

    pcmpgtd xmm5, xmm3 

    andps xmm3, xmm5 
    andnps xmm5, xmm1 
    orps xmm3, xmm5 

.cond: 
    add ecx, 4 
    js .loop 

Dies ist eine Basisschleife, um max/min unter den Eingängen zu finden. Der mein Prozessor ist AMD K8. Ich bin nicht in der Lage, cycles zu zählen, aber ich kann vergleichen, dass mein Code langsamer ist als meine Freunde, die SIMD nicht benutzt haben. Ich kann nicht verstehen warum. Ist diese Schleife nicht optimal? Siehst du eine Ursache?Min/Max. Optimierung

Antwort

1

K8 hat nur 64-Bit-Ausführungseinheiten, so dass jeder 128-Bit-Befehl in 2 m-Ops decodiert wird. Auch movups ist mehr m-ops als movaps, auch wenn die Adresse ausgerichtet ist. (Obwohl nach Agner Fog Tabellen, es hat immer noch die gleiche pro Zyklus 2 Durchsatz als movaps.)

Wenn Sie Zweige in der skalaren Version verwendet und die min und max nicht oft ändern, dann Verzweigungsvorhersage kann lass es ziemlich schnell laufen.

Dies ist einer der Fälle, in denen SIMD so viel mehr arbeiten muss, dass es tatsächlich langsamer ist als Skalar. Obwohl diese SSE2-Version möglicherweise besser als Skalar auf CPUs mit voller Breite Vektoreinheiten, wie K10 oder Merom. (oder neuer)

Natürlich erhalten Sie weit bessere Ergebnisse mit SSE4.1 pmaxsd/pminsd.