2014-10-09 26 views
7

Osservo che i compilatori generano codice che indirizza i registri SIMD ogni volta che viene utilizzata l'aritmetica double. Questo vale per il codice non ottimizzato e ottimizzato. Questo significa che l'unità x87 FP può essere considerata obsoleta e presente solo per compatibilità con le versioni precedenti?Lo stack FP x87 è ancora rilevante?

Ho anche notato che altre piattaforme "popolari" si basano anche sulle rispettive implementazioni SIMD anziché su FP come stack.

Anche le implementazioni SIMD tendono ad essere di almeno 128 bit di larghezza, quindi mi chiedo se ciò significhi che la precisione (interna) delle operazioni è superiore a quella dell'unità x87 FP?

Mi interesso anche di prestazioni, velocità e latenza, considerando che SIMD è stato concepito pensando all'esecuzione del vettore, quindi mi chiedo come facciano con gli scalari.

+0

In realtà la FPU può essere più precisa, poiché SIMD memorizza più valori in quei bit, attualmente supporta i doppi a 64 bit e i float a 32 bit. Esistono anche istruzioni scalari SSE. Tuttavia, FPU ha alcune funzioni che SSE non ha. – Jester

+0

@Jester - si suppone che le unità SIMD non utilizzino i 128 bit completi per memorizzare il valore singolo? E che invece viene trattato come un 'double' pieno e ha solo 64 bit? –

+0

E 'saldamente sulla lista delle specie in codice a rischio. Tutti hanno preso il cambio di rottura nei loro generatori di codice a 64 bit. I 3 grandi tutti sono passati. Ci sono alcuni ritardatari in giro, ad esempio il jitter .NET a 32 bit. A tempo debito possiamo chiamare il disastro FPU 80-bit una lontana brutta memoria. –

risposta

11

Anche le implementazioni SIMD tendono ad essere di almeno 128 bit di ampiezza, quindi mi chiedo se ciò significhi che la precisione (interna) delle operazioni è superiore a quella dell'unità x87 FP?

La larghezza di un registro SIMD non è la larghezza di un singolo componente del vettore che rappresenta. I set di istruzioni SIMD ampiamente disponibili offrono al massimo il formato binario64 IEEE 754 (larghezza 64 bit). Questo non è quasi buono come il formato storico a 80 bit esteso per precisione o intervallo.

Molti compilatori C rendono disponibile il formato a 80 bit come tipo long double. Lo uso spesso. È utile per la maggior parte dei calcoli intermedi: il suo utilizzo contribuisce a rendere il risultato finale più accurato anche se il risultato finale è destinato a essere restituito come binario64 double. Un esempio è la funzione in this question, per la quale una proprietà matematicamente intuitiva detiene il risultato finale se i calcoli intermedi vengono eseguiti con long double, ma non se i calcoli intermedi vengono eseguiti con lo stesso tipo double come input e output.

Analogamente, tra molti vincoli che dovevano essere ottenuta nella scelta dei parametri per il formato esteso 80-bit, una considerazione è che è ideale per compute una funzione binary64 pow() componendo 80 bit expl() e logl(). La precisione extra è necessaria per ottenere una buona precisione per il risultato finale.

Devo notare, tuttavia, che quando i calcoli "intermedi" sono una singola operazione di base, è meglio non passare attraverso una precisione estesa. In altre parole, quando x e sono di tipo double, la precisione di (double)(x * (long double)y) è leggermente inferiore alla precisione di x * y. Le due espressioni producono quasi sempre gli stessi risultati e nei rari casi in cui differiscono, x * y è leggermente più preciso. Questo fenomeno è chiamato double-rounding.

+0

Quindi non esiste una rappresentazione in virgola mobile a 128 bit da utilizzare nelle unità SIMD? –

+0

ad es. il "formato a virgola mobile binario a precisione quadrupla IEEE 754" –

+1

@ user3735658 Nella maggior parte dei set di istruzioni SIMD a 128 bit, un "registro a 128 bit" rappresenta due 'binary64' o quattro' binary32' e non può mai essere usato per uno singolo valore 'binary128'. –