Das war um 2. Praktikum aber nicht so

Es rechnet noch richtig.
Code: Alles auswählen
"movups (%[src]), %%xmm1\n"
:
: [src] "a" (&a.x),
[dest] "b" (&result.x)
: "%esi"
);
Ganz so stimmt das glaube ich nicht. Gibt man als Parameter "-mfpmath=sse" und "-msse2" an, dann verwendet gcc anstatt der FPU die xmm Register für skalare Operationen. Auf die Art und Weise lassen sich Berechnungen besser optimieren, da die Stack Struktur der FPU dafür eher ungeeignet ist. Kompiliert man auf 64bit (wie etwa auf dem Cluster), werden diese Flags automatisch gesetzt. Für automatische Vektorisierung (ps-Befehle) braucht man wahrscheinlich eher den Intel Compiler... Inwiefern gcc die Befehle konkret auf die Pipeline vom verbauten Prozessor optimieren kann weiß ich nicht, schließlich unterstüzt die g++Verison 4.5 auf dem Cluster als Architekturprofile maximal core2 und nicht corei7.^^x539 hat geschrieben:gcc verwendet sse schon von alleine wenn man mit -O3 compiliert. Deshalb wird es schwer das per handgeschriebenen inline-Asm zu übertreffen. Im 2. praktikum war standard mäßig die Optimierung aus geschaltet, desshalb war der unterschied deutlicher zu sehen.
Außerdem kann der Compiler, den Code nicht mehr so gut Optimieren wenn du inline-Asm blöck reinschreibst. Zum Beispiel kann er die reinfolge der Befehle nicht mehr optimal den die pipline der CPU anpassen, weil er den inline-asm-block fest übernehemen muss. Schlecht ist außerdem wenn du feste Register vorgibst die du verwenden willst. Dann müssen eventuell werte sinnlos hin und hergeschoben werden, nur weil du dich auf rax, rbx, etc. festgelegt hast obwohl das genauso gut ein beliebiges anders Register hätte sein können, in dem der wert bereits steht, bzw. in dem der Wert später benötigt wird.
Ich denke nicht das die sich starke unterscheiden, abersimon.r hat geschrieben:Inwiefern gcc die Befehle konkret auf die Pipeline vom verbauten Prozessor optimieren kann weiß ich nicht, schließlich unterstüzt die g++Verison 4.5 auf dem Cluster als Architekturprofile maximal core2 und nicht corei7.^^
Code: Alles auswählen
movl foo, rax
xor foo, rax
movl foo, rbx
xor foo, rbx
Code: Alles auswählen
movl foo, rax
movl foo, rbx
xor foo, rax
xor foo, rbx
Code: Alles auswählen
movl foo, rax
xor foo, rax
Code: Alles auswählen
vec3 vec3::normalize() const
{
vec3 result = *this;
asm (
"\n\tmovups (%1), %%xmm0"
"\n\tmovups %%xmm0, %%xmm2"
"\n\tmulps %%xmm0, %%xmm0"
"\n\tmovups %%xmm0, %%xmm1"
"\n\tshufps $0b10010011,%%xmm0, %%xmm0"
"\n\taddps %%xmm0, %%xmm1"
"\n\tmovaps %%xmm1, %%xmm0"
"\n\tshufps $0b01001110,%%xmm1, %%xmm1"
"\n\taddps %%xmm1, %%xmm0"
"\n\trsqrtps %%xmm0, %%xmm0"
"\n\tmulps %%xmm2, %%xmm0"
"\n\tmovups %%xmm0, %0"
: "=m"(result)
: "r"(this) : "xmm0", "xmm1", "xmm2");
/*
float invL = 1.0f/length();
result.x *= invL;
result.y *= invL;
result.z *= invL; */
return result;
}
Hast du deine Implementierung mal getestet? Die sieht nicht aus als würde sie den Vektor auf Länge 1 normieren sondern nochmal um die Länge strecken.Jörg B hat geschrieben:Jetzt wo die Abgabe vorbei ist, kann mir ja vielleicht jemand einen Tipp geben wieso das so ist?