Eu tenho um modelo considerável (~ 5000 linhas) escrito em C. É um programa serial, sem geração de números aleatórios em nenhum lugar. Utiliza a biblioteca FFTW para funções que utilizam a FFT - não conheço os detalhes da implementação da FFTW, mas presumo que as funções nela também sejam determinísticas (corrija-me se estiver errado).
O problema que não consigo entender é que estou obtendo pequenas diferenças nos resultados para execuções idênticas na mesma máquina (mesmo compilador, mesmas bibliotecas).
Uso variáveis de precisão dupla e, para gerar o resultado em variável, value
por exemplo, emito:
fprintf(outFID, "%.15e\n", value);
ou
fwrite(&value, 1, sizeof(double), outFID);
E eu constantemente
obtinha diferenças como: 2.07843469652206 4 e-16 vs. 2.07843469652206 3 e-16
Passei muito tempo tentando descobrir por que isso acontece. Inicialmente, pensei que um dos meus chips de memória estava com defeito e os encomendei e substituí, sem sucesso. Posteriormente, também tentei executar meu código na máquina Linux de um colega e obtive diferenças da mesma natureza.
O que poderia estar causando isso? É uma questão pequena agora, mas me pergunto se é a "ponta do iceberg" (de um problema sério).
Eu pensei em publicar aqui em vez do StackOverflow, caso alguém que trabalhe com modelos numéricos possa ter encontrado esse problema. Se alguém puder esclarecer isso, eu ficaria muito grato.
Seguimento dos comentários:
Christian Clason e Vikram: primeiro, obrigado por sua atenção à minha pergunta. Os artigos que você vinculou sugerem que: 1. erros de arredondamento limitam a precisão e 2. código diferente (como a introdução de declarações de impressão aparentemente inofensivas) pode afetar os resultados até o epsilon da máquina. Devo esclarecer que não estou comparando os efeitos fwrite
e fprintf
funções. Eu estou usando um OU o outro. Em particular, o mesmo executável é usado para ambas as execuções. Estou simplesmente afirmando que o problema ocorre se eu uso fprintf
OU fwrite
.
Portanto, o caminho do código (e executável) é o mesmo e o hardware é o mesmo. Com todos esses fatores externos mantidos constantes, de onde vem a aleatoriedade, fundamentalmente? Suspeitei que o bit flip ocorreu devido a uma falha na memória que não estava retendo um pouco corretamente, e foi por isso que substituí os chips de memória, mas esse não parece ser o problema aqui, verifiquei e você indicou. Meu programa gera milhares desses números de precisão dupla em uma única execução, e sempre há um punhado aleatório com inversões aleatórias de bits.
Seguimento do primeiro comentário de Christian Clason: Por que igual a 0 na precisão da máquina? O menor número positivo para um duplo é 2,22e-308, então não deveria ser igual a 0? Meu programa gera milhares de valores na faixa de 10 ^ -16 (variando de 1e-15 a 8e-17) e temos observado variações significativas em nosso projeto de pesquisa, por isso espero que não tenhamos analisado coisas sem sentido. números.
Acompanhamento # 2 :
Este é um gráfico da série temporal produzida pelo modelo, para ajudar na discussão dos comentários nos comentários.