Pergunta

Sabemos que os compiladores ficando melhor e melhor optimização do código e torná-lo correr mais rápido, mas a minha pergunta existem compiladores que podem otimizar operações de ponto flutuante para garantir maior precisão.

Por exemplo, uma regra básica é a de realizar multiplicações antes disso, isto porque a multiplicação e a divisão, utilizando números de ponto flutuante não introduzir imprecisões tão grande como a de adição e subtração, mas pode aumentar a magnitude das imprecisões introduzidas pela adição e subtração, por isso deve ser feito primeiro em muitos casos.

Assim, uma operação de ponto flutuante, como

y = x*(a + b); // faster but less accurate

Deve ser alterado para

y = x*a + x*b; // slower but more accurate

Existem compiladores que irá optimizar para a melhoria de ponto flutuante de precisão em detrimento da velocidade, como mostrei acima?Ou é a principal preocupação dos compiladores de velocidade com limite de olhar a precisão de operações de ponto flutuante?

Obrigado

Atualização:A resposta selecionada, mostrou um bom exemplo onde este tipo de otimização não funcionam, então ele não seria possível para o compilador sabe de antemão qual é a maneira mais precisa para avaliar y.Graças para o contra-exemplo.

Foi útil?

Solução

A sua premissa está com defeito. x*(a + b), é, em geral, menos precisos do que x*a + x*b.Na verdade, é, muitas vezes, ser mais precisos, porque ele executa apenas duas operações de ponto flutuante (e, portanto, incorre em apenas dois erros de arredondamento), enquanto a segunda realiza três operações.

Se você sabe algo sobre a distribuição esperada de valores para x, a, e b a priori, então você poderia fazer uma decisão informada, mas compiladores quase nunca têm acesso a esse tipo de informação.

Deixando isso de lado, que se a pessoa que escreve o programa, na verdade, significava x*(a+b) e, especificamente, queria exatamente arredondamentos que são causadas por que determinada sequência de operações?Esse tipo de coisa é bem comum na alta qualidade algoritmos numéricos.

Melhor fazer o que o programador escreveu, não o que você acha que ele poderia ter concebido.

Edição -- Um exemplo para ilustrar um caso em que a transformação que você sugeriu que resulta em uma perda catastrófica de precisão:suponha que

x = 3.1415926535897931
a = 1.0e15
b = -(1.0e15 - 1.0)

Em seguida, a avaliação em double temos:

x*(a + b) = 3.1415926535897931

mas

x*a + x*b = 3.0

Outras dicas

Os compiladores normalmente "otimizam" para precisão sobre a velocidade, precisão definida como implementação exata do padrão IEEE 754. Enquanto as operações inteiras podem ser reordenadas de qualquer maneira que não cause excesso, as operações de FP precisam ser executadas exatamente como o programador especifica. Isso pode sacrificar a precisão numérica (os compiladores c comuns não estão equipados para otimizar para isso), mas implementa fielmente o que o programador pediu.

Um programador que tem certeza de que não otimizou manualmente para precisão pode permitir recursos do compilador como o GCC's -funsafe-math-optimizations e -ffinite-math-only Para extrair velocidade extra. Mas geralmente não há muito ganho.

Não, não há.Stephen Canon dá algumas boas razões para que isso seria uma ideia estúpida, e ele está correto;assim, você não encontrará um compilador que faz isso.

Se você, como programador ter algum conhecimento sobre os intervalos de números que você está manipulando, você pode usar parênteses, variáveis temporárias e construções similares fortemente a sugestão de que o compilador sobre como você quer que as coisas sejam feitas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top