Stiamo eseguendo un programma scientifico e vorremmo implementare le funzionalità AVX. L'intero programma (scritto in Fortran + C) sta per essere vettorializzato e al momento sto cercando di implementare la moltiplicazione di numeri complessi all'interno dell'assemblaggio in linea di GCC.Codice assembly/istruzioni AVX per la moltiplicazione di numeri complessi. (Assemblaggio in linea GCC)
Il codice del montaggio 4 numeri complessi ed esegue due moltiplicazioni complesse contemporaneamente:
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;
}
dove A e B sono 256 bit doppia precisione:
typedef union v2complex {
__m256d v;
complex c[2];
} v2complex;
Il problema è che il il codice produce principalmente il risultato corretto, ma a volte fallisce.
Sono molto nuovo all'assemblaggio, ma ho cercato di capirlo da solo. Sembra che il programma C (ottimizzato -O3) interagisca con i registri ymm
utilizzati nel codice assembly. Ad esempio, posso stampare uno dei valori (ad es. A) prima di eseguire la moltiplicazione e il programma non dà mai risultati errati.
La mia domanda è come dire a GCC di non interagire con ymm. Non sono riuscito a inserirenell'elenco di registri con errori.
grazie mille, che ha risolto il problema =). Sto usando gcc 4.7.2 e thx per il tuo consiglio. –
Non usare '" r "(a)," r "(b)' con 'vmovupd (% 2), %% ymm1' ecc. GCC presumerà che * a e * b non siano accessibili (a meno che tu non aggiungi un clobber di "memoria"). –