Wir betreiben ein wissenschaftliches Programm und möchten AVX Features implementieren. Das ganze Programm (geschrieben in Fortran + C) wird vektorisiert werden und im Moment versuche ich eine komplexe Zahlenmultiplikation innerhalb der GCC Inline Assembly zu implementieren.Assemblercode/AVX-Anweisungen zur Multiplikation komplexer Zahlen. (GCC Inline Assembly)
Der Assembler-Code dauert 4 komplexe Zahlen und führt zwei auf einmal komplex Multiplikationen:
v2complex cmult(v2complex *a, v2complex *b) {
v2complex ret;
asm (
"vmovupd %2,%%ymm1;"
"vmovupd %2, %%ymm2;"
"vmovddup %%ymm2, %%ymm2;"
"vshufpd $15,%%ymm1,%%ymm1,%%ymm1;"
"vmulpd %1, %%ymm2, %%ymm2;"
"vmulpd %1, %%ymm1, %%ymm1;"
"vshufpd $5,%%ymm1,%%ymm1, %%ymm1;"
"vaddsubpd %%ymm1, %%ymm2,%%ymm1;"
"vmovupd %%ymm1, %0;"
:
"=m"(ret)
:
"m" (*a),
"m" (*b)
);
return ret;
}
wobei a und b 256-Bit-Doppelpräzisions sind:
typedef union v2complex {
__m256d v;
complex c[2];
} v2complex;
Das Problem ist das, dass die Code erzeugt meistens das korrekte Ergebnis, aber manchmal schlägt es fehl.
Ich bin sehr neu in der Montage, aber ich habe versucht, es selbst herauszufinden. Es scheint, dass das C-Programm (optimiertes -O3) mit den Registern ymm
interagiert, die im Assemblercode verwendet werden. Zum Beispiel kann ich einen der Werte (z.B. a) vor dem Ausführen der Multiplikation drucken, und das Programm liefert niemals falsche Ergebnisse.
Meine Frage ist, wie man GCC sagt, nicht mit ymm zu interagieren. Ich schaffte es nicht, setzen Sie die ymm
zu clobbered Registerliste.
Vielen Dank, dass das Problem gelöst =). Ich benutze gcc 4.7.2 und thx für Ihren Rat. –
Verwenden Sie nicht '" r "(a)," r "(b)' mit 'vmovupd (% 2), %% Ymm1' etc, GCC wird davon ausgehen, dass * a und * b nicht zugegriffen werden (außer Sie füge einen "Memory" Clobber hinzu. –