2015-08-14 3 views
14

Qualcuno sa perché GCC/Clang non ottimizzerà la funzione test1 nell'esempio di codice seguente per utilizzare semplicemente l'istruzione RCPPS quando si utilizza il fast- opzione matematica? C'è un altro flag del compilatore che genererebbe questo codice?Perché GCC o Clang non ottimizzano reciprocamente 1 istruzione quando si utilizza la matematica veloce

typedef float float4 __attribute__((vector_size(16))); 

float4 test1(float4 v) 
{ 
    return 1.0f/v; 
} 

Si può vedere l'output compilato qui: https://goo.gl/jXsqat

risposta

15

Poiché la precisione di RCPPS è un molto divisione inferiore float.

Un'opzione per abilitare quell'ottimizzazione non sarebbe appropriata come parte di -ffast-math.

Il x86 target options of the gcc manual dice che c'è, infatti, è un'opzione che (con -ffast-math) fa arrivare gcc usarli (con un'iterazione di Newton-Raphson):

  • -mrecip Questa opzione consente di utilizzare RCPSS e le istruzioni RSQRTSS (e le loro varianti vettorializzate RCPPS e RSQRTPS) con un ulteriore Newton-Raphson per aumentare la precisione invece di DIVSS e SQRTSS (e le loro varianti vettorializzate) per gli argomenti a virgola mobile a precisione singola. Queste istruzioni sono generate solo quando -funsafe-math-optimization è abilitato insieme a -finite-math-only e -fno-trapping-math. Si noti che mentre il throughput della sequenza è superiore al throughput dell'istruzione non reciproca, la precisione della sequenza può essere ridotta fino a 2 ulp (ovvero l'inverso di di 1,0 è uguale a 0,99999994).

    Nota che GCC implementa 1.0f/sqrtf (x) in termini di RSQRTSS (o RSQRTPS) già con -ffast-math (o la combinazione di opzioni precedente), e non ha bisogno di -mrecip.

    noti inoltre che GCC emette la sequenza sopra con ulteriore passo Newton-Raphson per vettorializzare divisione singolo galleggiante e sqrtf vettorializzare (x) già con -ffast-matematica (o alla suddetta combinazione di opzioni ), e no bisogno -mrecip.

  • -mrecip=opt

Questa opzione controlla quali possono essere utilizzati istruzioni stima reciproci. opt è un elenco separato da virgole di opzioni, che può essere preceduta da una per invertire l'opzione '!':!

’all’ 
     Enable all estimate instructions. 
‘default’ 
    Enable the default instructions, equivalent to -mrecip. 
‘none’ 
    Disable all estimate instructions, equivalent to -mno-recip. 
‘div’ 
    Enable the approximation for scalar division. 
‘vec-div’ 
    Enable the approximation for vectorized division. 
‘sqrt’ 
    Enable the approximation for scalar square root. 
‘vec-sqrt’ 
    Enable the approximation for vectorized square root. 

Così, per esempio, -mrecip = tutto, sqrt permette a tutti i approssimazioni reciproci , eccetto per la radice quadrata.

Si noti che il nuovo design Skylake di Intel further improves FP division performance, a 8-11 c di latenza, 1/3c throughput. (O uno per 5c velocità effettiva per vettori 256b, ma stessa latenza per vdivps). Hanno allargato i divisori, quindi AVX vdivps ymm ha ora la stessa latenza dei vettori 128b.

(Da SnB a Haswell ha fatto 256b div e sqrt con circa il doppio della latenza/velocità di ricezione, quindi hanno chiaramente solo divisori da 128b.) Skylake esegue anche pipeline di entrambe le operazioni, quindi circa 4 operazioni div possono essere in volo . sqrt è anche più veloce.

Quindi, in molti anni, una volta che Skylake è diffuso, vale la pena fare rcpps se è necessario dividere la stessa cosa più volte. rcpps e un paio fma potrebbero avere un throughput leggermente superiore ma una latenza peggiore. Inoltre, vdivps è solo un singolo utente; quindi saranno disponibili più risorse di esecuzione affinché le cose accadano contemporaneamente alla divisione.

Resta da vedere quale sarà l'implementazione iniziale di AVX512. Presumibilmente rcpps e un paio di FMA per le iterazioni di Newton-Raphson saranno una vittoria se le prestazioni della divisione FP sono un collo di bottiglia. Se la velocità effettiva è un collo di bottiglia e c'è molto lavoro da fare mentre le divisioni sono in volo, lo vdivps zmm probabilmente è ancora valido (a meno che lo stesso divisore non venga utilizzato ripetutamente, ovviamente).

+0

+1 Nice find sui numeri di latenza Skylake. Stavo aspettando che Agner Fog li pubblicasse, ma immagino che questo succederà fino a quel momento. – Mysticial

+0

@Mysticial: trovato in questa discussione RWT: http://www.realworldtech.com/forum/?threadid=151723&curpostid=151877. Vedere anche http://www.realworldtech.com/forum/?threadid=151723&curpostid=151724, http://www.realworldtech.com/forum/?threadid=151723&curpostid=152052 –

+1

I OCD'ed con quella tabella di latenza oggi. E sto arrivando alla conclusione che le porte 0 e 1 sono praticamente identiche per Skylake. Entrambi hanno una FPU a 4 cicli, un vettore int-add/shift a 1 ciclo, un vettore int-mul. Anche se non trovo alcuna prova che il divisore sia su entrambi o solo sulla porta 0. Vedremo la prossima settimana come io sia giusto/sbagliato. – Mysticial