O Fortran é mais fácil de otimizar que o C para cálculos pesados?


410

De tempos em tempos, leio que o Fortran é ou pode ser mais rápido que o C para cálculos pesados. Isso é mesmo verdade? Devo admitir que mal conheço o Fortran, mas o código do Fortran que vi até agora não mostrou que a linguagem possui recursos que C não possui.

Se for verdade, por favor me diga o porquê. Por favor, não me diga quais idiomas ou bibliotecas são bons para o processamento de números, não pretendo escrever um aplicativo ou lib para fazer isso, apenas estou curioso.


53
Não é realmente subjetivo das respostas dadas abaixo. O título correto é "Existem razões arquitetônicas fundamentais pelas quais um compilador Fortran PODE produzir um código otimizado melhor que um compilador C", mas isso é apenas uma escolha.
Martin Beckett

3
A questão do título não é tão subjetiva, é um mal-entendido, eu acho. A questão mais detalhada não é subjetiva.
Jfm3 28/09/08

1
Eu acho que ninguém aprenderia muito com isso, além da resposta ser "Sim" e "Não" ao mesmo tempo, e variar de acordo com o compilador, a fonte, a CPU, o layout da memória, etc, etc. Bocejo.
User7116 28/09/08

1
Não acho que a pergunta ou as respostas sejam subjetivas. Mas se você acha que essa bandeira ajuda alguém, eu estou bem com isso.
quinmars 28/09/08

2
@sixlettervariables Embora você e eu já saibamos a resposta, é uma pergunta que ocorre para a maioria das pessoas no início de suas carreiras e é importante entender a resposta. Em vez de postar um comentário desdenhoso, por que não encontrar uma resposta com a qual você concorde e dê +1 #
MarkJ

Respostas:


447

Os idiomas têm conjuntos de recursos semelhantes. A diferença de desempenho vem do fato de que Fortran diz que o aliasing não é permitido, a menos que uma instrução EQUIVALENCE seja usada. Qualquer código com alias não é Fortran válido, mas cabe ao programador e não ao compilador detectar esses erros. Assim, os compiladores Fortran ignoram possíveis aliases de ponteiros de memória e permitem gerar código mais eficiente. Veja este pequeno exemplo em C:

void transform (float *output, float const * input, float const * matrix, int *n)
{
    int i;
    for (i=0; i<*n; i++)
    {
        float x = input[i*2+0];
        float y = input[i*2+1];
        output[i*2+0] = matrix[0] * x + matrix[1] * y;
        output[i*2+1] = matrix[2] * x + matrix[3] * y;
    }
}

Essa função seria mais lenta que a do Fortran após a otimização. Por quê então? Se você escrever valores na matriz de saída, poderá alterar os valores da matriz. Afinal, os ponteiros podem se sobrepor e apontar para o mesmo pedaço de memória (incluindo o intponteiro!). O compilador C é forçado a recarregar os quatro valores da matriz da memória para todos os cálculos.

No Fortran, o compilador pode carregar os valores da matriz uma vez e armazená-los nos registros. Isso pode ser feito porque o compilador Fortran assume que ponteiros / matrizes não se sobrepõem na memória.

Felizmente, a restrictpalavra-chave e o apelido estrito foram introduzidos no padrão C99 para solucionar esse problema. Também é bem suportado na maioria dos compiladores C ++ atualmente. A palavra-chave permite que você dê ao compilador uma dica de que o programador promete que um ponteiro não faz alias com nenhum outro ponteiro. O aliasing estrito significa que o programador promete que ponteiros de tipos diferentes nunca se sobrepõem, por exemplo, a double*não se sobrepõe a um int*(com a exceção específica de que char*e void*pode se sobrepor a qualquer coisa).

Se você usá-los, obterá a mesma velocidade do C e do Fortran. No entanto, a capacidade de usar a restrictpalavra - chave apenas com funções críticas de desempenho significa que os programas C (e C ++) são muito mais seguros e fáceis de escrever. Por exemplo, considere o código Fortran inválido:, CALL TRANSFORM(A(1, 30), A(2, 31), A(3, 32), 30)que a maioria dos compiladores Fortran compila alegremente sem nenhum aviso, mas introduz um bug que só aparece em alguns compiladores, em algum hardware e com algumas opções de otimização.


26
Tudo verdadeiro e válido, jeff. No entanto, não considero o interruptor "assumir nenhum aliasing" seguro. Ele pode quebrar o código herdado de outros projetos de maneiras tão sutis que eu prefiro não usá-lo. Eu me tornei um-nazi restringir, por essa razão :-)
Nils Pipenbrinck

3
Para o meu segundo ponto, você não precisa usar a opção de compilador sem alias. Basta escrever o código para que as cargas baseadas no ponteiro sejam atribuídas a uma variável automática primeiro e depois trabalhe com a automação a partir daí. Ele parecerá mais detalhado, mas otimizará perfeitamente o compilador.
Alto Jeff

33
Um bom exemplo é a mera existência de memcpy () vs. memmove (). Diferentemente de memcpy (), memmove () lida com áreas sobrepostas, portanto, memcpy () pode ser mais rápido que o memmove (). Esse problema foi motivo suficiente para alguém incluir duas funções em vez de uma na biblioteca padrão.
jfs

12
Eu acho que esse foi o ponto de Sebastian - devido à complexidade / flexibilidade do manuseio de memória C, até algo tão simples quanto mover memória é complicado.
Martin Beckett

3
Seu call transformexemplo não tem muito sentido.
Vladimir F

163

Sim, em 1980; Em 2008? depende

Quando comecei a programar profissionalmente, o domínio da velocidade do Fortran estava sendo desafiado. Lembro-me de ler sobre isso no Dr. Dobbs e contar aos programadores mais velhos sobre o artigo - eles riram.

Então, eu tenho duas visões sobre isso, teóricas e práticas. Em teoria, o Fortran hoje não possui vantagem intrínseca ao C / C ++ ou mesmo a qualquer linguagem que permita código de montagem. Na prática, o Fortran hoje ainda desfruta dos benefícios do legado de uma história e cultura construídas em torno da otimização do código numérico.

Até o Fortran 77, inclusive, as considerações sobre o design da linguagem tinham como foco principal a otimização. Devido ao estado da teoria e da tecnologia do compilador, isso geralmente significava restringir recursos e capacidades para fornecer ao compilador a melhor chance de otimizar o código. Uma boa analogia é pensar no Fortran 77 como um carro de corrida profissional que sacrifica recursos por velocidade. Atualmente, os compiladores melhoraram em todos os idiomas e os recursos para a produtividade do programador são mais valorizados. No entanto, ainda existem lugares onde as pessoas estão preocupadas principalmente com a velocidade na computação científica; essas pessoas provavelmente herdaram código, treinamento e cultura de pessoas que eram programadoras do Fortran.

Quando se começa a falar sobre otimização de código, há muitos problemas e a melhor maneira de entender isso é espreitar onde as pessoas são cuja função é ter um código numérico rápido . Mas lembre-se de que esse código criticamente sensível é geralmente uma pequena fração das linhas gerais de código e muito especializado: muitos códigos do Fortran são tão "ineficientes" quanto muitos outros códigos em outros idiomas e a otimização nem deve ser uma preocupação principal desse código .

Um lugar maravilhoso para começar a aprender sobre a história e a cultura de Fortran é a wikipedia. A entrada da Fortran na Wikipedia é excelente e eu aprecio muito aqueles que dedicaram tempo e esforço para torná-la valiosa para a comunidade Fortran.

(Uma versão abreviada desta resposta teria sido um comentário no excelente tópico iniciado por Nils, mas eu não tenho o karma para fazer isso. Na verdade, eu provavelmente não teria escrito nada, exceto pelo fato de esse tópico ter conteúdo e compartilhamento de informações, em oposição às guerras de fogo e fanatismo linguístico, que é minha principal experiência com esse assunto. Fiquei impressionado e tive que compartilhar o amor.)


1
o link: web.archive.org/web/20090401205830/http://ubiety.uwaterloo.ca/… não funciona mais. Existe um link alternativo?
Nathanielng

64

Até certo ponto, o Fortran foi projetado tendo em mente a otimização do compilador. A linguagem suporta operações de matriz inteira, onde os compiladores podem explorar o paralelismo (especialmente em processadores com vários núcleos). Por exemplo,

A multiplicação densa de matrizes é simplesmente:

matmul(a,b)

A norma L2 de um vetor x é:

sqrt(sum(x**2))

Além disso declarações tais como FORALL, PUREe ELEMENTALprocedimentos etc. ajuda adicional para optimizar código. Até ponteiros no Fortran não são tão flexíveis quanto C por esse motivo simples.

O próximo padrão Fortran (2008) possui co-matrizes que permitem escrever facilmente código paralelo. O G95 (código aberto) e os compiladores do CRAY já o suportam.

Portanto, sim, o Fortran pode ser rápido simplesmente porque os compiladores podem otimizar / paralelizar melhor que o C / C ++. Mas, novamente, como tudo na vida, existem bons e maus compiladores.



1
A forallconstrução foi preterida porque os compiladores não puderam otimizar bem o código. A substituição é do concurrent. Além disso, o código sqrt(sum(x**2))parece ineficiente, porque o compilador provavelmente constrói o vetor inteiro x**2. Eu acho que um loop é melhor, mas é sem dúvida melhor chamar a norm2função intrínseca .
A. Hennink 9/08

39

É engraçado que muitas respostas aqui não sejam do conhecimento dos idiomas. Isso é especialmente verdadeiro para programadores de C / C ++ que abriram e codificaram o código FORTRAN 77 e discutiram os pontos fracos.

Suponho que o problema da velocidade seja principalmente uma questão entre C / C ++ e Fortran. Em um código Enorme, sempre depende do programador. Existem alguns recursos da linguagem que o Fortran supera e outros que o C faz. Então, em 2011, ninguém pode realmente dizer qual é o mais rápido.

Sobre o idioma em si, o Fortran atualmente suporta os recursos Full OOP e é totalmente compatível com versões anteriores. Eu usei o Fortran 2003 completamente e diria que foi delicioso usá-lo. Em alguns aspectos, o Fortran 2003 ainda está atrás do C ++, mas vejamos o uso. O Fortran é usado principalmente para computação numérica e ninguém usa recursos sofisticados de C ++ OOP por motivos de velocidade. Na computação de alto desempenho, o C ++ quase não tem para onde ir (dê uma olhada no padrão MPI e você verá que o C ++ foi descontinuado!).

Atualmente, você pode simplesmente fazer programação em linguagem mista com Fortran e C / C ++. Existem até interfaces para GTK + no Fortran. Existem compiladores gratuitos (gfortran, g95) e muitos excelentes comerciais.


8
Você poderia adicionar uma fonte, experiência específica ou um instituto científico / agência de computação de alto desempenho que esteja se afastando do C ++ para projetos futuros ou reescrevendo projetos c ++ para outro idioma. Só estou perguntando porque conheço pelo menos duas instituições científicas, Sandia e CERN, que usam muito o c ++ para modelagem de alto desempenho. Além disso, Sandia converteu um de seus softwares de modelagem (LAMMPS) do fortran para c ++, adicionando uma série de aprimoramentos impressionantes.
Zachary Kraus

7
O LAMMPS é escrito em C ++ extremamente simples, que não tira proveito da maioria dos recursos modernos da linguagem. Representa o C ++ que os programadores do Fortran que conhecem C escrevem depois de aprender C ++ 98. Isso não quer dizer que o LAMMPS esteja mal escrito, apenas que não é o exemplo que você deseja citar ao defender o C ++ no HPC.
Jeff

30

Existem várias razões pelas quais o Fortran pode ser mais rápido. No entanto, a quantidade que eles importam é tão inconseqüente ou pode ser contornada de qualquer maneira, que não deve importar. O principal motivo para usar o Fortran atualmente é manter ou estender aplicativos herdados.

  • Palavras-chave PURE e ELEMENTAL nas funções. Estas são funções que não têm efeitos colaterais. Isso permite otimizações em certos casos em que o compilador sabe que a mesma função será chamada com os mesmos valores. Nota: O GCC implementa "puro" como uma extensão do idioma. Outros compiladores também podem. A análise entre módulos também pode executar essa otimização, mas é difícil.

  • conjunto padrão de funções que lidam com matrizes, não com elementos individuais. Coisas como sin (), log (), sqrt () recebem matrizes em vez de escalares. Isso facilita a otimização da rotina. A vetorização automática oferece os mesmos benefícios na maioria dos casos, se essas funções estiverem embutidas ou embutidas

  • Tipo complexo embutido. Em teoria, isso pode permitir que o compilador reordene ou elimine certas instruções em certos casos, mas provavelmente você verá o mesmo benefício com a estrutura {double re, im; }; idioma usado em C. Ele facilita o desenvolvimento, embora os operadores trabalhem em tipos complexos no fortran.


1
"mas provavelmente você verá o mesmo benefício com o { double re, im; };idioma struct usado em C". Os compiladores C provavelmente retornarão essa estrutura no formato sret, com a pilha de chamadas alocando espaço, passando um ponteiro para o receptor que o preenche. Isso é várias vezes mais lento que o retorno de vários valores nos registradores, como faria um compilador Fortran. Observe que C99 corrigiu isso no caso especial de complexo.
quer

Não sei se concordo com o seu principal motivo. Pessoalmente, gosto de usar o fortran para códigos pesados ​​de matemática, onde matrizes e funções matemáticas são a parte mais importante do código. Mas sei que, em muitas instituições e bancos governamentais, eles continuam usando o fortran para manter ou estender o código legado. Eu pessoalmente usei o fortran para estender o código de um professor no meu Ph.D. o comitê escreveu.
Zachary Kraus

Sua declaração, "o principal motivo para usar o Fortran hoje em dia é manter ou estender aplicativos herdados", está completamente errada. Ainda não vi nenhuma outra linguagem de programação nem remotamente próxima dos recursos que o Fortran fornece, especialmente para aplicativos matemáticos. Você já nomeou alguns deles, como excelente suporte a array, aritmética complexa interna, funções puras ou elementares - e eu também poderia citar mais. Isso por si só é suficiente para provar que sua afirmação acima está errada.
Pap

28

Eu acho que o ponto chave a favor do Fortran é que é uma linguagem um pouco mais adequada para expressar matemática baseada em vetores e em array. O problema de análise de ponteiro apontado acima é real na prática, pois o código portátil não pode realmente assumir que você pode dizer algo ao compilador. SEMPRE existe uma vantagem em expressar computaitons de uma maneira mais próxima da aparência do domínio. C realmente não tem matrizes, se você olhar de perto, apenas algo que se comporta como esse. Fortran tem arrawys reais. O que facilita a compilação para certos tipos de algoritmos, especialmente para máquinas paralelas.

No fundo, em coisas como sistema de tempo de execução e convenções de chamada, C e o Fortran moderno são suficientemente semelhantes, tornando difícil ver o que faria a diferença. Observe que C aqui é realmente base C: C ++ é um problema totalmente diferente, com características de desempenho muito diferentes.


25

Não existe um idioma que seja mais rápido que outro, então a resposta correta é não .

O que você realmente precisa perguntar é "o código é compilado com o compilador Fortran X mais rápido que o código equivalente compilado com o compilador C Y?" A resposta para essa pergunta depende, é claro, de quais dois compiladores você escolhe.

Outra pergunta que se poderia fazer seria a seguinte: "Dado o mesmo esforço envidado na otimização de seus compiladores, qual compilador produziria código mais rápido?" A resposta para isso seria de fato Fortran . Os compiladores Fortran têm vantagens certian:

  • O Fortran teve que competir com a Assembly no dia em que alguns juraram nunca usar compiladores, por isso foi projetado para oferecer velocidade. C foi projetado para ser flexível.
  • O nicho de Fortran tem sido o processamento de números. Nesse código de domínio nunca é rápido o suficiente. Portanto, sempre houve muita pressão para manter a linguagem eficiente.
  • A maior parte da pesquisa em otimizações de compiladores é feita por pessoas interessadas em acelerar o código de processamento de números do Fortran; portanto, a otimização do código do Fortran é um problema muito mais conhecido do que a otimização de qualquer outra linguagem compilada, e novas inovações aparecem primeiro nos compiladores do Fortran.
  • Biggie : C incentiva muito mais uso de ponteiro do que o Fortran. Isso aumenta drasticamente o escopo potencial de qualquer item de dados em um programa C, o que os torna muito mais difíceis de otimizar. Observe que Ada também é muito melhor que C neste domínio e é uma linguagem OO muito mais moderna do que o Fortran77 comumente encontrado. Se você deseja um idioma OO que possa gerar código mais rápido que C, essa é uma opção para você.
  • Devido novamente ao seu nicho de processamento de números, os clientes dos compiladores Fortran tendem a se preocupar mais com a otimização do que os clientes dos compiladores C.

No entanto, não há nada que impeça alguém de dedicar muito esforço à otimização do compilador C e faça com que ele gere um código melhor que o compilador Fortran da plataforma. De fato, as vendas maiores geradas pelos compiladores C tornam esse cenário bastante viável


4
Concordo. E devo acrescentar que, quando o Fortran foi introduzido (foi a primeira linguagem de alto nível) no final dos anos 50, início dos anos 60, muitos ficaram céticos quanto à eficiência que poderia ser. Portanto, seus desenvolvedores tiveram que provar que o Fortran poderia ser eficiente e útil e começar a "otimizá-lo até a morte" apenas para provar seu argumento. C veio muito mais tarde (entre meados dos anos 70) e não tinha nada a provar, por assim dizer. Mas, a essa altura, muito código Fortran já havia sido escrito, de modo que a comunidade científica se manteve firme e ainda o faz. Não programo o Fortran, mas aprendi a criar um link para chamar sub-rotinas do Fortran em C ++.
Olumide

3
A pesquisa sobre otimização de compiladores foi mais diversificada do que você imagina. A história das implementações do LISP, por exemplo, é cheia de sucessos ao processar números mais rapidamente que o Fortran (que continua sendo o candidato padrão a ser desafiado). Além disso, grande parte da otimização do compilador tem como alvo representações intermediárias do compilador, o que significa que, além das diferenças na semântica (como alias), elas se aplicam a qualquer linguagem de programação de uma determinada classe.
Em nenhum lugar homem

2
A idéia se repete bastante, mas é um pouco falso dizer que não há consequências para a eficiência inerente a um design de linguagem de programação. Alguns recursos da linguagem de programação necessariamente levam a ineficiências, porque limitam as informações disponíveis no momento da compilação.
Praxeolitic

@Praxeolitic - Isso é bastante correto (é por isso que estou satisfeito por não ter dito isso).
TED

@TED ​​Honestamente, voltando aqui alguns meses depois, não tenho idéia do motivo pelo qual deixei esse comentário em sua resposta. Talvez eu quisesse deixá-lo em outro lugar? XP
Praxeolitic

22

Há outro item em que o Fortran é diferente de C - e potencialmente mais rápido. O Fortran possui regras de otimização melhores que C. No Fortran, a ordem de avaliação de uma expressão não está definida, o que permite ao compilador otimizá-la - se alguém deseja forçar uma determinada ordem, deve usar parênteses. Em C, a ordem é muito mais rigorosa, mas com as opções "-fast", elas são mais relaxadas e "(...)" também são ignoradas. Acho que Fortran tem um jeito que fica bem no meio. (Bem, o IEEE torna a vida mais difícil, pois certas alterações na ordem de avaliação exigem que não ocorram estouros, o que deve ser ignorado ou dificulta a avaliação).

Outra área de regras mais inteligentes são os números complexos. Não apenas que C 99 os levou até C 99, mas também as regras que os governam são melhores em Fortran; como a biblioteca Fortran do gfortran é parcialmente escrita em C, mas implementa a semântica do Fortran, o GCC ganhou a opção (que também pode ser usada com programas C "normais"):

-fcx-fortran-rules A multiplicação e a divisão complexas seguem as regras de Fortran. A redução do intervalo é feita como parte da divisão complexa, mas não há como verificar se o resultado de uma multiplicação ou divisão complexa é "NaN + I * NaN", com uma tentativa de resgatar a situação nesse caso.

As regras de alias mencionadas acima são outro bônus e também - pelo menos em princípio - as operações de toda a matriz, que se consideradas corretamente pelo otimizador do compilador, podem levar a códigos mais rápidos. Pelo contrário, certas operações demoram mais tempo; por exemplo, se alguém faz uma atribuição a um array alocável, são necessárias muitas verificações (realocar? [Recurso Fortran 2003], os avanços do array etc.), que tornam o operação simples mais complexa nos bastidores - e, portanto, mais lenta, mas torna a linguagem mais poderosa. Por outro lado, as operações de matriz com limites e avanços flexíveis facilitam a gravação de código - e o compilador geralmente otimiza melhor o código que um usuário.

No total, acho que C e Fortran são igualmente rápidos; a escolha deve ser mais de qual idioma se gosta mais ou se o uso das operações de todo o array do Fortran e sua melhor portabilidade são mais úteis - ou a melhor interface para as bibliotecas do sistema e da interface gráfica do usuário em C.


O que há para "resgatar" significativamente no caso Nan + INan? O que diferencia infinitos de NaN é que infinitos são assinados. Operações que envolvem infinidades não complexas que produziriam um sinal confuso resultam em NaN e não vejo razão para números complexos fazerem o contrário. Se multiplicarmos (DBL_MAX, DBL_MAX) por (2,2), elevar ao quadrado o resultado e depois o quadrado, qual deve ser o sinal do resultado na ausência de estouro? Em vez disso, o que é um multiplicado por (1.001, DBL_MAX)? Eu consideraria (NaN, NaN) a resposta correta e qualquer combinação de infinito e NaN como absurda.
precisa

14

Não há nada sobre os idiomas Fortran e C que torna um mais rápido que o outro para fins específicos. Há coisas sobre compiladores específicos para cada uma dessas linguagens que tornam algumas favoráveis ​​para determinadas tarefas mais do que outras.

Por muitos anos, existiram os compiladores Fortran que poderiam fazer magia negra em suas rotinas numéricas, tornando muitos cálculos importantes incrivelmente rápidos. Os compiladores C contemporâneos não conseguiram fazê-lo também. Como resultado, várias grandes bibliotecas de código cresceram no Fortran. Se você quiser usar essas bibliotecas bem testadas, maduras e maravilhosas, desmembrará o compilador Fortran.

Minhas observações informais mostram que hoje em dia as pessoas codificam seu material computacional pesado em qualquer idioma antigo e, se demorar um pouco, encontram tempo em algum cluster de computação barato. A Lei de Moore faz de todos nós tolos.


11
Quase modificado isso. O problema é que Fortran não tem algumas vantagens inerentes. No entanto, você está bastante correto de que o importante é olhar para o compier, não para o idioma.
TED

14

Comparo a velocidade do Fortran, C e C ++ com o clássico benchmark Levine-Callahan-Dongarra do netlib. A versão em vários idiomas, com o OpenMP, é http://sites.google.com/site/tprincesite/levine-callahan-dongarra-vectors OC é mais feio, pois começou com a tradução automática, além da inserção de restrições e pragmas para determinados compiladores. C ++ é apenas C com modelos STL, quando aplicável. Na minha opinião, o STL é um saco misto sobre se melhora a manutenção.

Há apenas um exercício mínimo de alinhamento automático de funções para ver em que medida melhora a otimização, uma vez que os exemplos são baseados na prática tradicional do Fortran, onde pouca confiança é depositada no alinhamento.

O compilador C / C ++, que é de longe o uso mais difundido, carece de auto-vetorização, na qual esses benchmarks dependem bastante.

Sobre o post que veio logo antes disso: existem alguns exemplos em que parênteses são usados ​​no Fortran para ditar a ordem de avaliação mais rápida ou precisa. Compiladores C conhecidos não têm opções para observar os parênteses sem desativar as otimizações mais importantes.


A tradução feia é necessária para superar o problema de alias. Você deve fornecer variáveis ​​simuladas ao compilador para informar que as variáveis ​​byref implementadas como ponteiros podem ser otimizadas para registro.
david

12

Sou programador amador e sou "mediano" nos dois idiomas. Acho mais fácil escrever código Fortran rápido do que código C (ou C ++). O Fortran e o C são linguagens "históricas" (atualmente padrão), são muito usadas e têm um compilador gratuito e comercial bem suportado.

Não sei se é um fato histórico, mas Fortran parece que foi construído para ser paralelo / distribuído / vetorizado / qualquer que seja o tamanho de muitos núcleos. E hoje é praticamente a "métrica padrão" quando falamos de velocidade: "ela escala?"

Para trituração pura da CPU, eu amo o Fortran. Para qualquer coisa relacionada a IO, acho mais fácil trabalhar com C. (é difícil nos dois casos).

Agora, é claro, para código intensivo de matemática paralela, você provavelmente deseja usar sua GPU. C e Fortran têm muitas interfaces CUDA / OpenCL mais ou menos bem integradas (e agora OpenACC).

Minha resposta moderadamente objetiva é: Se você conhece os dois idiomas igualmente bem / mal, acho que o Fortran é mais rápido, porque acho mais fácil escrever código paralelo / distribuído no Fortran do que C. não apenas código F77 estrito)

Aqui está uma segunda resposta para aqueles que desejam me rebaixar porque não gostam da primeira resposta: os dois idiomas têm os recursos necessários para escrever código de alto desempenho. Portanto, depende do algoritmo que você está implementando (intensivo em CPU, intensivo em io e intensivo em memória), o hardware (único núcleo? Multi-core? Distribui supercomputador? GPGPU? FPGA?), Sua habilidade e, finalmente, o próprio compilador. C e Fortran têm um compilador incrível. (Estou seriamente impressionado com o quão avançados são os compiladores Fortran, mas também os compiladores C).

PS: Fico feliz que você excluiu libs especificamente porque tenho muita coisa ruim a dizer sobre libs do Fortran GUI. :)


11

Eu estava fazendo matemática extensiva com FORTRAN e C por alguns anos. Pela minha própria experiência, posso dizer que o FORTRAN às vezes é realmente melhor que o C, mas não por sua velocidade (pode-se fazer o C executar tão rápido quanto o FORTRAN usando o estilo de codificação apropriado), mas por causa de bibliotecas muito bem otimizadas, como o LAPACK, e por causa de grande paralelização. Na minha opinião, o FORTRAN é realmente complicado de se trabalhar, e suas vantagens não são boas o suficiente para cancelar essa desvantagem, então agora estou usando o C + GSL para fazer cálculos.


10

Quaisquer diferenças de velocidade entre Fortran e C serão mais uma função das otimizações do compilador e da biblioteca matemática subjacente usada pelo compilador específico. Não há nada intrínseco ao Fortran que o tornaria mais rápido que o C.

De qualquer forma, um bom programador pode escrever o Fortran em qualquer idioma.


@ Scott Clawson: você recebeu -1'd e eu não sei por quê. Marcou com +1 para corrigir isso. No entanto, algo a ser levado em consideração é que o Fortran existe há mais tempo do que muitos de nossos pais. Tempo gasto otimizando a saída do compilador: D
user7116 28/09/08

Concordo. Acabei de postar uma resposta muito semelhante em paralelo.
226 Jeff alto

O problema de alias de ponteiro em C foi levantado por outros, mas existem vários métodos que o programador pode usar em compiladores modernos para lidar com isso, então eu ainda concordo.
Alto Jeff

1
@ Kluge: "Não há nada intrínseco ao Fortran que o torne mais rápido que o C". Aliasing de ponteiro, retornando valores compostos em registradores, construções numéricas de nível superior internas ...
Jon Harrop

9

Não ouvi dizer que Fortan é significativamente mais rápido que C, mas pode ser concebível que, em certos casos, seja mais rápido. E a chave não está nos recursos de linguagem que estão presentes, mas naqueles que (geralmente) estão ausentes.

Um exemplo são ponteiros C. Os ponteiros C são usados ​​praticamente em todos os lugares, mas o problema com os ponteiros é que o compilador geralmente não pode dizer se está apontando para as diferentes partes da mesma matriz.

Por exemplo, se você escreveu uma rotina strcpy parecida com esta:

strcpy(char *d, const char* s)
{
  while(*d++ = *s++);
}

O compilador deve trabalhar sob a suposição de que d e s possam estar sobrepondo matrizes. Portanto, não é possível executar uma otimização que produza resultados diferentes quando as matrizes se sobrepõem. Como seria de esperar, isso restringe consideravelmente o tipo de otimização que pode ser realizada.

[Devo observar que o C99 possui uma palavra-chave "restringir" que diz explicitamente aos compiladores que os ponteiros não se sobrepõem. Observe também que o Fortran também possui ponteiros, com semânticas diferentes das de C, mas os ponteiros não são onipresentes como em C.]

Mas voltando ao problema C vs. Fortran, é concebível que um compilador Fortran seja capaz de executar algumas otimizações que talvez não sejam possíveis para um programa C (escrito diretamente). Portanto, não ficaria muito surpreso com a afirmação. No entanto, espero que a diferença de desempenho não seja tão grande. [~ 5-10%]


9

Rápido e simples: ambos são igualmente rápidos, mas o Fortran é mais simples. O que é realmente mais rápido no final depende do algoritmo, mas não há diferença considerável de velocidade. Foi isso que aprendi em um workshop da Fortran no centro de computação de alto desempenho Stuttgard, na Alemanha, em 2015. Trabalho com Fortran e C e compartilho essa opinião.

Explicação:

C foi projetado para escrever sistemas operacionais. Portanto, ele tem mais liberdade do que o necessário para escrever código de alto desempenho. Em geral, isso não é problema, mas se não se programar com cuidado, pode-se facilmente atrasar o código.

O Fortran foi projetado para programação científica. Por esse motivo, ele suporta a escrita rápida de código em termos de sintaxe, pois esse é o principal objetivo do Fortran. Ao contrário da opinião pública, o Fortran não é uma linguagem de programação desatualizada. Seu último padrão é 2010 e novos compiladores são publicados regularmente, pois a maioria dos códigos de alto desempenho é gravada no Fortran. O Fortran também suporta recursos modernos como diretivas do compilador (em pragmas em C).

Exemplo: Queremos fornecer uma estrutura grande como argumento de entrada para uma função (fortran: sub-rotina). Dentro da função, o argumento não é alterado.

C suporta ambos, chamada por referência e chamada por valor, que é um recurso útil. No nosso caso, o programador pode, por acidente, usar chamada por valor. Isso torna as coisas consideravelmente mais lentas, pois a estrutura precisa ser copiada primeiro na memória.

Fortran trabalha apenas com chamada por referência, o que força o programador a copiar a estrutura manualmente, se ele realmente deseja uma operação de chamada por valor. No nosso caso, o fortran será automaticamente tão rápido quanto a versão C com chamada por referência.


Você pode escrever um aplicativo paralelo nativo em C (ou seja, sem chamar nenhuma biblioteca?). Não. Você pode escrever um aplicativo paralelo nativo no Fortran? Sim, de algumas maneiras diferentes. Portanto, Fortran é "mais rápido". Embora, para ser justo, em 2010, quando você escreveu seu comentário, o suporte a recursos paralelos de do-co-array do Fortran provavelmente não fosse tão difundido como agora.
Mali Remorker

@MaliRemorker Ele escreveu isso em 2016, não em 2010.
Kowalski

A sobrecarga de criação de processos paralelos não é, em minha opinião, o fator mais relevante para uma linguagem de programação denominada 'rápida'. Mais relevantes são considerações práticas, como uma paz de código sem desempenho. Portanto, não ajuda em nada se você economizar tempo uma vez (ao criar o processo paralelo) e gastá-lo em vários núcleos posteriormente. O termo 'rápido' também deve considerar códigos não paralelos. Por esse motivo, não vejo argumento contra meu argumento. Talvez seu comentário tenha sido uma resposta independente?
Markus Dutschke 28/03

8

Geralmente, o FORTRAN é mais lento que o C. C pode usar indicadores de nível de hardware, permitindo que o programador otimize manualmente. FORTRAN (na maioria dos casos) não tem acesso à memória de hardware que aborda hacks. (VAX FORTRAN é outra história.) Eu uso FORTRAN dentro e fora desde os anos 70. (Realmente.)

No entanto, a partir dos anos 90, o FORTRAN evoluiu para incluir construções de linguagem específicas que podem ser otimizadas em algoritmos inerentemente paralelos que podem realmente gritar em um processador com vários núcleos. Por exemplo, a Vetorização automática permite que vários processadores manipulem cada elemento em um vetor de dados simultaneamente. 16 processadores - vetor de 16 elementos - o processamento demora 1/16 do tempo.

Em C, você precisa gerenciar seus próprios threads e projetar seu algoritmo cuidadosamente para multiprocessamento e, em seguida, usar várias chamadas de API para garantir que o paralelismo ocorra corretamente.

No FORTRAN, você só precisa projetar seu algoritmo cuidadosamente para o multiprocessamento. O compilador e o tempo de execução podem lidar com o resto para você.

Você pode ler um pouco sobre o High Performance Fortran , mas encontra muitos links inativos. Você está melhor lendo sobre Programação Paralela (como o OpenMP.org ) e como o FORTRAN suporta isso.


6
@ S.Lott: Eu não conseguia imaginar o quão terrível o código C teria que parecer tão bem quanto o Fortran simplesmente escrito para a maioria dos códigos que temos aqui ... e eu sou um programador em C. Você obterá melhor desempenho com o código mais simples no Fortran. Não que você ou eu não tenhamos encontrado um contra-exemplo. : D
user7116 28/09/08

2
@ Greg Rogers: Você terá que resolver o seu problema com o pessoal da Fortran Vectorization, não comigo. Estou apenas relatando o que li. polyhedron.com/absoftlinux
S.Lott 28/09/08

2
-1 // "Geralmente FORTRAN é mais lento que C. Isso é verdade para quase tudo." porque? // um argumento baseado na facilidade de usar multithreading no Fortran vs C não está dizendo nada sobre o desempenho.
Steabert

4
@ S.Lott: "o multi-threading existe apenas para desempenho". Err, não.
21912 Jon Jonop

4
@ S.Lott: "O uso de ponteiros por C quase no nível do hardware permite que C seja mais rápido que o Fortran". Err, não
Jon Harrop

5

O código mais rápido não é realmente o idioma, é o compilador, para que você possa ver o "compilador" ms-vb que gera código de objeto inchado, mais lento e redundante que é amarrado dentro de um ".exe", mas o powerBasic gera muito melhor código. O código de objeto criado pelos compiladores C e C ++ é gerado em algumas fases (pelo menos 2), mas pelo design a maioria dos compiladores Fortran tem pelo menos 5 fases, incluindo otimizações de alto nível, portanto, pelo design, o Fortran sempre terá a capacidade de gerar código altamente otimizado. Portanto, no final, o compilador não é o idioma que você deve solicitar, o melhor que eu conheço é o Intel Fortran Compiler, porque você pode obtê-lo no LINUX e no Windows e usar o VS como IDE, se estiver procurando por um compilador barato, você sempre pode usar o OpenWatcom.

Mais informações sobre isso: http://ed-thelen.org/1401Project/1401-IBM-Systems-Journal-FORTRAN.html


3

O Fortran possui melhores rotinas de E / S, por exemplo, o recurso implícito do fornece flexibilidade que a biblioteca padrão da C não pode corresponder.

O compilador Fortran lida diretamente com a sintaxe mais complexa envolvida e, como essa sintaxe não pode ser facilmente reduzida à forma de passagem de argumentos, C não pode implementá-la com eficiência.


1
Você tem benchmarks que mostram Fortran batendo C para E / S?
Jeff

3

Usando padrões modernos e compilador, não!

Algumas pessoas aqui sugeriram que o FORTRAN é mais rápido porque o compilador não precisa se preocupar com aliases (e, portanto, pode fazer mais suposições durante a otimização). No entanto, isso tem sido tratado em C desde o padrão C99 (eu acho) com a inclusão da palavra-chave restringir. O que basicamente diz ao compilador que, dentro de um escopo, o ponteiro não é um alias. Além disso, C permite aritmética adequada de ponteiro, onde coisas como aliasing podem ser muito úteis em termos de desempenho e alocação de recursos. Embora eu ache que a versão mais recente do FORTRAN permita o uso de ponteiros "adequados".

Para implementações modernas, o C geral supera o FORTRAN (embora também seja muito rápido).

http://benchmarksgame.alioth.debian.org/u64q/fortran.html

EDITAR:

Uma crítica justa a isso parece ser que o benchmarking pode ser tendencioso. Aqui está outra fonte (relativa a C) que coloca o resultado em mais contexto:

http://julialang.org/benchmarks/

Você pode ver que C normalmente supera o Fortran na maioria dos casos (novamente veja as críticas abaixo que também se aplicam aqui); como outros já declararam, o benchmarking é uma ciência inexata que pode ser facilmente carregada para favorecer um idioma em detrimento de outros. Mas coloca em contexto como Fortran e C têm desempenho semelhante.


4
Seria um tolo acreditar em qualquer coisa sobre Fortran a partir de um post que supõe que ainda seja FORTRAN. Isso mudou mais de 25 anos atrás. Esses testes não podem comparar idiomas, porque eles usam compiladores de diferentes fornecedores, embora a Intel e o GCC tenham compiladores para C e Fortran. Portanto, essas comparações são inúteis.
Vladimir F

2

O Fortran pode lidar com matriz, especialmente matrizes multidimensionais, de maneira muito conveniente. Fatiar elementos da matriz multidimensional no Fortran pode ser muito mais fácil do que no C / C ++. O C ++ agora tem bibliotecas que podem fazer o trabalho, como Boost ou Eigen, mas, afinal, são bibliotecas externas. No Fortran, essas funções são intrínsecas.

Se o Fortran é mais rápido ou mais conveniente para o desenvolvimento, depende principalmente do trabalho que você precisa concluir. Como pessoa de computação científica em geofísica, fiz a maior parte do cálculo em Fortran (refiro-me ao Fortran moderno,> = F90).


1
E também se o Fortran é mais rápido também depende: do compilador que você usa (é importante!), Para trabalhos de computação, se você aplica paralelização apropriada ao código e como o seu código é escrito.
Kai

1

Isso é mais que um pouco subjetivo, porque entra na qualidade dos compiladores e mais do que qualquer outra coisa. No entanto, para responder mais diretamente à sua pergunta, falando do ponto de vista do idioma / compilador, não há nada no Fortran sobre C que o torne inerentemente mais rápido ou melhor que o C. Se você estiver executando operações matemáticas pesadas, ele se resumirá a a qualidade do compilador, a habilidade do programador em cada idioma e as matemáticas intrínsecas de suporte às bibliotecas que suportam essas operações para determinar, em última análise, qual será mais rápido para uma determinada implementação.

EDIT: Outras pessoas como @Nils levantaram o ponto positivo sobre a diferença no uso de ponteiros em C e a possibilidade de alias que talvez torne as implementações mais ingênuas mais lentas em C. No entanto, existem maneiras de lidar com isso em C99 , por meio de sinalizadores de otimização do compilador e / ou na forma como o C é realmente escrito. Isso está bem coberto na resposta do @Nils e nos comentários subsequentes que se seguem.


Parece um teste de referência de um algoritmo. O que leva menos tempo, FORTRAN ou C? Não parece subjetivo para mim. Talvez esteja faltando alguma coisa.
S.Lott 28/09/08

1
Discordo. Você está comparando os compiladores, não os idiomas. Eu acho que a pergunta original é se existe algo sobre o IDIOMA que o torna inerentemente melhor. Outras respostas aqui estão abordando algumas das sutis diferenças questionáveis, mas acho que a maioria concorda que elas estão no barulho.
226 Jeff alto

Esta não é uma análise O (n) de algoritmos. É desempenho. Não veja como o desempenho pode ser um conceito hipotético independente de implementação. Acho que estou perdendo alguma coisa.
S.Lott

1
-1: "não há nada no Fortran sobre C que o torne inerentemente mais rápido ou melhor que o C". Err, não.
21912 Jon Jonop

0

A maioria das postagens já apresenta argumentos convincentes, portanto, adicionarei os proverbiais 2 centavos a um aspecto diferente.

Ser fortran mais rápido ou mais lento em termos de poder de processamento no final pode ter sua importância, mas se levar 5 vezes mais tempo para desenvolver algo no Fortran, porque:

  • falta uma boa biblioteca para tarefas diferentes da trituração de números pura
  • falta qualquer ferramenta decente para documentação e testes de unidade
  • é uma linguagem com expressividade muito baixa, aumentando rapidamente o número de linhas de código.
  • tem um manuseio muito ruim de cordas
  • ele tem uma quantidade insana de problemas entre diferentes compiladores e arquiteturas, deixando você louco.
  • possui uma estratégia de IO muito ruim (READ / WRITE of sequential files. Sim, existem arquivos de acesso aleatório, mas você os viu usados?)
  • não incentiva boas práticas de desenvolvimento, modularização.
  • falta efetiva de um compilador de código-fonte totalmente padrão e totalmente compatível (o gfortran e o g95 não oferecem suporte a tudo)
  • interoperabilidade muito baixa com C (desconfiguração: um sublinhado, dois sublinhados, sem sublinhado, em geral um sublinhado, mas dois se houver outro sublinhado. e apenas não vamos nos aprofundar nos blocos COMUNS ...)

Então a questão é irrelevante. Se algo é lento, na maioria das vezes você não pode melhorá-lo além de um determinado limite. Se você quiser algo mais rápido, altere o algoritmo. No final, o tempo do computador é barato. O tempo humano não é. Valorize a escolha que reduz o tempo humano. Se aumentar o tempo do computador, é econômico de qualquer maneira.


3
diminuiu porque, apesar de você levantar pontos interessantes que contribuem para uma discussão sobre os benefícios / desvantagens do fortrans em relação a outros idiomas (com os quais não concordo completamente), isso não é realmente uma resposta para a pergunta ...
steabert

@steabert: na verdade, eu disseI will just add the proverbial 2 cents to a different aspect
Stefano Borini

1
+1 de mim para uma resposta não-nítida. Como você disse, o Fortran pode ser mais rápido em algumas tarefas raras (não vi nenhuma pessoalmente). Mas a quantidade de tempo que você perde para manter um idioma inatingível arruina qualquer vantagem possível.
André Bergner

10
-1. Você parece estar pensando em Fortran em termos de F77. Isso foi substituído por F90, F95, F03 e F08.
Kyle Kanos #

4
Votado porque fala exclusivamente sobre um lado de uma troca. A velocidade de desenvolvimento pode ser importante para a maioria da programação geral, mas isso não a torna a única troca válida. Os programadores do Fortran geralmente são cientistas / engenheiros que valorizam a simplicidade da linguagem (a fórmula do FORmula TRAN é extremamente fácil de aprender e dominar. O C / C ++ não é ), as excelentes bibliotecas (frequentemente usadas em outros idiomas) e a velocidade (por exemplo, simulações meteorológicas que levam dias no Fortran, mas meses se escritos inteiramente em outros idiomas).
BraveNewCurrency

-3

O Fortran tradicionalmente não define opções como -fp: strict (que o ifort requer para habilitar alguns dos recursos do USE IEEE_arithmetic, parte do padrão f2003). O Intel C ++ também não define -fp: strict como padrão, mas isso é necessário para o tratamento de ERRNO, por exemplo, e outros compiladores de C ++ não tornam conveniente desativar o ERRNO ou obter otimizações como a redução simd. O gcc e o g ++ exigiram que eu configurasse o Makefile para evitar o uso da combinação perigosa -O3 -ffast-math -fopenmp -march = native. Além desses problemas, essa pergunta sobre desempenho relativo fica mais exigente e depende das regras locais sobre a escolha de compiladores e opções.


As atualizações recentes do gcc corrigiram o problema com a combinação do Openmp e da matemática rápida.
tim18 23/09/16

Essa resposta é realmente sobre usuários que não entendem os sinalizadores padrão para seus compiladores, não os próprios idiomas.
Jeff
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.