Breve nota sobre “simplicidade”

Quando você coloca as mãos em dispositivos simples como o Arduino, se dá conta de que está mal acostumado com a massiva quantidade de memória a sua disposição e grandes velocidades de processamento, no PC. Num desktop, hoje, posso dispor da precisão em cálculos em ponto flutuante que me convier. Se 23 bits de mantissa não são suficientes, uso 51… se preciso de ainda mais, uso 63. Posso até usar bibliotecas de multiprecisão e usar quantos bits me der na telha, até um valor grande o suficiente onde a performance não seja um problema.

Tenho acesso a 8 “núcleos” de processamento paralelo, sem contar com 300 streams na minha placa de vídeo… Posso armazenar, permanentemente, uns 600 GB de dados (o espaço que tenho disponível no meu segundo HD, atualmente). E por ai vai…

O projeto Controlduino, além de ser uma pequena aventura intelectual, é também o meu jeito de te mostrar que mesmo projetos “simples” podem ficar bastante complexos, desde que você se atenha aos detalhes e faça um bom planejamento (não fiz um tão bom assim!). Eis uma outra consideração a respeito de cálculos em ponto flutuante que me veio à mente depois que escrevi o último artigo — onde falo sobre os erros de integração…

Será que é uma boa idéia simplificar a equação abaixo?

area(y_n\dots y_{n-2},dx)=\frac{y_n+y_{n+1}}{2} \delta x + \frac{y_n - 2y_{n-1}+y_{y-2}}{48} \delta x

O detalhe aqui é que multiplicações e divisões por 2, mesmo em ponto flutuante, são bem rápidas… Dividir por dois, um valor normalizado, é somente questão de decrementar o expoente em uma unidade, e multiplicar, incrementá-lo. As únicas operações que gastarão bastante tempo são as adições, subtrações e divisão por 48.

Acima temos 3 multiplicações (uma delas por 2 — e, ok, eu sei que dá para usar apenas uma multiplicação por δx. ao invés de duas!), 2 divisões (uma delas por 2), 3 adições e uma subtração. Na simplificação:

area(y_n\dots y_{n-2},dx)=\frac{25y_n - 26y_{n-1}+y_{y-2}}{48} \delta x

Temos 3 multiplicações, uma divisão, uma subtração e uma adição. São menos operações, mas as multiplicações e divisões por valores arbitrários, diferentes de 2, obriga às funções aritméticas a gastarem mais tempo.

As duas contas são equivalentes… fazem a mesma coisa e dão o mesmo resultado (a segunda veio da primeira), mas pode ser que a equação simplificada seja mais lenta! Somente depois de codificá-las e compará-las, ciclo a ciclo, poderei tomar uma decisão… E para fazer isso tenho que comparar também as rotinas de multiplicação e divisão da libm (que são grandes)…

Vale aqui a famosa frase de H. L. Mencken: Para todo problema complexo existe uma solução simples, óbvia… e errada.

Deixe um comentário