Esistono molte sfide tecniche che rendono estremamente difficile la esatta riproducibilità bit per bit dei risultati computazionali.
A livello di software, le modifiche al codice o ad una qualsiasi delle librerie utilizzate dal codice possono ovviamente produrre risultati diversi. Saresti sorpreso dal numero di librerie di supporto che possono finire collegate in un tipico codice scientifico.
A un livello inferiore, anche la ricompilazione di uno dei codici o delle librerie utilizzate dal codice con un nuovo compilatore o con diverse ottimizzazioni del compilatore attivate può causare problemi. Uno dei motivi è che varie operazioni nel codice potrebbero essere eseguite in un ordine diverso quando il codice viene ricompilato. Poiché l'aggiunta in virgola mobile non è associativa (a + b) + c <> a + (b + c), ciò può dare risultati diversi.
OK, quindi se conserviamo l'intero ambiente software (sistema operativo, librerie e codice compilato) (ad es.) Masterizzandolo su un CD-ROM di avvio che eseguirà il codice. Ora possiamo essere sicuri che otterremo gli stessi risultati se eseguiamo questo codice su un altro computer?
Sorprendentemente, alcuni codici in realtà variano l'ordine dei calcoli in base agli aspetti del particolare modello di processore su cui sono in esecuzione. Ad esempio, le librerie di algebra lineare ottimizzata in genere interrompono le moltiplicazioni di matrici per lavorare su blocchi che si adattano alla cache. Quando Intel rilascia un nuovo microprocessore con una cache più grande, il codice potrebbe regolare dinamicamente la dimensione del blocco, determinando un'aritmetica che viene eseguita in un ordine diverso e dando risultati diversi. Altri codici regolano dinamicamente l'ordine dei calcoli in base alla quantità di memoria disponibile, se si esegue il codice su un computer con più memoria che potrebbe causare l'aritmetica in un ordine diverso e quindi dare risultati diversi.
Le cose diventano incredibilmente più complicate quando si inserisce il codice multithread, poiché l'esatta cronologia di esecuzione dei diversi thread è spesso non deterministica e ciò può nuovamente comportare l'esecuzione di operazioni aritmetiche in un ordine diverso da una corsa all'altra.
In pratica, il massimo che puoi davvero sperare sono risultati simili da una macchina all'altra, fino alle tolleranze di precisione degli algoritmi utilizzati. ad esempio, se ho un problema di ricerca della radice e utilizzo la bisection per ottenere una radice entro + -1,0e-10, allora dovrei essere felice finché macchine diverse stanno producendo risposte che concordano con quella tolleranza.