3dnow tests (tutorial scherfgen)
-
mein vorschlag wäre das hier:
inline void multwithvector(const float* input, const float* output, const int vectorcount) { asm ( "mov %3, %%edx\n\t" //vectorcount "shl 4, %%edx\n\t" //vectocount*16 "mov %0, %%eax\n\t" "mov %1, %%ebx\n\t" "mov %2, %%ecx\n\t" "add %%edx, %%ebx\n\t" "add %%edx, %%ecx\n\t" "neg %%edx" "femms\n\t" "loop:\n\t" "movq (%%ebx,%%edx), %%mm0\n\t" //für alle nicht at&t assembler: "movq 8(%%ebx,%%edx), %%mm1\n\t" //(%%ebx,%%edx,8) == (%ebx+%edx*8) "add 16, %%edx\n\t" //flags frühzeitig setzen, um sprungvorhersage zu optimieren "movq %%mm0, %%mm2\n\t" "pfmul (%%eax), %%mm0\n\t" "movq %%mm1, %%mm3\n\t" "pfmul 8(%%eax), %%mm1\n\t" "pfacc %%mm1, %%mm0\n\t" "movq %%mm2, %%mm4\n\t" "pfmul 16(%%eax), %%mm2\n\t" "pfacc %%mm2, %%mm0\n\t" "movq %%mm3, %%mm5\n\t" "pfmul 24(%%eax), %%mm3\n\t" "pfacc %%mm3, %%mm0\n\t" "movq %%mm4, %%mm6\n\t" "pfmul 32(%%eax), %%mm4\n\t" "movq %%mm5, %%mm7\n\t" "pfmul 40(%%eax), %%mm5\n\t" "pfacc %%mm5, %%mm4\n\t" "pfmul 48(%%eax), %%mm6\n\t" "pfacc %%mm6, %%mm4\n\t" "pfmul 56(%%eax), %%mm7\n\t" "pfacc %%mm7, %%mm4\n\t" "movq %%mm0, -16(%%ecx,%%edx)\n\t" //edx wurde schon erhöht "movq %%mm4, -8(%%ecx,%%edx)\n\t" "jnz loop\n\t" "femms\n\t" ://kein output //Ah=matrix .. ich berechne A*x nicht x*A wie im tutorial :"a" (Ah), "b" (input), "c" (output), "d" (vectorcount) ); }
-
huuuuuuuuuuu schrieb:
Ringding schrieb:
Ich glaube, es gibt keinen Compiler, der 3dnow-Code erzeugt.
gcc
Hmm, stimmt. Der kann aber nicht vektorisieren, das ist bei solchen Sachen auch oft nützlich/notwendig.
-
schön
funktioniert aber leider nicht.. gibt nen seg. fault. ich versuche gerade herauszufinden woran das liegt.. aber das selbe problem hatte ich auch mal (mein erster war auch ein logischer "von vorne nach hinten durchlaufen" ansatz) und konnte es nicht lösen.
gruss
eviluser
-
die pfacc befehle sind nat. falsch gewesen:
"movq (%%ebx,%%edx), %%mm0\n\t" "movq 8(%%ebx,%%edx), %%mm1\n\t" "add 16, %%edx\n\t" "movq %%mm0, %%mm2\n\t" "pfmul (%%eax), %%mm0\n\t" "movq %%mm1, %%mm3\n\t" "pfmul 8(%%eax), %%mm1\n\t" "pfacc %%mm1, %%mm0\n\t" "movq %%mm2, %%mm4\n\t" "pfmul 16(%%eax), %%mm2\n\t" "movq %%mm3, %%mm5\n\t" "pfmul 24(%%eax), %%mm3\n\t" "pfacc %%mm3, %%mm2\n\t" "movq %%mm4, %%mm6\n\t" "pfmul 32(%%eax), %%mm4\n\t" "pfacc %%mm2, %%mm0\n\t" "movq %%mm5, %%mm7\n\t" "pfmul 40(%%eax), %%mm5\n\t" "pfacc %%mm5, %%mm4\n\t" "pfmul 48(%%eax), %%mm6\n\t" "pfmul 56(%%eax), %%mm7\n\t" "pfacc %%mm7, %%mm6\n\t" "pfacc %%mm6, %%mm4\n\t" "movq %%mm0, -16(%%ecx,%%edx)\n\t" "movq %%mm4, -8(%%ecx,%%edx)\n\t"
warum hier ein segfault auftritt ist mir allerdings nicht klar
-
okok.. ich bestehe ja darauf at&t assembler zu verwenden.. da bin ich selbst daran schuld..
die lösung ist.. ich kann nicht einfach so ne zahl in nen operator schreiben.. ich muss sie kennzeichnen.. add $16, %%edxdann klappts.. bis auf den letzten schleifendurchlauf..
den kopiere ich einfach runter..
so.. perfekt
-
ich weiss nicht inwiefern das representativ ist.. deshalb nenne ich das ding einfach mal pseudobench..
ich brauche für 10000000 vektoren angeblich 1.1 sekunden prozessorzeit.
mit der anderen (umgekehrten version) genau das selbe.. ich suche jetzt erstmal nach diesem amd-tool.. vieleicht bekomme ich da brauchbarere werte raus
gruss
eviluser
-
ich probiere gerade einbischen mit der ausrichtung von adressen herum und wenn ich mir den code ansehe den du mir vorher gepostet hattest..
int *p,*p_aligned; p = malloc( 1000 * sizeof( int ) - 1 + ALIGNMENT ); p_aligned = (int*)( ( (unsigned)p - 1 + ALIGNMENT ) & -ALIGNMENT ); // irgendwas mit p_aligned tun free( p );
muss ich feststellen dass das ein trick ist den ich nciht verstehe
du erzeugst 2 pointer vom typ int. einem davon reservierst du speicher .. so etwa 4015 gross. und dann machst du etwas krasses mit p_aligned .. vergleichst es bitweise mit -Alignment ?? im endeffekt haben dan beide (p&p_aligned) die selbe adresse.. und die endet mit 0.. und irgendwie beschleicht mich das gefühl dass das kein zufall war..gruss
eviluser