Come costringere GCC a utilizzare tutti i registri SSE (o AVX)?
-
11-11-2019 - |
Domanda
Sto cercando di scrivere un codice intensivo computazionalmente per Windows X64 Target, con SSE o le nuove istruzioni AVX, compilando in GCC 4.5.2 e 4.6.1, MINGW64 (build GCC TDM e qualche build personalizzata). Le mie opzioni del compilatore sono -O3 -mavx
. (-m64
è implicito)
In breve, voglio eseguire un lungo calcolo su 4 vettori 3D di galleggianti confezionati. Ciò richiede registri 4x3 = 12 xmm o ymm per la memorizzazione e 2 o 3 registri per risultati temporanei. Ciò dovrebbe adattarsi a IMHO nei 16 registri SSE (o AVX) disponibili per obiettivi a 64 bit. Tuttavia, GCC produce un codice molto non ottimale con riversazioni di registro, utilizzando solo i registri xmm0-xmm10
e mescolare dati da e sullo stack. La mia domanda è:
C'è un modo per convincere il GCC a utilizzare tutti i registri xmm0-xmm15
?
Per correggere le idee, considerare il seguente codice SSE (solo per illustrazione):
void example(vect<__m128> q1, vect<__m128> q2, vect<__m128>& a1, vect<__m128>& a2) {
for (int i=0; i < 10; i++) {
vect<__m128> v = q2 - q1;
a1 += v;
// a2 -= v;
q2 *= _mm_set1_ps(2.);
}
}
Qui vect<__m128>
è semplicemente un struct
di 3 __m128
, con aggiunta naturale e moltiplicazione per scalare. Quando la linea a2 -= v
è commentato, cioè abbiamo bisogno di solo registri 3x3 per l'archiviazione poiché stiamo ignorando a2
, il codice prodotto è davvero semplice senza mosse, tutto viene eseguito nei registri xmm0-xmm10
. Quando rimuovo il commento a2 -= v
, il codice è piuttosto terribile con un sacco di mescolamento tra registri e stack. Anche se il compilatore potrebbe semplicemente usare i registri xmm11-xmm13
o qualcosa.
In realtà non ho visto GCC utilizzare nessuno dei registri xmm11-xmm15
ovunque nel mio codice ancora. Che cosa sto facendo di sbagliato? Capisco che sono registri salvati da Callee, ma questo sovraccarico è completamente giustificato semplificando il codice Loop.
Nessuna soluzione corretta