2014-04-07 13 views
45

Basta leggere questo fascinating article sui rallentamenti 20x-200x che è possibile ottenere su CPU Intel con float denormalizzati (numeri in virgola mobile molto vicini a 0).Come vengono gestiti i floals denormalizzati in C#?

Esiste un'opzione con SSE per arrotondare a 0, ripristinando le prestazioni quando si verificano tali valori in virgola mobile.

Come gestiscono le app C#? C'è un'opzione per abilitare/disabilitare _MM_FLUSH_ZERO?

+23

Non penso che sia una domanda tecnica sciocca. – user1717828

risposta

43

Non esiste questa opzione.

La parola di controllo FPU in un'app C# viene inizializzata dal CLR all'avvio. La modifica non è un'opzione fornita dal framework. Anche se provi a cambiarlo con il pinzettante _control87_2(), non durerà a lungo; qualsiasi eccezione causerà il reset della parola di controllo dall'implementazione della gestione delle eccezioni all'interno del CLR. Che è stato scritto per trattare un altro aspetto della parola di controllo della FPU, consente di smascherare le eccezioni a virgola mobile. Sarà inoltre dannoso per qualsiasi altro codice gestito che non si aspetti che lo stato globale venga modificato in questo modo.

Non avere un controllo diretto sull'hardware è una restrizione implicita quando si esegue il codice in una macchina virtuale. Non è affatto facile farlo anche nel codice nativo, le librerie tendono a comportarsi male quando anche loro si aspettano che l'FPU abbia l'inizializzazione predefinita. In particolare un problema con i flag di mascheramento delle eccezioni, le DLL create con gli strumenti Borland hanno un'abilità per attivare le eccezioni, facendo fallire altro codice che non è stato scritto per gestire un'eccezione del genere. Un problema estremamente brutto da risolvere, la parola di controllo FPU è la peggiore variabile globale che si possa immaginare.

Questo ti porta il peso di non lasciare che i tuoi calcoli in virgola mobile vadano in tilt in questo modo. Il calcolo con i denormali produce quasi sempre risultati senza senso, se non da valori radicalmente piccoli, quindi almeno dalla rapida perdita di cifre significative. Troncare valori inferiori a 2.2E-308 a 0 dipende da te. Sì, non molto pratico. Forse va bene che un programma fornisca risultati senza senso un po 'più lenti del normale :)

+0

Mentre acconsento completamente alla tua risposta che non si può fare, mi preoccupo della banalizzazione del problema. Troncare i doppi può essere raro; ma è terribilmente facile denormalizzare Singles quando si esegue l'elaborazione audio (ad esempio filtri digitali, linee di ritardo, & c). Dato che il successo delle prestazioni è orripilante per l'architettura x86, sarebbe terribilmente bello richiedere il lancio di eccezioni di denorm.Scalars ha controllato le operazioni. Perché non galleggia anche tu? –

+1

Pinvoking _control87_2() non è un problema quando il codice è localizzato in questo modo. Utilizza _DN_FLUSH, non dimenticare di reimpostarlo. –

Problemi correlati