La maggior parte dei problemi di calcolo scientifico che è necessario risolvere implementando un particolare algoritmo in C/C++ richiede un'accuratezza molto inferiore alla doppia precisione. Ad esempio, 1e-6
, 1e-7
la precisione copre 99%
dei casi per i risolutori ODE o l'integrazione numerica. Anche nei rari casi in cui abbiamo bisogno di maggiore accuratezza, di solito il metodo numerico fallisce prima di poter sognare di raggiungere un'accuratezza vicina alla doppia precisione. Esempio: non possiamo aspettarci un'accuratezza 1e-16 da un semplice metodo Runge-Kutta anche quando si risolve un'equazione differenziale ordinaria normale del nostiff a causa di errori di arrotondamento. In questo caso, il requisito della doppia precisione è analogo a quello di chiedere una migliore approssimazione della risposta sbagliata.Ottimizzazioni a virgola mobile - linea guida
Quindi, l'ottimizzazione aggressiva del punto di viraggio sembra essere una situazione vantaggiosa per tutti, in quanto rende il codice più veloce (molto più veloce!) E non influisce sulla precisione di destinazione del problema specifico. Detto questo, sembra notevole difficile assicurarsi che una particolare implementazione/codice sia stabile contro le ottimizzazioni fp. Esempio classico (e alquanto inquietante): GSL, la biblioteca scientifica GNU, non è solo la libreria numerica standard sul mercato, ma è anche una libreria molto ben scritta (non riesco a immaginare di fare un lavoro migliore). Tuttavia, GSL non è stabile contro le ottimizzazioni fp. Infatti, se si compila GSL con il compilatore intel, ad esempio, i test interni non avranno esito positivo a meno che non si attivi il flag -fp-model strict
che disattiva le ottimizzazioni fp.
Quindi, la mia domanda è: ci sono linee guida generali per scrivere codice che sia stabile contro le ottimizzazioni in virgola mobile aggressive. Sono queste le linee guida linguistiche (compilatore) specifiche. In tal caso, quali sono le best practice C/C++ (gcc/icc)?
Nota 1: questa domanda non chiede quali sono i flag di ottimizzazione fp in gcc/icc.
Nota 2: questa domanda non si pone in merito alle linee guida generali per l'ottimizzazione di C/C++ (come non utilizzare le funzioni virtuali per le funzioni di piccole dimensioni chiamate molto).
Nota 3: questa domanda non richiede l'elenco delle ottimizzazioni fp più standard (come x/x -> 1).
Nota 4: Credo fermamente che questa NON sia una domanda soggettiva/fuori tema simile al classico "The Coolest Server Names". Se non sei d'accordo (perché non sto fornendo un esempio/codice/problema concreto), segnalalo come wiki della comunità. Sono molto più interessato alla risposta che ad ottenere alcuni punti di stato (non sono importanti - ottieni il punto!).
Gli errori si accumulano - anche se tutti i calcoli eseguiti a doppia precisione, il risultato finale non sarà preciso fino all'ultimo bit, lontano da esso. Se si utilizza float ovunque, è necessario eseguire una corretta analisi degli errori per capire quanti bit della risposta sono affidabili (se ce ne sono). Dovresti fare la stessa cosa per il doppio, ovviamente. –
La stabilità numerica generale è spesso ottenuta tramite passaggi intermedi scelti con cura e per lo più fragili, specificamente progettati per superare il carattere non associativo dell'aritmetica a virgola mobile a precisione finita. Ottimizzazioni aggressive tendono a rompersi, ad es. cambiando l'ordine di esecuzione. La regolazione iterativa potrebbe aiutare, ma poi ci vuole più tempo per ottenere la risposta. Suggerimento: potresti voler pubblicare la tua domanda sul sito [Computational Science] (http://scicomp.stackexchange.com/). –