Fortran est-il plus facile à optimiser que C pour les calculs lourds?


410

De temps en temps, je lis que Fortran est ou peut être plus rapide que C pour les calculs lourds. Est-ce vraiment vrai? Je dois admettre que je connais à peine Fortran, mais le code Fortran que j'ai vu jusqu'à présent ne montre pas que le langage a des fonctionnalités que C n'a pas.

Si c'est vrai, dites-moi pourquoi. S'il vous plaît ne me dites pas quelles langues ou bibliothèques sont bonnes pour le calcul des nombres, je n'ai pas l'intention d'écrire une application ou une bibliothèque pour le faire, je suis juste curieux.


53
Pas vraiment subjectif à partir des réponses données ci-dessous. Le titre correct est "Y a-t-il des raisons architecturales fondamentales pour lesquelles un compilateur Fortran POURRAIT produire un meilleur code optomisé qu'un compilateur C", mais ce n'est que du choix.
Martin Beckett

3
La question du titre n'est pas tant subjective que c'est un malentendu, je pense. La question plus détaillée n'est pas subjective.
jfm3

1
Je ne pense pas que quiconque apprendrait beaucoup de cela à part la réponse est "Oui" et "Non" en même temps, et varie en fonction du compilateur, de la source, du CPU, de la disposition de la mémoire, etc etc etc. Yawn.
user7116

1
Je ne pense pas que la question ou les réponses soient subjectives. Mais si vous pensez que ce drapeau aide quelqu'un, ça me va.
quinmars

2
@sixlettervariables bien que vous et moi connaissions déjà la réponse, c'est une question qui se pose à la plupart des gens au début de leur carrière et il est important de comprendre la réponse. Plutôt que de poster un commentaire dédaigneux, pourquoi ne pas trouver une réponse avec laquelle vous êtes d'accord et donner +1
MarkJ

Réponses:


447

Les langues ont des ensembles de fonctionnalités similaires. La différence de performances vient du fait que Fortran dit que l'aliasing n'est pas autorisé, sauf si une instruction EQUIVALENCE est utilisée. Tout code qui a un alias n'est pas Fortran valide, mais c'est au programmeur et non au compilateur de détecter ces erreurs. Ainsi, les compilateurs Fortran ignorent l'aliasing possible des pointeurs de mémoire et leur permettent de générer du code plus efficace. Jetez un oeil à ce petit exemple en 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;
    }
}

Cette fonction fonctionnerait plus lentement que l'homologue Fortran après optimisation. Pourquoi Si vous écrivez des valeurs dans le tableau de sortie, vous pouvez modifier les valeurs de la matrice. Après tout, les pointeurs peuvent se chevaucher et pointer vers le même bloc de mémoire (y compris le intpointeur!). Le compilateur C est obligé de recharger les quatre valeurs de matrice à partir de la mémoire pour tous les calculs.

Dans Fortran, le compilateur peut charger une fois les valeurs de la matrice et les stocker dans des registres. Il peut le faire car le compilateur Fortran suppose que les pointeurs / tableaux ne se chevauchent pas en mémoire.

Heureusement, le restrictmot clé et l'alias strict ont été introduits dans la norme C99 pour résoudre ce problème. Il est également bien pris en charge dans la plupart des compilateurs C ++ de nos jours. Le mot-clé vous permet d'indiquer au compilateur que le programmeur promet qu'un pointeur ne fait pas d'alias avec un autre pointeur. Les moyens stricts-aliasing que les promesses de programmeur que les pointeurs de type différent ne sera jamais chevauchement, par exemple double*ne se chevauchent pas avec un int*(à l'exception spécifique char*et void*peuvent se chevaucher avec quoi que ce soit).

Si vous les utilisez, vous obtiendrez la même vitesse de C et de Fortran. Cependant, la possibilité d'utiliser le restrictmot clé uniquement avec des fonctions essentielles aux performances signifie que les programmes C (et C ++) sont beaucoup plus sûrs et plus faciles à écrire. Par exemple, considérez le code Fortran non valide: CALL TRANSFORM(A(1, 30), A(2, 31), A(3, 32), 30)que la plupart des compilateurs Fortran compileront avec plaisir sans avertissement, mais introduisent un bogue qui n'apparaît que sur certains compilateurs, sur certains matériels et avec certaines options d'optimisation.


26
Tout est vrai et valide, jeff. Cependant, je ne considère pas le commutateur "supposer aucun aliasing" comme sûr. Il peut casser le code hérité d'autres projets de manière si subtile que je préfère ne pas l'utiliser. Je suis devenu un nazi restrictif pour cette raison :-)
Nils Pipenbrinck

3
À mon deuxième point, vous n'avez pas à utiliser le commutateur de compilateur no alias. Il suffit d'écrire le code pour que les charges basées sur le pointeur soient d'abord affectées dans une variable automatique, puis de travailler avec les automatiques à partir de là. Il paraîtra plus détaillé, mais il sera optimisé parfaitement par le compilateur.
Tall Jeff

33
Un bon exemple est la simple existence de memcpy () vs memmove (). Contrairement à memcpy (), memmove () gère les zones qui se chevauchent, donc memcpy () peut être plus rapide que memmove (). Ce problème était une raison suffisante pour que quelqu'un inclue deux fonctions au lieu d'une dans la bibliothèque standard.
jfs

12
Je pense que c'était le point de vue de Sebastian - en raison de la complexité / flexibilité de la gestion de la mémoire C, même quelque chose d'aussi simple que de déplacer la mémoire est délicat.
Martin Beckett

3
Votre call transformexemple n'a pas beaucoup de sens.
Vladimir F

163

Oui, en 1980; En 2008? dépend

Quand j'ai commencé à programmer professionnellement, la domination de la vitesse de Fortran venait d'être remise en question. Je me souviens avoir lu à ce sujet dans le Dr Dobbs et avoir parlé de l'article aux programmeurs plus âgés - ils ont ri.

J'ai donc deux vues à ce sujet, théoriques et pratiques. En théorie, Fortran n'a aujourd'hui aucun avantage intrinsèque par rapport au C / C ++ ou même à tout langage permettant le code assembleur. Dans la pratique, Fortran jouit encore aujourd'hui des avantages de l'héritage d'une histoire et d'une culture construites autour de l'optimisation du code numérique.

Jusqu'à et y compris Fortran 77, les considérations de conception de langage avaient pour objectif principal l'optimisation. En raison de l'état de la théorie et de la technologie du compilateur, cela signifiait souvent une restriction des fonctionnalités et des capacités afin de donner au compilateur la meilleure chance d'optimiser le code. Une bonne analogie est de penser à Fortran 77 comme une voiture de course professionnelle qui sacrifie les fonctionnalités pour la vitesse. De nos jours, les compilateurs se sont améliorés dans tous les langages et les fonctionnalités de productivité des programmeurs sont plus appréciées. Cependant, il y a encore des endroits où les gens sont principalement concernés par la vitesse dans le calcul scientifique; ces personnes ont très probablement hérité du code, de la formation et de la culture de personnes qui étaient elles-mêmes des programmeurs Fortran.

Quand on commence à parler d'optimisation du code, il y a beaucoup de problèmes et la meilleure façon de se faire une idée est de se cacher là où les gens ont pour mission de disposer d'un code numérique rapide . Mais gardez à l'esprit qu'un tel code critique critique est généralement une petite fraction de l'ensemble des lignes de code et très spécialisé: beaucoup de code Fortran est tout aussi "inefficace" que beaucoup d'autres codes dans d'autres langues et l' optimisation ne devrait même pas être une préoccupation majeure de ce code .

Wikipédia est un excellent endroit pour commencer à découvrir l'histoire et la culture de Fortran. L'entrée Wikipedia de Fortran est superbe et j'apprécie beaucoup ceux qui ont pris le temps et les efforts pour la rendre utile à la communauté Fortran.

(Une version abrégée de cette réponse aurait été un commentaire dans l'excellent fil de discussion lancé par Nils, mais je n'ai pas le karma pour le faire. En fait, je n'aurais probablement rien écrit du tout, mais pour cela, ce fil a une réelle le contenu et le partage d'informations par opposition aux guerres enflammées et au fanatisme linguistique, qui est ma principale expérience avec ce sujet. J'ai été submergé et j'ai dû partager l'amour.)


1
le lien: web.archive.org/web/20090401205830/http://ubiety.uwaterloo.ca/… ne fonctionne plus. Existe-t-il un lien alternatif?
nathanielng

64

Dans une certaine mesure, Fortran a été conçu en gardant à l'esprit l'optimisation du compilateur. Le langage prend en charge les opérations de tableau entier où les compilateurs peuvent exploiter le parallélisme (en particulier sur les processeurs multicœurs). Par exemple,

La multiplication matricielle dense est simplement:

matmul(a,b)

La norme L2 d'un vecteur x est:

sqrt(sum(x**2))

En outre des déclarations telles que FORALL, PUREet ELEMENTALprocédures , etc. Une aide supplémentaire au code. Optimize Même les pointeurs de Fortran ne sont pas aussi flexibles que C pour cette simple raison.

La prochaine norme Fortran (2008) a des co-tableaux qui vous permettent d'écrire facilement du code parallèle. G95 (open source) et les compilateurs de CRAY le supportent déjà.

Donc oui, Fortran peut être rapide simplement parce que les compilateurs peuvent l'optimiser / paralléliser mieux que C / C ++. Mais encore une fois, comme tout le reste de la vie, il y a de bons et de mauvais compilateurs.



1
La forallconstruction est obsolète car les compilateurs ne pouvaient pas optimiser le code correctement. Le remplacement est do concurrent. En outre, le code sqrt(sum(x**2))semble inefficace, car le compilateur construit probablement le vecteur entier x**2. Je suppose qu'une boucle est meilleure, mais il vaut sans doute mieux appeler la norm2fonction intrinsèque .
A. Hennink

39

C'est drôle que beaucoup de réponses ici de ne pas connaître les langues. Cela est particulièrement vrai pour les programmeurs C / C ++ qui ont ouvert et ancien code FORTRAN 77 et discutent des faiblesses.

Je suppose que le problème de vitesse est principalement une question entre C / C ++ et Fortran. Dans un code Huge, cela dépend toujours du programmeur. Il y a certaines fonctionnalités du langage que Fortran surpasse et certaines fonctionnalités que C fait. Ainsi, en 2011, personne ne peut vraiment dire lequel est le plus rapide.

À propos de la langue elle-même, Fortran prend actuellement en charge les fonctionnalités complètes de POO et il est entièrement rétrocompatible. J'ai utilisé le Fortran 2003 à fond et je dirais que c'était juste un plaisir de l'utiliser. À certains égards, Fortran 2003 est toujours derrière C ++, mais regardons son utilisation. Fortran est principalement utilisé pour le calcul numérique, et personne n'utilise de fonctionnalités C ++ OOP sophistiquées pour des raisons de vitesse. Dans le calcul haute performance, le C ++ n'a presque aucun endroit où aller (jetez un oeil à la norme MPI et vous verrez que le C ++ est obsolète!).

De nos jours, vous pouvez simplement faire de la programmation en langage mixte avec Fortran et C / C ++. Il existe même des interfaces pour GTK + dans Fortran. Il existe des compilateurs gratuits (gfortran, g95) et de nombreux excellents commerciaux.


8
Pourriez-vous s'il vous plaît ajouter une source, une expérience spécifique ou un institut scientifique / une agence informatique de haute performance qui s'éloigne du C ++ pour de futurs projets ou réécrit des projets c ++ dans un autre langage. Je demande seulement parce que je connais au moins deux institutions scientifiques, Sandia et CERN, qui utilisent fortement le c ++ pour leur modélisation haute performance. De plus, Sandia a converti l'un de leurs logiciels de modélisation (LAMMPS) de fortran en c ++ en y ajoutant un certain nombre d'améliorations impressionnantes.
Zachary Kraus

7
LAMMPS est écrit en C ++ extrêmement simple qui ne tire pas parti de la plupart des fonctionnalités modernes du langage. Il représente le C ++ que les programmeurs Fortran qui connaissent le C écrivent après avoir appris le C ++ 98. Cela ne veut pas dire que LAMMPS est mal écrit, juste que ce n'est pas l'exemple que vous voulez citer lorsque vous préconisez le C ++ dans HPC.
Jeff

30

Il y a plusieurs raisons pour lesquelles Fortran pourrait être plus rapide. Cependant, le montant qu'ils importent est si insignifiant ou peut être résolu de toute façon, que cela ne devrait pas avoir d'importance. La principale raison d'utiliser Fortran de nos jours est la maintenance ou l'extension des applications héritées.

  • Mots-clés PURE et ELEMENTAL sur les fonctions. Ce sont des fonctions qui n'ont aucun effet secondaire. Cela permet des optimisations dans certains cas où le compilateur sait que la même fonction sera appelée avec les mêmes valeurs. Remarque: GCC implémente "pure" comme une extension du langage. D'autres compilateurs le peuvent aussi. L'analyse inter-modules peut également effectuer cette optimisation mais elle est difficile.

  • ensemble standard de fonctions qui traitent des tableaux, pas des éléments individuels. Des trucs comme sin (), log (), sqrt () prennent des tableaux au lieu de scalaires. Cela facilite l'optimisation de la routine. La vectorisation automatique offre les mêmes avantages dans la plupart des cas si ces fonctions sont intégrées ou intégrées

  • Type complexe intégré. En théorie, cela pourrait permettre au compilateur de réorganiser ou d'éliminer certaines instructions dans certains cas, mais vous verriez probablement le même avantage avec la structure {double re, im; }; idiome utilisé en C. Il permet un développement plus rapide, car les opérateurs travaillent sur des types complexes dans fortran.


1
"mais vous verriez probablement le même avantage avec l' { double re, im; };idiome struct utilisé en C". Les compilateurs C retourneront très probablement cette structure sous forme sret avec la pile d'appelant allouant de l'espace, en passant un pointeur à l'appelé qui le remplit. C'est plusieurs fois plus lent que de renvoyer plusieurs valeurs dans des registres comme le ferait un compilateur Fortran. Notez que C99 a corrigé cela dans le cas particulier des complexes.
Jon Harrop

Je ne suis pas sûr d'être d'accord avec votre principale raison. Personnellement, j'aime utiliser fortran pour le code lourd mathématique où les tableaux et les fonctions mathématiques sont la partie la plus importante du code. Mais je sais pertinemment que dans de nombreuses institutions gouvernementales et banques, ils continuent d'utiliser fortran pour maintenir ou étendre le code hérité. J'ai personnellement utilisé fortran pour étendre le code d'un professeur sur mon doctorat. écrit le comité.
Zachary Kraus

Votre déclaration, "la principale raison d'utiliser Fortran de nos jours est de maintenir ou d'étendre les applications héritées", est complètement fausse. Je n'ai encore vu aucun autre langage de programmation même à distance proche des fonctionnalités fournies par Fortran, en particulier pour les applications mathématiques. Vous en avez déjà nommé quelques-uns, tels que la superbe prise en charge des tableaux, les fonctions arithmétiques complexes intégrées, les fonctions pures ou élémentaires - et je pourrais également en nommer d'autres. Cela suffit à lui seul pour prouver que votre déclaration ci-dessus est fausse.
Pap

28

Je pense que le point clé en faveur de Fortran est qu'il s'agit d'un langage légèrement plus adapté à l'expression des mathématiques basées sur des vecteurs et des tableaux. Le problème d'analyse de pointeur souligné ci-dessus est réel dans la pratique, car le code portable ne peut pas vraiment supposer que vous pouvez dire quelque chose à un compilateur. Il y a TOUJOURS un avantage aux calculs d'expression d'une manière plus proche de l'apparence du domaine. C n'a pas vraiment de tableaux du tout, si vous regardez de près, juste quelque chose qui se comporte comme ça. Fortran a de vrais arrawys. Ce qui facilite la compilation pour certains types d'algorithmes, en particulier pour les machines parallèles.

Au fond de choses comme le système d'exécution et les conventions d'appel, C et Fortran moderne sont suffisamment similaires pour qu'il soit difficile de voir ce qui ferait une différence. Notez que C ici est vraiment de base C: C ++ est un problème totalement différent avec des caractéristiques de performances très différentes.


25

Il n'y a pas de langue plus rapide qu'une autre, donc la bonne réponse est non .

Ce que vous devez vraiment demander, c'est "le code est-il compilé avec le compilateur Fortran X plus rapidement que le code équivalent compilé avec le compilateur C Y?" La réponse à cette question dépend bien sûr des deux compilateurs que vous choisissez.

Une autre question que l'on pourrait se poser serait du type "Étant donné la même quantité d'efforts consacrés à l'optimisation dans leurs compilateurs, quel compilateur produirait du code plus rapide?" La réponse à cela serait en fait Fortran . Les compilateurs Fortran ont des avantages certian:

  • Fortran a dû rivaliser avec Assembly à l'époque où certains ont juré de ne jamais utiliser de compilateurs, il a donc été conçu pour la vitesse. C a été conçu pour être flexible.
  • Le créneau de Fortran a été le calcul des nombres. Dans ce code de domaine n'est jamais assez rapide. Il y a donc toujours eu beaucoup de pression pour garder la langue efficace.
  • La plupart des recherches sur les optimisations de compilateurs sont effectuées par des personnes intéressées par l'accélération du code de calcul de nombres Fortran, donc l'optimisation du code Fortran est un problème bien mieux connu que l'optimisation de tout autre langage compilé, et les nouvelles innovations apparaissent d'abord dans les compilateurs Fortran.
  • Biggie : C encourage l'utilisation du pointeur beaucoup plus que Fortran. Cela augmente considérablement la portée potentielle de tout élément de données dans un programme C, ce qui les rend beaucoup plus difficiles à optimiser. Notez que Ada est également bien meilleur que C dans ce domaine, et est un langage OO beaucoup plus moderne que le Fortran77 couramment trouvé. Si vous voulez une langue OO qui peut générer un code plus rapide que C, c'est une option pour vous.
  • En raison de nouveau de sa niche de calcul, les clients des compilateurs Fortran ont tendance à se soucier davantage de l'optimisation que les clients des compilateurs C.

Cependant, rien n'empêche quelqu'un de consacrer des tonnes d'efforts à l'optimisation de son compilateur C et de le faire générer un meilleur code que le compilateur Fortran de sa plate-forme. En fait, les ventes plus importantes générées par les compilateurs C rendent ce scénario tout à fait réalisable


4
Je suis d'accord. Et puis-je ajouter que lorsque Fortran a été introduit (c'était le premier langage de haut niveau) à la fin des années 50 et au début des années 60, beaucoup étaient sceptiques quant à son efficacité. Par conséquent, ses développeurs devaient prouver que Fortran pouvait être efficace et utile et s'apprêtaient à «l'optimiser à mort» juste pour prouver leur point de vue. C est venu beaucoup plus tard (du début au milieu des années 70) et n'avait rien à prouver, pour ainsi dire. Mais à cette époque, beaucoup de code Fortran avait été écrit, de sorte que la communauté scientifique s'y est attachée et le fait toujours. Je ne programme pas Fortran mais j'ai appris à établir un lien pour appeler des sous-programmes Fortran à partir de C ++.
Olumide

3
La recherche sur l'optimisation du compilateur a été plus diversifiée que vous ne le pensez. L'histoire des implémentations LISP, par exemple, est pleine de succès à faire des calculs plus rapides que Fortran (qui reste le concurrent par défaut à contester). De plus, une grande partie de l'optimisation du compilateur a ciblé des représentations intermédiaires du compilateur, ce qui signifie que, hormis les différences de sémantique (comme l'aliasing), elles s'appliquent à tout langage de programmation d'une classe donnée.
Nulle part homme

2
L'idée est souvent répétée, mais il est un peu fallacieux de dire qu'il n'y a aucune conséquence pour l'efficacité inhérente à la conception d'un langage de programmation. Certaines fonctionnalités du langage de programmation conduisent nécessairement à des inefficacités car elles limitent les informations disponibles au moment de la compilation.
Praxeolitic

@Praxeolitic - C'est tout à fait correct (c'est pourquoi je suis heureux de n'avoir rien dit de tel).
TED

@TED ​​Honnêtement, en revenant ici quelques mois plus tard, je ne sais pas pourquoi j'ai laissé ce commentaire sur votre réponse. Peut-être que je voulais le laisser ailleurs? XP
Praxeolitic

22

Il y a un autre élément où Fortran est différent de C - et potentiellement plus rapide. Fortran a de meilleures règles d'optimisation que C. Dans Fortran, l'ordre d'évaluation d'une expression n'est pas défini, ce qui permet au compilateur de l'optimiser - si l'on veut forcer un certain ordre, il faut utiliser des parenthèses. En C, l'ordre est beaucoup plus strict, mais avec les options "-fast", ils sont plus détendus et "(...)" sont également ignorés. Je pense que Fortran a un chemin qui se situe bien au milieu. (Eh bien, l'IEEE rend la vie plus difficile car certains changements d'ordre d'évaluation nécessitent qu'aucun débordement ne se produise, ce qui doit être ignoré ou gêner l'évaluation).

Un autre domaine de règles plus intelligentes sont les nombres complexes. Non seulement il a fallu attendre C 99 pour que C en ait, mais les règles les régissent sont meilleures à Fortran; puisque la bibliothèque Fortran de gfortran est partiellement écrite en C mais implémente la sémantique Fortran, GCC a gagné l'option (qui peut également être utilisée avec des programmes C "normaux"):

-fcx-fortran-rules La multiplication et la division complexes suivent les règles de Fortran. La réduction de la plage se fait dans le cadre d'une division complexe, mais il n'y a pas de vérification si le résultat d'une multiplication ou division complexe est "NaN + I * NaN", avec une tentative de sauver la situation dans ce cas.

Les règles d'alias mentionnées ci-dessus sont un autre bonus et également - au moins en principe - les opérations sur l'ensemble du tableau, qui, si elles sont correctement prises en compte par l'optimiseur du compilateur, peuvent entraîner un code plus rapide. En revanche, certaines opérations prennent plus de temps, par exemple, si l'on fait une affectation à un tableau allouable, il y a beaucoup de vérifications nécessaires (réallouer? [Fonction Fortran 2003], a les foulées du tableau, etc.), opération simple plus complexe en arrière-plan - et donc plus lente, mais rend le langage plus puissant. D'un autre côté, les opérations de tableau avec des limites et des étapes flexibles facilitent l'écriture de code - et le compilateur optimise généralement mieux le code qu'un utilisateur.

Au total, je pense que C et Fortran sont à peu près aussi rapides; le choix devrait être plus la langue que l'on aime le plus ou si l'utilisation des opérations de tableau complet de Fortran et sa meilleure portabilité sont plus utiles - ou la meilleure interface avec le système et les bibliothèques d'interface utilisateur graphique en C.


Qu'y a-t-il à "sauver" de manière significative dans le cas Nan + INan? Ce qui différencie les infinis de NaN, c'est que les infinis sont signés. Les opérations impliquant des infinis non complexes qui donneraient un signe embrouillé donnent NaN et je ne vois aucune raison pour que les nombres complexes fassent autrement. Si un multiple (DBL_MAX, DBL_MAX) par (2,2), met le résultat au carré, puis le met au carré, quel devrait être le signe du résultat en l'absence de débordement? Qu'est-ce qui est plutôt multiplié par (1.001, DBL_MAX)? Je considérerais (NaN, NaN) comme la bonne réponse, et toute combinaison d'infini et de NaN comme absurde.
supercat

14

Il n'y a rien dans les langages Fortran et C qui rend l'un plus rapide que l'autre à des fins spécifiques. Il y a des choses sur les compilateurs spécifiques pour chacune de ces langues qui rendent certaines plus favorables à certaines tâches que d'autres.

Pendant de nombreuses années, les compilateurs Fortran ont existé, ce qui pourrait faire de la magie noire à vos routines numériques, ce qui rend incroyablement rapides de nombreux calculs importants. Les compilateurs C contemporains ne pouvaient pas le faire aussi bien. En conséquence, un certain nombre de grandes bibliothèques de code se sont développées à Fortran. Si vous voulez utiliser ces bibliothèques bien testées, matures et merveilleuses, vous sortez le compilateur Fortran.

Mes observations informelles montrent que de nos jours, les gens codent leurs trucs de calcul lourds dans n'importe quel ancien langage, et si cela prend un certain temps, ils trouvent du temps sur un cluster de calcul bon marché. La loi de Moore nous trompe tous.


11
Presque modernisé cela. Le problème est que Fortran ne possède certains avantages inhérents. Cependant, vous êtes tout à fait correct que la chose importante à regarder est le compier, pas la langue.
TED

14

Je compare la vitesse de Fortran, C et C ++ avec la référence classique Levine-Callahan-Dongarra de netlib. La version multilingue, avec OpenMP, est http://sites.google.com/site/tprincesite/levine-callahan-dongarra-vectors Le C est plus laid, car il a commencé par la traduction automatique, plus l'insertion de restrictions et de pragmas pour certains compilateurs. C ++ est juste C avec des modèles STL le cas échéant. À mon avis, la STL est un sac mixte pour savoir si elle améliore la maintenabilité.

Il n'y a qu'un exercice minimal de la fonction de doublage automatique des fonctions pour voir dans quelle mesure elle améliore l'optimisation, car les exemples sont basés sur la pratique traditionnelle de Fortran où peu de confiance est accordée à la doublure.

Le compilateur C / C ++ qui a de loin l'utilisation la plus répandue manque d'auto-vectorisation, sur laquelle ces benchmarks s'appuient fortement.

Concernant l'article qui est venu juste avant ceci: il y a quelques exemples où des parenthèses sont utilisées dans Fortran pour dicter l'ordre d'évaluation plus rapide ou plus précis. Les compilateurs C connus n'ont pas d'options pour observer les parenthèses sans désactiver les optimisations plus importantes.


La traduction laide est nécessaire pour surmonter le problème d'alias. Vous devez donner des variables factices au compilateur pour lui dire que les variables byref implémentées comme pointeurs peuvent être optimisées pour les registres.
david

12

Je suis un programmeur amateur et je suis "moyen" dans les deux langues. Je trouve plus facile d'écrire du code Fortran rapide que du code C (ou C ++). Fortran et C sont des langages "historiques" (selon la norme actuelle), sont largement utilisés et ont un compilateur gratuit et commercial bien pris en charge.

Je ne sais pas si c'est un fait historique, mais Fortran a l'impression qu'il est construit pour être mis en parallèle / distribué / vectorisé / quoi que ce soit. Et aujourd'hui, c'est à peu près la "métrique standard" quand nous parlons de vitesse: "est-ce que ça évolue?"

Pour le crunching pur CPU, j'adore Fortran. Pour tout ce qui concerne les E / S, je trouve plus facile de travailler avec C. (c'est difficile dans les deux cas de toute façon).

Maintenant, bien sûr, pour le code intensif mathématique parallèle, vous voudrez probablement utiliser votre GPU. C et Fortran ont tous les deux une interface CUDA / OpenCL plus ou moins bien intégrée (et maintenant OpenACC).

Ma réponse modérément objective est: si vous connaissez les deux langues également bien / mal, alors je pense que Fortran est plus rapide parce que je trouve plus facile d'écrire du code parallèle / distribué dans Fortran que C. (une fois que vous avez compris que vous pouvez écrire pour fortran "freeform" et pas seulement un code F77 strict)

Voici une 2e réponse pour ceux qui veulent me déprécier car ils n'aiment pas la 1ère réponse: Les deux langues ont les fonctionnalités requises pour écrire du code haute performance. Cela dépend donc de l'algorithme que vous implémentez (processeur intensif? Io intensif? Mémoire intensive?), Du matériel (processeur unique? Multicœur? Distribuez un supercalculateur? GPGPU? FPGA?), De vos compétences et, finalement, du compilateur lui-même. C et Fortran ont tous deux un compilateur génial. (Je suis très étonné de voir à quel point les compilateurs Fortran sont avancés, mais les compilateurs C aussi).

PS: je suis heureux que vous ayez spécifiquement exclu les bibliothèques car j'ai beaucoup de mauvaises choses à dire sur les bibliothèques GUI Fortran. :)


11

Je faisais quelques mathématiques approfondies avec FORTRAN et C pendant quelques années. D'après ma propre expérience, je peux dire que FORTRAN est parfois vraiment meilleur que C mais pas pour sa vitesse (on peut faire en sorte que C fonctionne aussi vite que FORTRAN en utilisant un style de codage approprié) mais plutôt à cause de bibliothèques très bien optimisées comme LAPACK, et à cause de grande parallélisation. À mon avis, FORTRAN est vraiment difficile à travailler, et ses avantages ne sont pas assez bons pour annuler cet inconvénient, alors maintenant j'utilise C + GSL pour faire des calculs.


10

Toutes les différences de vitesse entre Fortran et C seront plus fonction des optimisations du compilateur et de la bibliothèque mathématique sous-jacente utilisée par le compilateur particulier. Il n'y a rien intrinsèque à Fortran qui le rendrait plus rapide que C.

Quoi qu'il en soit, un bon programmeur peut écrire Fortran dans n'importe quelle langue.


@Scott Clawson: vous avez obtenu -1 et je ne sais pas pourquoi. +1 pour y remédier. Cependant, quelque chose à prendre en compte est que Fortran existe depuis plus longtemps que beaucoup de nos parents. Beaucoup de temps passé à optimiser la sortie du compilateur: D
user7116

Je suis d'accord. Je venais de poster une réponse très similaire en parallèle.
Tall Jeff

Le problème d'alias de pointeur en C a été soulevé par d'autres, mais il existe plusieurs méthodes que le programmeur peut utiliser sur les compilateurs modernes pour gérer cela, donc je suis toujours d'accord.
Tall Jeff

1
@Kluge: "Il n'y a rien d'intrinsèque à Fortran qui le rendrait plus rapide que C". Alias ​​de pointeur, retour de valeurs composées dans les registres, constructions numériques de niveau supérieur intégrées ...
Jon Harrop

9

Je n'ai pas entendu dire que Fortan est beaucoup plus rapide que C, mais il pourrait être concevable que dans certains cas, ce serait plus rapide. Et la clé n'est pas dans les caractéristiques linguistiques qui sont présentes, mais dans celles qui (généralement) sont absentes.

Un exemple sont les pointeurs C. Les pointeurs C sont utilisés à peu près partout, mais le problème avec les pointeurs est que le compilateur ne peut généralement pas dire s'ils pointent vers les différentes parties du même tableau.

Par exemple, si vous avez écrit une routine strcpy qui ressemblait à ceci:

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

Le compilateur doit fonctionner en supposant que les d et s peuvent être des tableaux qui se chevauchent. Il ne peut donc pas effectuer une optimisation qui produirait des résultats différents lorsque les tableaux se chevauchent. Comme vous vous en doutez, cela limite considérablement le type d'optimisations qui peuvent être effectuées.

[Je dois noter que C99 a un mot-clé "restrict" qui indique explicitement aux compilateurs que les pointeurs ne se chevauchent pas. Notez également que le Fortran a également des pointeurs, avec une sémantique différente de celle de C, mais les pointeurs ne sont pas omniprésents comme en C.]

Mais pour en revenir au problème C vs Fortran, il est concevable qu'un compilateur Fortran soit capable d'effectuer certaines optimisations qui pourraient ne pas être possibles pour un programme C (écrit simplement). Je ne serais donc pas trop surpris par cette affirmation. Cependant, je m'attends à ce que la différence de performances ne soit pas si grande. [~ 5-10%]


9

Rapide et simple: les deux sont tout aussi rapides, mais Fortran est plus simple. Ce qui est vraiment plus rapide à la fin dépend de l'algorithme, mais il n'y a de toute façon pas de différence de vitesse considérable. C'est ce que j'ai appris dans un atelier Fortran au centre de calcul haute performance de Stuttgart en Allemagne en 2015. Je travaille avec Fortran et C et partage cette opinion.

Explication:

C a été conçu pour écrire des systèmes d'exploitation. Par conséquent, il a plus de liberté que nécessaire pour écrire du code haute performance. En général, ce n'est pas un problème, mais si l'on ne programme pas soigneusement, on peut facilement ralentir le code.

Fortran a été conçu pour la programmation scientifique. Pour cette raison, il prend en charge l'écriture rapide de code syntaxiquement, car c'est le but principal de Fortran. Contrairement à l'opinion publique, Fortran n'est pas un langage de programmation obsolète. Sa dernière norme est 2010 et de nouveaux compilateurs sont publiés régulièrement, car la plupart des codes hautes performances sont écrits en Fortran. Fortran prend également en charge les fonctionnalités modernes en tant que directives de compilation (dans les pragmas C).

Exemple: Nous voulons donner une grande structure comme argument d'entrée à une fonction (fortran: sous-routine). Dans la fonction, l'argument n'est pas modifié.

C prend en charge les deux, appel par référence et appel par valeur, ce qui est une fonctionnalité pratique. Dans notre cas, le programmeur pourrait par accident utiliser l'appel par valeur. Cela ralentit considérablement les choses, car la structure doit d'abord être copiée dans la mémoire.

Fortran ne fonctionne qu'avec l'appel par référence, ce qui oblige le programmeur à copier la structure à la main, s'il veut vraiment une opération d'appel par valeur. Dans notre cas, fortran sera automatiquement aussi rapide que la version C avec appel par référence.


Pouvez-vous écrire une application parallèle native en C (c'est-à-dire sans appeler de bibliothèque?). Non. Pouvez-vous écrire une application parallèle native dans Fortran? Oui, de différentes manières. Ergo, Fortran est "plus rapide". Bien que, pour être honnête, en 2010, lorsque vous avez rédigé votre commentaire, la prise en charge des fonctionnalités parallèles do et co-array de Fortran n'était probablement pas aussi répandue qu'aujourd'hui.
Mali Remorker

@MaliRemorker Il a écrit cela en 2016, pas en 2010.
Kowalski

La surcharge liée à la création de processus parallèles n'est à mon avis pas le facteur le plus pertinent pour qu'un langage de programmation soit appelé «rapide». Les considérations pratiques sont plus pertinentes, comme une paix de code non performante. Cela n'aide donc pas si vous gagnez du temps une fois (lors de la création du processus parallèle) et le gaspillez plus tard sur plusieurs cœurs. Le terme «rapide» devrait également prendre en compte les codes non parallèles. Pour cette raison, je ne vois pas d'argument contre mon point. Peut-être que votre commentaire était une réponse indépendante?
Markus Dutschke

8

Généralement, FORTRAN est plus lent que C. C peut utiliser des pointeurs de niveau matériel permettant au programmeur d'optimiser manuellement. FORTRAN (dans la plupart des cas) n'a pas accès à la mémoire matérielle pour adresser les hacks. (VAX FORTRAN est une autre histoire.) J'utilise FORTRAN de temps en temps depuis les années 70. (Vraiment.)

Cependant, à partir des années 90, FORTRAN a évolué pour inclure des constructions de langage spécifiques qui peuvent être optimisées en algorithmes intrinsèquement parallèles qui peuvent vraiment crier sur un processeur multicœur. Par exemple, la vectorisation automatique permet à plusieurs processeurs de gérer simultanément chaque élément d'un vecteur de données. 16 processeurs - 16 éléments vectoriels - le traitement prend 1 / 16e de temps.

En C, vous devez gérer vos propres threads et concevoir soigneusement votre algorithme pour le multi-traitement, puis utiliser un tas d'appels d'API pour vous assurer que le parallélisme se déroule correctement.

Dans FORTRAN, vous n'avez qu'à concevoir soigneusement votre algorithme pour le multi-traitement. Le compilateur et l'exécution peuvent gérer le reste pour vous.

Vous pouvez lire un peu sur Fortran High Performance , mais vous trouverez beaucoup de liens morts. Vous feriez mieux de lire sur la programmation parallèle (comme OpenMP.org ) et comment FORTRAN prend en charge cela.


6
@ S.Lott: Je ne pouvais pas imaginer à quel point un code C horrible devrait ressembler à un simple Fortran écrit pour la plupart des codes que nous avons ici ... et je suis un programmeur C. Vous obtiendrez de meilleures performances avec du code plus simple dans Fortran. Non pas que vous ou moi n'ayons pas trouvé de contre-exemple. : D
user7116

2
@Greg Rogers: Vous devrez aborder votre problème avec les gens de Fortran Vectorization, pas moi. Je rapporte juste ce que j'ai lu. polyhedron.com/absoftlinux
S.Lott

2
-1 // "Généralement, FORTRAN est plus lent que C. Cela est vrai pour presque tout." Pourquoi? // un argument basé sur la facilité d'utilisation du multi-threading dans Fortran vs C ne dit rien sur les performances.
steabert

4
@ S.Lott: "le multi-threading n'existe que pour les performances". Euh, non.
Jon Harrop

4
@ S.Lott: "L'utilisation par C de pointeurs presque au niveau matériel permet à C d'être plus rapide que Fortran". Euh, non
Jon Harrop

5

Le code plus rapide n'est pas vraiment à la hauteur du langage, c'est le compilateur pour que vous puissiez voir le "compilateur" ms-vb qui génère du code objet gonflé, plus lent et redondant qui est lié à l'intérieur d'un ".exe", mais powerBasic génère également trop meilleur code. Le code objet créé par un compilateur C et C ++ est généré en certaines phases (au moins 2), mais par conception, la plupart des compilateurs Fortran ont au moins 5 phases, y compris des optimisations de haut niveau, donc par conception, Fortran aura toujours la capacité de générer du code hautement optimisé. Donc, à la fin, le compilateur n'est pas le langage que vous devriez demander, le meilleur compilateur que je connaisse est le compilateur Intel Fortran parce que vous pouvez l'obtenir sur LINUX et Windows et vous pouvez utiliser VS comme IDE, si vous cherchez un compilateur tigh pas cher, vous pouvez toujours relayer sur OpenWatcom.

Plus d'informations à ce sujet: http://ed-thelen.org/1401Project/1401-IBM-Systems-Journal-FORTRAN.html


3

Fortran a de meilleures routines d'E / S, par exemple la fonction implicite de do donne une flexibilité que la bibliothèque standard de C ne peut pas correspondre.

Le compilateur Fortran gère directement la syntaxe la plus complexe impliquée, et comme cette syntaxe ne peut pas être facilement réduite à la forme de passage d'arguments, C ne peut pas l'implémenter efficacement.


1
Avez-vous des repères qui montrent que Fortran bat C pour les E / S?
Jeff

3

En utilisant des normes et un compilateur modernes, non!

Certaines personnes ici ont suggéré que FORTRAN est plus rapide car le compilateur n'a pas à se soucier de l'alias (et peut donc faire plus d'hypothèses lors de l'optimisation). Cependant, cela a été traité en C depuis la norme C99 (je pense) avec l'inclusion du mot-clé restrict. Ce qui indique fondamentalement au compilateur, que dans une étendue donne, le pointeur n'est pas aliasé. De plus, C permet une arithmétique de pointeur appropriée, où des choses comme l'aliasing peuvent être très utiles en termes de performances et d'allocation de ressources. Bien que je pense qu'une version plus récente de FORTRAN permette l'utilisation de pointeurs "appropriés".

Pour les implémentations modernes, C surpasse généralement FORTRAN (bien qu'il soit très rapide aussi).

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

ÉDITER:

Une critique juste à ce sujet semble être que l'analyse comparative peut être biaisée. Voici une autre source (par rapport à C) qui met le résultat dans plus de contexte:

http://julialang.org/benchmarks/

Vous pouvez voir que C surpasse généralement Fortran dans la plupart des cas (voir à nouveau les critiques ci-dessous qui s'appliquent ici aussi); comme d'autres l'ont déclaré, l'analyse comparative est une science inexacte qui peut être facilement chargée pour favoriser une langue par rapport aux autres. Mais cela met en contexte comment Fortran et C ont des performances similaires.


4
On serait fou de croire quoi que ce soit à propos de Fortran à partir d'un post qui suppose qu'il est toujours FORTRAN. Cela a changé il y a plus de 25 ans. Ces tests ne peuvent pas comparer les langages, car ils utilisent des compilateurs de différents fournisseurs, bien qu'Intel et GCC aient des compilateurs pour C et Fortran. Par conséquent, ces comparaisons sont sans valeur.
Vladimir F

2

Fortran peut gérer des tableaux, en particulier des tableaux multidimensionnels, très facilement. Le découpage des éléments d'un tableau multidimensionnel dans Fortran peut être beaucoup plus facile que celui en C / C ++. C ++ a maintenant des bibliothèques qui peuvent faire le travail, comme Boost ou Eigen, mais elles le sont après toutes les bibliothèques externes. À Fortran, ces fonctions sont intrinsèques.

Que Fortran soit plus rapide ou plus pratique pour le développement dépend principalement du travail que vous devez terminer. En tant que spécialiste du calcul scientifique pour la géophysique, j'ai effectué la plupart des calculs à Fortran (je veux dire le Fortran moderne,> = F90).


1
Et aussi si Fortran est plus rapide dépend aussi: du compilateur que vous utilisez (ça compte!), Pour les travaux de calcul si vous appliquez la parallélisation appropriée au code, et comment votre code est écrit.
Kai

1

C'est plus que quelque peu subjectif, car cela entre dans la qualité des compilateurs et plus que toute autre chose. Cependant, pour répondre plus directement à votre question, parlant d'un point de vue langage / compilateur, rien sur Fortran sur C ne le rendra intrinsèquement plus rapide ou meilleur que C. Si vous effectuez des opérations mathématiques lourdes, cela se résumera à la la qualité du compilateur, la compétence du programmeur dans chaque langue et les bibliothèques de support mathématiques intrinsèques qui prennent en charge ces opérations pour déterminer finalement ce qui sera plus rapide pour une implémentation donnée.

EDIT: D'autres personnes telles que @Nils ont soulevé le bon point sur la différence dans l'utilisation des pointeurs en C et la possibilité d'aliasing qui rend peut-être les implémentations les plus naïves plus lentes en C. Cependant, il existe des moyens de traiter cela en C99 , via les drapeaux d'optimisation du compilateur et / ou la façon dont le C est réellement écrit. Ceci est bien couvert dans la réponse @Nils et les commentaires suivants qui suivent sa réponse.


Cela ressemble à un test de référence d'un algorithme. Qui prend moins de temps, FORTRAN ou C? Cela ne me semble pas subjectif. Peut-être que je manque quelque chose.
S.Lott

1
Être en désaccord. Vous comparez les compilateurs, pas les langues. Je pense que la question initiale est de savoir s'il y a quelque chose dans la LANGUE qui la rend intrinsèquement meilleure. D'autres réponses ici entrent dans certaines des subtiles différences discutables, mais je pense que nous sommes le plus d'accord pour dire qu'elles sont dans le bruit.
Tall Jeff

Ce n'est pas une analyse O (n) des algorithmes. C'est la performance. Ne voyez pas comment les performances peuvent être un concept hypothétique indépendant de l'implémentation. Je suppose que je manque quelque chose.
S.Lott

1
-1: "rien sur Fortran par rapport à C ne va le rendre intrinsèquement plus rapide ou meilleur que C". Euh, non.
Jon Harrop

0

La plupart des articles présentent déjà des arguments convaincants, je vais donc simplement ajouter les 2 cents proverbiaux à un aspect différent.

Être plus rapide ou plus lent en termes de puissance de traitement peut avoir son importance, mais si cela prend 5 fois plus de temps pour développer quelque chose dans Fortran, car:

  • il manque une bonne bibliothèque pour des tâches différentes de la compression des nombres purs
  • il manque tout outil décent pour la documentation et les tests unitaires
  • c'est un langage à très faible expressivité, qui fait monter en flèche le nombre de lignes de code.
  • il a un très mauvais traitement des cordes
  • il a un nombre insensé de problèmes entre différents compilateurs et architectures qui vous rendent fou.
  • il a une stratégie d'E / S très médiocre (LIRE / ÉCRIRE des fichiers séquentiels. Oui, des fichiers à accès aléatoire existent mais les avez-vous déjà vus utilisés?)
  • elle n'encourage pas les bonnes pratiques de développement, la modularisation.
  • manque effectif d'un compilateur opensource entièrement standard et entièrement conforme (gfortran et g95 ne prennent pas tout en charge)
  • très faible interopérabilité avec C (mangling: un trait de soulignement, deux traits de soulignement, pas de trait de soulignement, en général un trait de soulignement mais deux s'il y a un autre trait de soulignement. et juste ne pas plonger dans les blocs COMMUNS ...)

Ensuite, le problème n'est pas pertinent. Si quelque chose est lent, la plupart du temps, vous ne pouvez pas l'améliorer au-delà d'une limite donnée. Si vous voulez quelque chose de plus rapide, changez l'algorithme. En fin de compte, le temps informatique est bon marché. Le temps humain ne l'est pas. Valorisez le choix qui réduit le temps humain. Si cela augmente le temps de l'ordinateur, c'est quand même rentable.


3
downvoted parce que bien que vous souleviez des points intéressants qui s'ajoutent à une discussion sur les avantages / inconvénients de fortrans par rapport aux autres langues (avec lesquelles je ne suis pas complètement d'accord), ce n'est pas vraiment une réponse à la question ...
steabert

@steabert: en fait, j'ai ditI will just add the proverbial 2 cents to a different aspect
Stefano Borini

1
+1 de ma part pour une réponse non-nitpicky. Comme vous l'avez dit, Fortran pourrait être plus rapide dans certaines tâches rares (je n'en ai pas vu personnellement). Mais le temps que vous perdez pour maintenir une langue insoutenable ruine tout avantage possible.
André Bergner

10
-1. Vous semblez penser à Fortran en termes de F77. Cela a été remplacé par F90, F95, F03 et F08.
Kyle Kanos

4
Voté parce qu'il parle exclusivement d'un côté d'un compromis. La vitesse de développement peut être importante pour la plupart des programmes généraux, mais cela n'en fait pas le seul compromis valable. Les programmeurs Fortran sont souvent des scientifiques / ingénieurs qui apprécient la simplicité du langage (FORmula TRANslation est extrêmement facile à apprendre et à maîtriser. C / C ++ ne l' est pas ), les excellentes bibliothèques (souvent utilisées dans d'autres langues) et la vitesse (par exemple, les simulations météorologiques qui prennent des jours à Fortran, mais des mois s'ils sont entièrement écrits dans d'autres langues).
BraveNewCurrency

-3

Fortran ne définit traditionnellement pas d'options telles que -fp: strict (dont ifort a besoin pour activer certaines des fonctionnalités de USE IEEE_arithmetic, une partie de la norme f2003). Intel C ++ ne définit pas non plus -fp: strict par défaut, mais cela est requis pour la gestion d'ERRNO, par exemple, et d'autres compilateurs C ++ ne permettent pas de désactiver ERRNO ou d'obtenir des optimisations telles que la réduction simd. gcc et g ++ m'ont obligé à configurer Makefile pour éviter d'utiliser la combinaison dangereuse -O3 -ffast-math -fopenmp -march = native. Outre ces problèmes, cette question sur les performances relatives devient plus délicate et dépend des règles locales sur le choix des compilateurs et des options.


Les mises à jour récentes de gcc ont corrigé le problème avec la combinaison d'Openmp et de fast-math.
tim18

Cette réponse concerne les utilisateurs qui ne comprennent pas les indicateurs par défaut de leurs compilateurs, pas les langues elles-mêmes.
Jeff
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.