Eu quero desenvolver um software de computação científica paralelo do zero. Eu quero alguns pensamentos sobre qual idioma começar. O programa envolve ler / gravar dados em arquivos txt e realizar cálculos pesados em paralelo, com muitas fatorações de LU e o uso de solucionadores lineares esparsos. As soluções candidatas que eu estava pensando são Fortran 2003/2008 com OpenMP ou co-array, C ++ com openmp cilk + ou TBB, python. Quaisquer outras sugestões documentadas são bem-vindas! Eu sei muito bem C, Fortran e Java (nessa ordem). Eu fiz alguns scripts em python, mas coisas básicas.
Eu sei que o fortran é muito rápido, mas difícil de manter e paralelizar. Diz-se que C ++ é lento, a menos que você use bibliotecas externas, etc. Eu gosto de Python, mas é realista escrever um software em escala industrial em escala completa?
O software precisa ser capaz de lidar com grandes quantidades de dados e ser eficaz com cálculos científicos. O desempenho é essencial.
Como pano de fundo, eu já tenho um software de trabalho escrito em Fortran. Muitas pessoas estiveram envolvidas no desenvolvimento ao longo de muitos anos e o código está realmente sujo. Manter e paralelizar o código provou ser um pesadelo e estou pensando em alternativas.
Petros
Respostas:
Deixe-me tentar detalhar seus requisitos:
Nesta lista, eu consideraria os seguintes idiomas:
C, C ++, Fortran, Python, MATLAB, Java
Julia é um novo idioma promissor, mas a comunidade ainda está se formando em torno dele e não foi implantada em nenhum dos principais códigos novos.
Leitura / gravação de dados de texto
É fácil acertar em qualquer linguagem de programação. Verifique se você está armazenando o buffer e coalescendo adequadamente seu acesso de E / S e obterá um bom desempenho de qualquer um dos idiomas que você deve considerar. Evite os objetos de fluxo no C ++, a menos que você saiba como usá-los com desempenho.
Interfaces / capacidade fortes para fatorações de LU
Se você estiver executando fatorações densas de LU, convém usar LAPACK ou ScaLAPACK / Elemental para funcionalidade paralela. LAPACK e ScaLAPACK são escritos em Fortran, Elemental é escrito em C ++. Todas as três bibliotecas têm desempenho, são bem suportadas e documentadas. Você pode fazer interface com eles a partir de qualquer um dos idiomas que você deve considerar.
Solucionadores lineares esparsos
Os principais solucionadores lineares esparsos disponíveis gratuitamente estão quase todos disponíveis no PETSc , escrito em C, que é bem documentado e suportado. Você pode fazer interface com o PETSc a partir de qualquer um dos idiomas que você deve considerar.
Desempenho e escalabilidade para grandes dados
Os únicos paradigmas de programação paralela mencionados são baseados em memória compartilhada, o que significa que você não está considerando uma abordagem de computação de memória distribuída baseada em MPI (passagem de mensagem). De acordo com minha experiência, é muito mais fácil escrever código que vai muito além de uma dúzia de núcleos usando uma solução de memória distribuída. Quase todos os "agrupamentos" de universidades são baseados em MPI atualmente, grandes máquinas de memória compartilhada são caras e, correspondentemente, raras. Você deve considerar o MPI para sua abordagem, mas meu conselho será aplicado independentemente do paradigma de programação que você escolher.
Com relação ao desempenho no nó, se você estiver escrevendo rotinas numéricas, é mais fácil obter um bom desempenho serial no Fortran. Se você tem um pouco de experiência em C, C ++ ou Python, pode obter um desempenho muito comparável (C e C ++ são inoperantes mesmo com Fortran, Python e MATLAB dentro de uma sobrecarga de cerca de 25% do tempo sem muito esforço). O MATLAB faz isso através de um compilador JIT e muito boa expressividade em álgebra linear. Você provavelmente precisará usar kernels numéricos Cython, numpy, numexpr ou incorporar para obter o desempenho reivindicado do Python. Não posso comentar sobre o desempenho do Java, porque não conheço muito bem a linguagem, mas desconfio que ela não esteja muito longe da linguagem do Python se escrita por um especialista.
Uma nota sobre interfaces
Espero ter convencido você de que você poderá fazer tudo o que quiser em qualquer uma das linguagens de programação que estiver considerando. Se você estiver usando Java, as interfaces C serão um pouco desafiadoras. O Python possui excelente suporte à interface C e Fortran por meio de ctypes, Cython e f2py. O LAPACK já está empacotado e disponível através do scipy. O MATLAB possui toda a funcionalidade necessária em suas bibliotecas nativas, mas não é facilmente escalável ou particularmente fácil de executar em clusters. Java pode suportar interfaces C e Fortran com o JNI , mas não é comumente encontrado em clusters e em software paralelo para computação científica.
Manutenção
Muito disso vai se resumir ao gosto pessoal, mas o consenso geral sobre manutenção é que você deseja minimizar o número de linhas de código em seu software, escrever código modular com interfaces bem definidas e, para o software computacional, fornecer testes que verificam a correção e a funcionalidade da implementação.
Recomendação
Eu , pessoalmente, tive muita sorte com Python e eu recomendo para muitos projetos computacionais. Eu acho que você deve considerá-lo fortemente para o seu projeto. Python e MATLAB são provavelmente as línguas mais expressivas disponíveis para a computação científica. Você pode facilmente conectar o Python a qualquer outra linguagem de programação, pode usar o f2py para encapsular sua implementação atual do Fortran e reescrever peça por peça, independentemente das peças que você deseja no Python enquanto verifica se está mantendo a funcionalidade. No momento, eu recomendaria uma combinação da implementação oficial do Python 2.7 com o scipy . Você pode começar muito facilmente com essa pilha na distribuição gratuita do Enthought Python .
Você também pode fazer a maior parte disso em C, C ++ ou Fortran. C e C ++ são linguagens muito atraentes para desenvolvedores profissionais com muita experiência, mas frequentemente viajam para novos desenvolvedores e, nesse sentido, provavelmente não são uma ótima idéia para um código mais acadêmico. Fortran e MATLAB são populares na computação acadêmica, mas são fracos nas estruturas avançadas de dados e na expressividade que o Python oferece (pense em um objeto de ditado do Python, por exemplo).
Perguntas relacionadas:
fonte
Além da resposta muito abrangente de Aron, eu daria uma olhada nos vários tópicos do scicomp.stackexchange que tratavam da questão de qual linguagem de programação tomar - tanto em relação à velocidade dos programas quanto à questão de quão fácil ou difícil é escrever e manter software nesses idiomas.
Dito isto, além do que foi escrito lá, deixe-me fazer algumas observações:
(i) Você inclui o co-array Fortran em sua lista. Que eu saiba, o número de compiladores que realmente o suportam é muito pequeno - e, na verdade, sou zero. O compilador Fortran mais amplamente disponível é o GNU gfortran e, embora as fontes de desenvolvimento atuais analisem um subconjunto de co-matrizes, acredito que ele não suporta nada disso (ou seja, aceita a sintaxe, mas não implementa nenhuma semântica) . Obviamente, essa é uma observação geral sobre os novos padrões do Fortran: que o atraso com o qual os compiladores realmente suportam novos padrões é medido em vários anos - os compiladores implementaram o Fortran 2003 apenas completamente nos últimos dois anos e suportam apenas parcialmente o Fortran 2008. Isso não deve impedi-lo de usar nada, se você tiver um compilador que suporte o que você usa,
(ii) O mesmo certamente acontece com C ++ / Cilk +: Sim, a Intel está desenvolvendo isso em uma filial do GCC, mas não está disponível em nenhuma das versões do GCC e, provavelmente, não será por um tempo. Você pode esperar mais dois ou três anos, pelo menos, até encontrar o Cilk + com as versões do GCC instaladas em máquinas linux típicas.
(iii) C ++ / TBB é uma história diferente: o TBB existe há algum tempo, possui uma interface muito estável e é compilável com a maioria dos compiladores C ++ existentes nos últimos anos (tanto no Linux quanto no Windows) . Nós o usamos em deal.II há vários anos, com bons resultados. Há também um livro muito bom sobre isso.
(iv) Tenho minha própria opinião sobre o OpenMP, a saber, que é uma solução em busca de um problema. Funciona bem para paralelizar os loops internos, o que pode ser interessante se você tiver estruturas de dados muito regulares. Mas raramente é o que você quer fazer se precisar paralelizar algo - porque o que você realmente deseja fazer é paralelizar os loops externos . E, para isso, soluções como o TBB são soluções muito melhores porque usam os mecanismos da linguagem de programação em vez de tentar descrever o que acontece fora da linguagem (via #pragmas) e de maneira que você não tenha acesso aos identificadores de encadeamento , indicadores de status do resultado etc., de dentro do seu programa.
(v) Se você é experimental, também pode dar uma olhada nas novas linguagens de programação projetadas para programação paralela e, em particular, para tarefas como as que você descreve. Existem essencialmente dois que eu daria uma olhada: X10 e Chapel . Eu já vi bons tutoriais no Chapel, e parece bem desenhado, embora ambos, hoje em dia, sejam soluções insulares também.
fonte
Geralmente, se você é realmente sério sobre esse projeto de software, sugiro uma reescrita completa em qualquer idioma em que você se sinta mais confortável. Parece que você fará o trabalho sozinho e, portanto, obterá os melhores resultados no idioma em que se sentir mais à vontade.
Mais especificamente, porém, em relação ao paralelismo, eu o incentivaria a tentar pensar um pouco fora da caixa. O OpenMP tem seus pontos fortes, mas está preso em uma mentalidade de pegar um código seqüencial e colocar um paralelismo aqui e ali. O mesmo vale, em essência, para a Intels TBB.
Cilk é definitivamente um passo na direção certa, ou seja, força você a repensar seu problema / solução em uma configuração inerentemente paralela. O que eu não gosto sobre isso, porém, é que é outra língua . Além disso, como apenas pode inferir relações entre tarefas paralelas, o agendador pode ser bastante conservador e pode não ter boa escala para determinados problemas.
A boa notícia é que, novamente, se você é sério sobre sua implementação, pode fazer o que o Cilk faz; por exemplo, reescreva seu problema como um conjunto de tarefas interdependentes e distribua-os por vários processadores / núcleos, tudo por conta própria, usando pthreads ou mau uso do OpenMP para gerar processos. Um bom exemplo de como isso pode ser feito é o planejador QUARK usado na biblioteca PLASMA . Uma boa comparação de seu desempenho vs. Cilk é apresentada aqui .
fonte
pthreads-win32
dentro docygwin
projeto.Houve pouca discussão sobre o coarray fortran nos comentários acima. No momento, e para meu conhecimento limitado, o suporte a coarray nos compiladores é aproximadamente o seguinte:
Geralmente, eu teria cuidado ao iniciar um código baseado em coarray. A sintaxe é simples e muito mais conveniente que o Fortran / C / C ++ com MPI, mas não é tão completa. Por exemplo, o MPI suporta muitas operações de redução, etc., o que pode ser muito conveniente para você. Isso realmente dependeria da sua necessidade de muita comunicação. Se você quiser um exemplo, entre em contato e eu posso fornecer alguns, se eu puder desenterrar os arquivos.
fonte
Dê uma olhada no Spark, que é uma estrutura distribuída para cálculos na memória, que tira proveito da programação funcional. A estrutura de um programa no Spark é muito diferente quando comparada ao MPI. Basicamente, você escreve um código como para um único computador, que é automaticamente distribuído como funções aos dados localizados na memória. Ele suporta Scala, Java e Python.
Regressão logística (scala):
Existe uma extensão chamada MLib (biblioteca de aprendizado de máquina) que usa uma biblioteca Fortran para alguns cálculos de baixo nível (para Python, acho que o numpy é usado). Portanto, a ideia é simples, concentre-se no seu algoritmo e deixe as otimizações em níveis mais baixos (ordem de processamento, distribuição de dados etc.).
fonte