458 votes

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

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 le Fortran, mais le code Fortran que j'ai vu jusqu'à présent ne montrait pas que ce langage avait des caractéristiques que le C n'avait pas.

Si c'est vrai, dites-moi pourquoi. Ne me dites pas quels langages ou librairies sont bons pour le calcul, je n'ai pas l'intention d'écrire une application ou une librairie pour faire cela, je suis juste curieux.

65 votes

Notreally subjective à partir des réponses données ci-dessous. Le titre correct est "Existe-t-il des raisons architecturales fondamentales pour lesquelles un compilateur Fortran pourrait produire un code mieux optomisé qu'un compilateur C" mais c'est juste du pinaillage.

4 votes

La question du titre n'est pas tant subjective qu'il s'agit d'un malentendu, je pense. La question plus détaillée n'est pas subjective.

1 votes

Je ne pense pas que quiconque puisse apprendre grand-chose de tout cela, si ce n'est que la réponse est "Oui" et "Non" à la fois, et qu'elle varie en fonction du compilateur, de la source, du processeur, de la disposition de la mémoire, etc etc etc. Yawn.

497voto

Nils Pipenbrinck Points 41006

Ces langues ont des caractéristiques similaires. La différence de performance vient du fait que le Fortran interdit l'aliasing, sauf si une instruction EQUIVALENCE est utilisée. Tout code comportant un aliasing n'est pas un Fortran valide, mais c'est au programmeur et non au compilateur de détecter ces erreurs. Ainsi, les compilateurs Fortran ignorent l'aliasing éventuel des pointeurs mémoire et leur permettent de générer un code plus efficace. Jetez un coup d'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 s'exécuterait plus lentement que son homologue en Fortran après optimisation. Pourquoi ? Si vous écrivez des valeurs dans le tableau de sortie, vous risquez de modifier les valeurs de la matrice. Après tout, les pointeurs pourraient se chevaucher et pointer sur le même morceau de mémoire (y compris le tableau de sortie). int pointeur !). Le compilateur C est obligé de recharger les quatre valeurs de la matrice depuis la mémoire pour tous les calculs.

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

Heureusement, le restrict et l'anticrénelage strict ont été introduits dans la norme C99 pour résoudre ce problème. Ils sont également bien supportés par la plupart des compilateurs C++ de nos jours. Le mot-clé permet de donner au compilateur une indication que le programmeur promet qu'un pointeur ne s'aliasera pas avec un autre pointeur. L'aliasage strict signifie que le programmeur promet que des pointeurs de type différent ne se chevaucheront jamais, par exemple un pointeur double* ne se chevauchera pas avec une int* (avec l'exception spécifique que char* y void* peut se chevaucher avec n'importe quoi).

Si vous les utilisez, vous obtiendrez la même vitesse en C et en Fortran. Cependant, la possibilité d'utiliser les restrict Le fait de n'utiliser le mot-clé qu'avec les 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 invalide : CALL TRANSFORM(A(1, 30), A(2, 31), A(3, 32), 30) que la plupart des compilateurs Fortran compileront sans aucun avertissement, mais qui introduit un bogue qui n'apparaît que dans certains compilateurs, sur certains matériels et avec certaines options d'optimisation.

1 votes

Outre le mot-clé restrict, la plupart des compilateurs disposent de drapeaux d'optimisation en ligne de commande pour demander au compilateur de ne pas se soucier de l'aliasing. Étant donné que l'aliasing réel est plutôt rare, je considère ce niveau d'optimisation comme le point de départ par défaut.

0 votes

De plus, sans le drapeau ou le mot-clé new, en C, il suffit d'assigner les opérations basées sur les pointeurs à travers une variable automatique. Cela indique au compilateur que l'aliasing peut être ignoré et, bien que cela ressemble à plus de code, vous obtiendrez le résultat le plus rapide possible grâce à l'optimiseur.

2 votes

La "rareté" peut être ou non une bonne raison d'avoir des bogues non déterministes bancals. Je l'ai vu dans des cas où une fonction est utilisée pour traiter des données soit en place, soit hors place.

176voto

jaredor Points 1255

Oui, en 1980 ; en 2008 ? ça dépend

Lorsque j'ai commencé à programmer professionnellement, la domination de Fortran en termes de vitesse était tout juste remise en question. Je me souviens Je l'ai lu dans le Dr. Dobbs et j'ai parlé de l'article aux programmeurs plus âgés - ils ont ri.

J'ai donc deux points de vue à ce sujet, théorique et pratique. En théorie Aujourd'hui, Fortran n'a aucun avantage intrinsèque par rapport à C/C++ ou même à tout autre langage permettant le code d'assemblage. En pratique Fortran bénéficie 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'à Fortran 77 inclus, les considérations relatives à la conception du langage avaient pour objectif principal l'optimisation. En raison de l'état de la théorie et de la technologie des compilateurs, cela signifiait souvent en restreignant afin de donner au compilateur les meilleures chances d'optimiser le code. Une bonne analogie consiste à considérer Fortran 77 comme une voiture de course professionnelle qui sacrifie des fonctionnalités pour la vitesse. De nos jours, les compilateurs se sont améliorés dans tous les langages et les fonctionnalités destinées à améliorer la productivité des programmeurs sont plus appréciées. Cependant, il existe encore des endroits où les gens sont principalement préoccupé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.

Lorsque l'on commence à parler d'optimisation du code, les questions sont nombreuses et la meilleure façon de s'en faire une idée est de de rôder là où se trouvent les gens dont le métier est d'avoir un code numérique rapide. . Mais gardez à l'esprit que ce code critiquement sensible ne représente généralement qu'une petite fraction du nombre total de lignes de code et qu'il est très spécialisé : Une grande partie du code Fortran est tout aussi "inefficace" qu'une grande partie du code dans d'autres langages et dans d'autres domaines. l'optimisation ne devrait même pas être une préoccupation majeure d'un tel code .

wikipedia est un excellent point de départ pour découvrir l'histoire et la culture de Fortran. L'entrée Fortran sur Wikipedia est superbe et j'apprécie beaucoup ceux qui ont pris le temps et l'effort de le 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 faire ça. En fait, je n'aurais probablement rien écrit du tout si ce fil de discussion ne contenait pas d'informations et de partages réels, par opposition aux guerres de mots et au fanatisme linguistique, ce qui est ma principale expérience avec ce sujet. J'ai été submergé et j'ai dû partager l'amour).

1 votes

Le lien : web.archive.org/web/20090401205830/http://ubiety.uwaterloo.ca/ ne fonctionne plus. Existe-t-il un autre lien ?

69voto

user49734 Points 201

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

La multiplication des matrices denses est simple :

matmul(a,b)

La norme L2 d'un vecteur x est :

sqrt(sum(x**2))

En outre, des déclarations telles que FORALL , PURE & ELEMENTAL etc. contribuent à l'optimisation du code. Même les pointeurs en Fortran ne sont pas aussi flexibles qu'en C pour cette simple raison.

La prochaine norme Fortran (2008) comporte des co-arrays 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 dans la vie, il y a de bons et de mauvais compilateurs.

0 votes

1 votes

El forall est déprécié parce que les compilateurs ne pouvaient pas optimiser le code correctement. Son remplacement est do concurrent . De plus, le code sqrt(sum(x**2)) semble inefficace, car le compilateur construit probablement le vecteur entier x**2 . Je suppose qu'une boucle est préférable, mais il est sans doute préférable d'appeler la fonction intrinsèque norm2 fonction.

32voto

Greg Rogers Points 18119

Il y a plusieurs raisons pour lesquelles Fortran pourrait être plus rapide. Cependant, elles sont si peu importantes ou peuvent être contournées de toute façon qu'elles ne devraient pas avoir d'importance. La principale raison d'utiliser Fortran de nos jours est de maintenir ou d'étendre les applications existantes.

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

  • ensemble standard de fonctions qui traitent des tableaux, et non des éléments individuels. Des fonctions comme sin(), log(), sqrt() prennent des tableaux au lieu de scalaires. Cela rend plus facile l'optimisation de la routine. L'auto-vectorisation donne les mêmes avantages dans la plupart des cas si ces fonctions sont en ligne ou builtins.

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

1 votes

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

0 votes

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

1 votes

Votre affirmation, "la principale raison d'utiliser Fortran de nos jours est la maintenance ou l'extension d'anciennes applications", est totalement fausse. Je n'ai encore vu aucun autre langage de programmation se rapprochant de près ou de loin des fonctionnalités offertes par Fortran, en particulier pour les applications mathématiques. Vous en avez déjà cité quelques-unes, comme le superbe support des tableaux, l'arithmétique complexe intégrée, les fonctions pures ou élémentaires - et je pourrais en citer d'autres. Ce seul fait suffit à prouver que votre affirmation ci-dessus est fausse.

31voto

jakobengblom2 Points 2873

Je pense que le point clé en faveur de Fortran est que c'est un langage légèrement plus adapté à l'expression des mathématiques basées sur les vecteurs et les tableaux. Le problème de l'analyse des pointeurs évoqué plus haut est réel en pratique, puisque le code portable ne peut pas vraiment supposer que vous pouvez dire quelque chose au compilateur. Il y a TOUJOURS un avantage à exprimer les calculs d'une manière plus proche de la façon dont le domaine se présente. Le C n'a pas vraiment de tableaux, si vous regardez de près, juste quelque chose qui se comporte comme tel. Fortran a de vrais tableaux. Ce qui le rend plus facile à compiler pour certains types d'algorithmes, en particulier pour les machines parallèles.

En ce qui concerne le système d'exécution et les conventions d'appel, le C et le Fortran moderne sont suffisamment similaires pour qu'il soit difficile de voir ce qui pourrait faire la différence. Notez que le C ici est vraiment le C de base : le C++ est un problème totalement différent avec des caractéristiques de performance très différentes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X