Espero que ninguém use Java pra trigonometria :shock:
Benchmarks de Linguagens
16 Respostas
Olá
Muito bom seu post. Vem corroborar algumas reclamações que tenho colocado em alguns de meus posts. Como engenheiro não me conformo que a minha linguagem favorita seja tão fraquinha para cálculos matemáticos.
Dentro do próprio processador Intel há um coprocessador aritmético com funções trigonométricas e exponenciais. Nos meus tempos de Clipper escrevi bibliotecas em asm x86/x87 que permitiam fazer o Clipper resolver problemas matemáticos e estatísticos de forma rápida. Não sei porque a Sun não contrata um escovador de bits para escrever funções que usem nativamente o coprocessador (e também as extensões MMX). Provavelmente é isto que faz com que o C# seja mais rápido do que o Java nas funções trigonométricas.
Sei que o Java já melhorou muito desde a versão 1.02 que comecei usando em 96/97. Mas seu post mostra que ainda há necessidade de melhorar.
[]s
Luca
Você mesmo já deu o motivo pelo qual a Sun não faz isso!! 8)
Você disse processador Intel!! O Java não foi feito para rodar apenas em Intel!
MMX idem…isso é uma tecnologia proprietária da Intel também.
Como engenheiro não me conformo que a minha linguagem favorita seja tão fraquinha para cálculos matemáticos.
Use Fortran,Haskell…pra isso.
E a portabilidade vai pro c# mesmo!(e eu não quis dizer C#)
Mas seria interessante ter uma biblioteca a parte só pra isso não?(ou uma especificação,apesar de achar q java não é pra isso…)
Olá
A linguagem Java é multi plataforma mas a JVM não. Há uma JVM para cada ambiente. A JVM feita para plataforma CISC Intel DEVERIA usar o coprocessador Intel (ou AMD e outros). A JVM para RISC deveria usar tudo de bom do RISC, assim por diante.
Não nos serve a solução de reinventar a roda e escrever funções matemáticas usando as instruções de 80 bits do coprocessador. Veja um pouco do que falo em: http://webster.cs.ucr.edu/Page_AoALinux/HTML/RealArithmetic.html O motivo é que as poucas instruções de acesso a métodos nativos disponibilizadas para nós no JNI são limitadas e lentas. Além disso troca de dados mataria mais um pouco as vantagens obtidas na escovação de bits.
Iron,
Java é tão mais moderno que Fortran que não tem sentido misturar os 2. Sei que alguns usam C/C++ para processamento científico, mas eu gostaria de reescrever alguns sistemas científicos em Java.
Não conheço nada em Haskell, muito menos sistemas científicos profissionais.
[]s
Luca
E dai? As JVMs do Windows, do Linux e do FreeBSD foram feita pra rodar em Intel (ou Intel-like, incluindo aqui AMD, Transmeta, e todos os outros clones, se eh que ainda existe mais algum). Que elas rodem bem no processador que vc deu pra ela, entao, ueh! 
Java é tão mais moderno que Fortran que não tem sentido misturar os 2. Sei que alguns usam C/C++ para processamento científico, mas eu gostaria de reescrever alguns sistemas científicos em Java.
Luca,se eh para levar em conta a especificação de cada VM,deveria primeiro haver uma modificação dos tipos!(Em Haskell soh para comparar,o tipo Inteiro é infinito,ele estoura quando sua CPU pedir água!)
A Stack default teria q ser enorme…
Mas esse uso é tão restrito,q não seria melhor manipular as instruções diretamente de cada CPU?(fazer uma sublinguagem…) jah viu a quantidade d barramentos q existem?São muitos fatores q devem ser levados em conta…não é soh pegar um escovador de bytes profissional e botar pra escrever uma especificação…
Olá
-
Dei uma olhada na tal de Haskell. Já usei algumas linguagens deste tipo. Não creio que sirva para escrever um sistema que resolve milhares de equações com várias iterações de uma análise não linear e ainda seja capaz de apresentar os dados em gráficos, base de dados e relatórios.
-
Já usei Fortran em várias máquinas completamente diferentes tais como IBM, Burroughs, ControlData, Honeywell Bull e DEC. O tamanho das palavras as vezes era bem diferente. O que acontecia é que uma poderia ser um pouco mais precisa do que a outra, mas o funcionamento da linguagem era o mesmo.
-
O uso dos registradores de 80 bits só é possível enquanto está executando as instruções dentro do coprocessador. O que é feito é mover os dados dos segmentos de dados e registradores normais x86 para aqueles x87, fazer as contas de um seno, cosseno, etc. e depois retornar aos registradores e segmentos de dados normais. Não muda absolutamente nada no formato dos tipos doubles (e floats). Detalhe: se a CPU não precisar dos dados naquele instante dentro do coprocessador, ela pode processar em paralelo com o coprocssador. É um avião mesmo!
O melhor realmente seria a Sun fazer com que seus métodos nativos usarem o que há de melhor em cada arquitetura de hardware.
[]s
Luca
Olá
Iron, preciso complementar minha resposta sobre algo que você disse.
Gostaria de lembrar que o Java no início era uma porcaria para fazer I/O. Muitos métodos e até mesmo algumas classes que você hoje usa com fluência só apareceram com o j2sdk 1.2. As classes InetAddress, sockets e cia. só apareceram no j2sdk 1.1. Em outras palavras Java parecia que não foi feito para I/O.
Java foi melhorando o I/O mas ainda não tinha muitas coisas comuns em outras linguagens como lock de arquivo, arquivos mapeados na memória, manipulação de arquivos sequenciais de modo não bloqueado (nonblocking mode streams) e o select/pool do C para Unix. Mesmo assim foram desenvolvidas muitas aplicações servidoras bases do J2EE.
Hoje com java.nio falta muito pouco para o Java ganhar um 10 em I/O. Bem que a Sun podia dar uma ajeitada nas APIs matemáticas dos doubles que não é tão dificil. As bibliotecas que eu fiz há 10 anos atrás para o Clipper não me tomaram uma semana entre estudo, codificação, testes e documentação.
E se me permite vou mais além. Porque a Sun não compra o projetinho rxtx? Daria uma ajeitada e consertaria de vez o bugento e limitado javax.comm. Assim acessaríamos com Java e sem bugs todos os periféricos seriais, paralelos, USB, etc. Não me diga que Java não é para isto porque há muita gente usando e tentando usar Java nos ERPs.
[]s
Luca
Não me diga que Java não é para isto porque há muita gente usando e tentando usar Java nos ERPs.
Não acho q seja uma boa idéia tentar levar java para o meio científico!Continuo dizendo q cada caso é um caso!Concordo com vc que é necessário melhorar certas API´s(Como javax.comm e uma nova GUI api tb!),dar uma remexida nos tipos(e seus limites),mas são features q jah existem na especificação e o negócio é aprimorá-las mesmo.Vc (q eh engenheiro) deve saber o quão difícil é representar números fracionários em binário,pois são impossíveis de se representar com precisão.Se a Sun for dar atenção a esse tipo de coisa,esbarraria em muitas especificações e diferentes máquinas…mais vms,mais vms,mais erros…
Seria necessário uma J2ScDK(Java2 Scientific Development Kit) para cada máquina…quer queira ou não,a computação científica torna a linguagem dependente do hard(coisas q C respondem bem a isso),fica difícil de padronizar d+!Talvez para suas necessidades,algumas poucas modificações na Api bastariam,mas para muitos,as modificações seriam avassaladoras. 
Olá
Desculpe insistir mas representar números de ponto flutuante em binário com precisão suficiente para cálculos matemáticos ja é um problema perfeitamente resolvido há mais de 30 anos. Como também são bem antigas as técnicas de avaliar os erros de precisão causados pela impossibilidade de representar exatamente todas as frações.
Mas de todo modo há a JSR 84 sobre Floating Point Extensions:
[color=“blue”]
This JSR proposes extensions to the Java Programming Language and Java Virtual Machine that support more efficient execution of floating point code.
. . . .
2.3 What need of the Java community will be addressed by the proposed specification?
The proposal will enable Java programs to achieve competitive floating point performance by taking advantage of the hardware of various widespread microprocessors and better code generator restructuring.
[/color]
Um bom link sobre o assunto Java Numerics: http://math.nist.gov/javanumerics/
[]s
Luca
E porque não desenvolver plug-ins pro SDK trabalhar com coisas cientificas e desenvolver um plug-in pra JVM?
Ainda bem, ainda bem que java tem a performance numérica pobre!
Espero que nunca venha a ter performance topo-de-linha nessa area.
Mas eu explico o por que disso.
Quando estamos falando de computação científica performance não é a maior das preocupações, bem antes dela vem precisão e determinismo, isso nenhuma opção mais veloz que java oferece.
Determinismo:
Erros devem ser facilmente detectaveis, java tem verificação a acesso de objetos e arrays obrigatorio, isso torna erros clássicos de overflow impossiveis de ocorrer.
Precisão:
Diferente das maiorias das linguagens onde precisão e funcionamento correto são despresados em note de otimizações do compilador, java possui regras muito explicitas sobre o comportamento da unidade de FP da JVM.
Performance não importa muito quando voce tem que ficar naquela masturbação com as flags e extensões do compilador.
Mesmo assim java ta ganhando muito espaço nessa area por providenciar um ambiente muito mais prático e confiavel, e isso é inevitavel, basta analisarmos o crecimento da performance dos grandes clusters.
Nos últimos 10 anos os cluster se tornaram 500x mais rápidos, enquanto os processadores não chegam a 20x. Ou seja, o futuro está nos clusters, em grid computing. Eu tenho confiança que qualquer aposta nessa area que não seja java vai perder.
Uma aplicação escrita usando java em modo strictfp vai possui o exato mesmo comportamento em qualquer arquitetura. Conseguir isso com C, fortran, clipper, assembly é muito, muito mais dificil.
Luca, uma nota sobre a implementação na JVM da Sun de FP. Todas funções de Math e StrictMath recebem um tratamento especial e o jitter faz inline delas emitindo direto instruções x87, assim como para todas operações com float e double. A performance não é muito boa dado o fato que otimizações comuns, como as envolvendo identidades matemáticas, causam perda de precisão numérica alem da permitida pela especificação, um exemplo é float b = a * 2;, isso não pode ser traduzido para float b = a + a; ou float b = a << 1; dado q os resultados serão diferentes!
Não Luca,Não estão resolvidos.A explicação do Louds foi ótima,mas há algumas coisas a considerar…
A precisão depende para qual finalidade será seu programa.Se vc quer um programinha de pgto de contas de caixa de padaria,2 casas decimais,bastam.Agora,se vc faz estudos de mapeamento de genes e proteômica(ciência q estuda a função das proteínas q compõe os genes),a coisa pega.No estudo da genômica,o DNA já traz todas as informações das cadeias polipeptíticas-estrutura primária das proteínas,e nos aminoácidos as 4 bases q o compõe são conhecidas(adenina,citosina…),Vc viu o tempinho q os micros da Celera Genomics demoraram para mapear tão pouca coisa?No Proteoma(conjunto de proteínas de um organismo)há dezenas de bases e sujeitas a alterações químicas!Os proteomas são diversos, cada tecido do corpo tem um proteoma diferente, ou seja, não há um único genoma. O proteoma varia muito de tecido para tecido, de pessoa para pessoa, de condição para condição.Se o Cv ou o Louds Tomam umas 10 latinhas de Guiness,ocorrerão mudanças q alterarão a saúde do seu fígado(Cv,vc ainda tem isso?) e isso alterará seus proteomas.Aliás,um simples remédio o fará.O que quero dizer é q a Proteômica é dinâmico!As soluções citadas são falhas e,no momento,todas as máquinas do mundo trabalhando em conjunto demorariam milhares de anos para mapear o proteoma de um único indivíduo.A precisão dos fp é muuuito imprecisa ainda.Eu tô falando de milhões de casas decimais de precisão,não dezenas.Vc estaria mais perto disso em C do q em Java-atualmente-.(Essa é a solução-momentânea-q eles usaram para o Genoma humano,agora usam Perl Tb).E o determinismo infelizmente é tão distante quanto o PC Quântico…por enquanto.Amanhã tudo pode mudar. 
Olá
Iron e Louds, obrigado pelo prazer de dialogar com gente inteligente. Devo agradecer também a oportunidade de dedicar alguns minutos do meu raciocínio as questões de análise numérica, cálculo numérico e analise real que já foram uma das minhas paixões e praticamente o motivo porque me dediquei à informática.
Iron,
Sou engenheiro estrutural UFRJ/70, COPPE/72. Pouco ou nada sei de genoma que é palavra que nem existia quando sai do mestrado. Mas gostei muito da parte que fala em tomar umas 10 latinhas de Guiness.
Minhas necessidades consistiam em apenas resolver no computador problemas de engenharia estrutural usando elementos finitos. Se acreditasse que computador não servia para cálculos nem teria me apaixonado por informática. Antes de participar do desenvolvimento de ERPs ou agência de bancos, fiz muitas aplicações de cálculo e desenho nas áreas de CAD e CAE (Computer Aided Design e Computer Aided Engineering) por mais de 15 anos.
Resolver sistemas de mais de 1000 equações no PC já é feito desde os tempos do 286. Tudo que o PC nos fornece é suficiente para cálculos com precisão completamente de acordo com as suposições feitas na modelagem do problema. No cálculo científico não importa ter um valor com muitos algarismos significativos se não podemos ter certeza que a discretização do problema é realmente exata.
Um dia procure saber como se calculou a ponte Rio Niterói ou a cúpula da usina nuclear de Angra dos Reis. É interessante saber como os engenheiros estruturais da COPPE ajudaram o Brasil a se tornar líder na tecnologia de prospecção de petróleo em águas profundas com nossos engenheiros estruturais (e outras especialidades) sendo reconhecidos em todo o mundo. Uma dica: em nenhum destes cálculos foram usadas técnicas de cálculos matemáticos exatos e sim técnicas de análise e cálculo numérico aproximado.
Louds,
a) Determinismo:
Um sistema em Fortran ou C TRAVA quando ocorre um overflow. Portanto nenhum sistema científico pode permitir um overflow. As técnicas de manipulação de grandezas de ponto flutuante em qualquer linguagem exigem em todos os cálculos verificações nos números para ver se estão dentro da faixa esperada. Nada é comparado com zero e sim com um valor muito pequeno compatível com o erro admitido. Portanto não seria necessário mudar o Java para fornecer exceções de overflow.
b) Precisão
As otimizações normais dos compiladores não alteram a precisão dos cálculos. Algumas opções especiais impróprias para matemática que os manuais alertavam claramente podiam realmente afetar os cálculos. Para estas 2 frases me baseio apenas no que lembro de C até o Microsoft C 6.0. Segundo recordo vagamente, o Microsoft C 5.1 não tinha tantas opções agressivas. Os Fortrans que usei não tinham opções de otimização que alterassem precisão a menos das opções de usar ou não os co-processadores 80x87. O uso do 80x87 aumenta a precisão dos cálculos intermediários feitos dentro do processador com 80 bits, mas os resultados são truncados quando se volta aos 64 bits normais.
c) Performance:
Tudo neste tópico começou aqui. Pelo que diz o artigo ainda falta um pouco para o Java igualar outras linguagens em alguns tipos de cálculos.
d) Clusters:
Realmente este é um caminho. Já em 1983/84 a grande moda era o paralelismo. Os congressos de engenharia estrutural recebiam muitos papers nesta área. Aqui em SP e na COPPE/RJ os caras pegavam um PC comum com processador 8088 e colocavam mais outro processador Intel i860. Assim construiam máquinas “caseiras” com 2 processadores e resolviam sistemas com muita rapidez apesar da limitação do equipamento. Portanto na área de cálculo estrutural as técnicas de análise numérica são antigas. O segredo é o mesmo daquele dos coprocessadores: dividir os trabalhos de modo que um dos processadores possa prosseguir sem precisar esperar pelo resultado do outro. Para isto o sistema de equações precisa ser montado de forma muito especial.
e) strictfp
Há várias décadas atrás o IEEE reuniu grandes especialistas para discutir as representações numéricas de ponto flutuante e publicou uma padronização. Algumas linguagens a adotaram como C e Fortran. O Java custou um pouco e ainda parece um pouco renitente. O Clipper era do tipo p-code, na verdade era um pré-compilador que convertia tudo para C. Porém C com opção de NÃO usar o co-processador 80x87 que pelos idos dos 8088,80286 pouca gente tinha. O assembler sempre foi difícil usar ponto flutuante, geralmente só era usado para acelerar pequenos trechos de código. Nunca vi um sistema inteiro em assembler para cálculo estrutural.
f) uso do 80x87 pelos jitters
Nada posso afirmar sobre isto e acredito em você. Apenas especulo que não deve estar sendo feito o melhor uso porque senão os resultados do benchmark do artigo não seriam tão diferentes das outras linguagens compiladas ou não.
[]s
Luca
Eu nunca disse q não servia!Mas isso é limitado…vc sabe,quanto mais se usa,mais se necessita!Os parâmetros usados hj já não dão conta de uma série de coisas,não importa de qual plataforma ou base de cálculo vc esteja falando,isso é uma verdade!Imagina agora q um certo lunático disse q o homem agora tem data para pousar em Marte… :roll:
No cálculo científico não importa ter um valor com muitos algarismos significativos se não podemos ter certeza que a discretização do problema é realmente exata.
Isso q vc falou eh válido,mas continuo a dizer q depende da necessidade…(e o tipo de parâmetros q serão usados)
Conheço um eng Civil(Dário) q me deu umas aulas de cálculo q participou do projeto!
Estude um pouquinho sobre treliças, resistência dos materias, mecânica dos fluidos e bastante cálculo que talvez voce até construa uma ponte algum dia 