Wie schlecht ist dieser Code? xD



  • Hallo,

    Ich beschäftige mich gerade mit SSE und implementiere zur Übung gewisse Funktionen aus meinen Projekten vollständig in Assembler (x86-64). Ich bin mir sehr wohl bewusst, dass der Compiler das vermutlich viel besser kann als ich - aber genau darum gehts mir auch: Ich will ein wenig ein Auge dafür bekommen, was gut und was weniger gut ist. Z.B. habe ich folgende reflect-Funktion (nasm-2.06rc7) für meine Vektorklasse (3 x 64-bit double) geschrieben:

    [global refl]
    refl:
        movaps xmm0, [rcx]
        movsd xmm1, [rcx + 010h]
        movaps xmm2, [rdx]
        movsd xmm3, [rdx + 010h]
        movaps xmm4, xmm0
        movsd xmm5, xmm1
        mulpd xmm4, xmm2
        mulsd xmm5, xmm3
        haddpd xmm4, xmm4
        addsd xmm4, xmm5
        addsd xmm4, xmm4
        movddup xmm4, xmm4
        mulpd xmm2, xmm4
        mulsd xmm3, xmm4
        subpd xmm0, xmm2
        subsd xmm1, xmm3
        movaps [r8], xmm0
        movsd [r8 + 010h], xmm1
        ret
    

    In C++ habe ich dann folgende Signatur für den Aufruf:

    // r = v - 2 * dot(v, n) * n
    extern "C" void __fastcall refl(const double *v /* = rcx */, const double *n /* = rdx */, double *r /* = r8 */);
    

    Der Code funktioniert und ist performancemässig fast gleich schnell wie der vom Compiler (MSVC2008) generierte Code. Warum nur fast? Wenn ich mir den vom Compiler generierten Code anschaue, dann gibts dort scheinbar nicht einmal Inlining. dot generiert dort etwas längeren Code:

    ;movsdx	xmm0, QWORD PTR [rcx+16]
    	;movsdx	xmm1, QWORD PTR [rcx+8]
    	;movsdx	xmm2, QWORD PTR [rcx]
    
    	mulsd	xmm0, QWORD PTR [rdx+16]
    	mulsd	xmm1, QWORD PTR [rdx+8]
    	mulsd	xmm2, QWORD PTR [rdx]
    	addsd	xmm0, xmm1
    	addsd	xmm0, xmm2
    

    Mein Code:

    ; Initialisierungen aus refl
        ;movaps xmm0, [rcx]
        ;movsd xmm1, [rcx + 010h]
        ;movaps xmm2, [rdx]
        ;movsd xmm3, [rdx + 010h]
        ;movaps xmm4, xmm0
        ;movsd xmm5, xmm1
    
        mulpd xmm4, xmm2
        mulsd xmm5, xmm3
        haddpd xmm4, xmm4
        addsd xmm4, xmm5
    

    Kann irgend jemand bitte meinen schlechten Code zerpflücken, damit ich etwas daran ändern kann? Ich habe das Gefühl, dass meine Initialisierungen nicht gerade optimal sind 😃

    MfG



  • /rant/ schrieb:

    Ich beschäftige mich gerade mit SSE und implementiere zur Übung gewisse Funktionen aus meinen Projekten vollständig in Assembler (x86-64).

    👍

    Ich habe leider "nur" eine 32-Bit CPU... 😞

    Kann es vielleicht sein, dass es solche Effekte wie hier sind http://www.c-plusplus.net/forum/viewtopic-var-t-is-237896.html

    Wie hast Du es gemessen?
    Wie sieht Deine C/C++ Implementierung der Funktion aus? Nur wenn's kein Geheimnis ist 😉


Anmelden zum Antworten