IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langages de programmation Discussion :

Les meilleures fonctionnalités des langages de programmation


Sujet :

Langages de programmation

  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 41
    Par défaut Les meilleures fonctionnalités des langages de programmation
    Bonjour à tous.

    J'ouvre cette discussion, afin de partager mon avis – et avoir le votre – quant aux fonctionnalités offertes par les langages de programmation. (Il ne s'agit pas de prétendre qu'un langage est meilleur qu'un autre, mais de partager les caractéristiques qui nous ont marquées.) Selon vous, quelles sont les fonctionnalités indispensables d'un bon langage ?

    Pour ma part, c'est la clarté du code qui importe, notamment lorsqu'il est question d'héritage ou de programmation parallèle. J'aimerai également voir un support natif de nombre de fonctionnalités apportées par des libraires (notamment, le parallélisme).

    Et vous, quelle est votre opinion sur la question ?

  2. #2
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Ah ! Un inventaire à la Prévert. Voyons le mien...


    D'abord les qualités :
    * Un langage moderne : pas de fichiers d'en-tête, support unicode complet (pas de trigraphes et autres nids à vermines), etc.
    * Un langage consistent, respectueux du principe de moindre surprise, sans ambiguïtés, avec une seule façon simple de faire chaque chose.
    * Un bon outillage (IDE, complétion de code, colorisation, refactorisation, etc). Un compilateur efficace me dispensant de massacrer mon code pour obtenir des perfs correctes.
    * De bonnes bibliothèques de base, notamment concernant les chaînes, les structures de données, le parallélisme, les fichiers, le débogage (y compris assertions et mini-contrats) et les tests unitaires.


    Maintenant les fonctionnalités proprement dîtes :

    * Concision : si je veux créer un type immuable avec deux champs je veux pouvoir le faire en une ligne et ne pas avoir à déclarer deux champs, deux propriétés, deux constructeurs (initial et copie) et un type et avoir éventuellement à surcharger/définir à la main cinq méthodes pour tester l'égalité structurelle (GetHashCode/Equals/Equals spécialisé/opérateur ==/opérateur !=) et une autre pour obtenir un formatage au débogage.

    * Réutilisabilité du code : le système de types choisi doit permettre une véritable et pleine ré-utilisabilité, et être extensible. Ce qui est très rarement le cas. C# et Java ont par exemple tous deux commencé sans types paramétriques et les interfaces n'étaient qu'un piètre substitut à l'héritage multiple. Encore aujourd'hui je me retrouve régulièrement dans des impasses.

    * Des types transportant davantage d'informations : énumérations et identifiants pour les entiers (un ID de client est un entier mais devrait être représenté comme un type à part, ClientID, tandis que les énumérations ne sont plus à présenter), information de nullité, types algébriques, etc.

    * De puissantes capacités de méta-programmation, à la fois à la compilation (génération de code) et à l'exécution.

    * Des fonctionnelles (lambdas / first-class functions) avec clôture (closure).

    * Des pelletées de sucre syntaxique, du pattern matching à la ocaml aux tests implicites de nullité lors d'accès à des membres.

  3. #3
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 41
    Par défaut
    Ce que tu recherches, ce sont donc des fonctionnalités (du moins, en partie) offertes par des langages tel Cobra ! Qu'en est-il de la concurrence ? Juges-tu que le parallélisme est une trop lourde tâche ?

  4. #4
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Citation Envoyé par Marvell Voir le message
    Ce que tu recherches, ce sont donc des fonctionnalités (du moins, en partie) offertes par des langages tel Cobra ! Qu'en est-il de la concurrence ? Juges-tu que le parallélisme est une trop lourde tâche ?
    Je te remercie car je ne connaissais pas Cobra et il ne semble effectivement pas dénué de qualités. La doc est malheureusement plutôt succincte et laisse beaucoup de questions en suspens mais je pense que je prendrai le temps de l'essayer. Malheureusement le choix de s'appuyer sur dotnet est à la fois une bénédiction (utilisable de suite) et une malédiction (limites du système de types avec les mixins comme parade).

    Concernant la concurrence, distinguons d'abord les choses : il y a la concurrence de tous les jours, pour monsieur tout le monde, celle qui consiste à envoyer une tâche en arrière-plan ou à répartir le traitement de N éléments sur plusieurs threads. Simple et sans grand risque. En ce domaine C# avec ses mots clés async-await-lock et ses classes standards (collections, Parallel, Task, etc) fournit à peu près tout ce qui est nécessaire.

    Et puis il y a la concurrence "pour les hommes, les vrais", celle qui est loin d'être aussi triviale (je ne parle pas de micro-optimisations à base de barrières mémoires et d'instructions atomiques mais d'architectures et d'algorithmes concurrents). Dans ce domaine il ne fait aucun doute qu'on peut encore progresser.
    • Une partie de la solution est donnée par la prog fonctionnelle, d'où mes demandes sur les objets immuables, les tests d'égalité structurelle (pour la mémoïsation), les fonctionnelles, etc. Sauf que parfois les performances exigent des structures mutables partagées entre threads et, là, il n'y a pas de solution bien établie.
    • J'aime toutefois ce qu'a fait Duffy à ce sujet, ses ajouts rendent le code plus expressif et permettent au compilateur de vérifier de nombreuses choses. Je ne sais pas s'il y a d'autres travaux intéressants sur l'enrichissement du langage pour accroître la vérifiabilité à la compilation.
    • Je pense aussi qu'on peut travailler sur la vérification de la cohérence du système à l'exécution et les stress tests en fournissant au développeur des mots-clés et annotations réservées aux binaires en mode débogage et qui disparaîtront dans la version finale (vérification de l'identité du thread, spécification des points de contention pour guider le compilateur dans un test systématique des entretisses possibles de chemins d'exécution concurrents, etc).


    Enfin il y a le calcul sur GPU et les architectures matérielles hétérogènes. J'aimerais que tous les langages exposent OpenCL en standard avec la garantie que le client aura une machine compatible quelle que soit sa plateforme (un problème qui va bien au-delà du créateur du langage). J'aimerais aussi un meilleur outillage, je veux pouvoir déboguer un kernel OpenCL comme je débogue un code normal, avec du pas-à-pas dans les sources etcétéra. Enfin et très accessoirement, pourquoi pas une intégration directement dans la syntaxe du langage mais je ne suis même pas sûr que ce soit une bonne idée.

  5. #5
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 41
    Par défaut
    Citation Envoyé par DonQuiche Voir le message
    J'aimerais que tous les langages exposent OpenCL en standard avec la garantie que le client aura une machine compatible quelle que soit sa plateforme. […] Enfin et très accessoirement, pourquoi pas une intégration directement dans la syntaxe du langage mais je ne suis même pas sûr que ce soit une bonne idée.
    Je pense, bien au contraire, que les nouveaux langages doivent supporter nativement les fils d'exécution. Leur absence est préjudiciable. Elle revient à sous-entendre qu'il s'agit là d'une fonctionnalité exotique, optionnelle, qui ne concerne qu'un public averti, en quête des meilleures performances et ce au prix de grands efforts. Alors que nous entrons dans ère où les architectures hétérogènes tendent à s'imposer, une telle philosophie est inacceptable. Pour autant, les implémentations actuelles laissent à désirer…

    À mon goût, OpenCL est une erreur. Demander au programmeur de gérer des ressources de bas-niveau est un non-sens. Outre son aspect contre-productif, c'est également source de contention au niveau du matériel ; le programmeur n'ayant que peu d'informations de l'environnement (la charge de travail initiée par l'ensemble des processus actifs, l'implémentation physique des divers cœurs d'exécution, etc.). CUDA est un outil bien plus simple d'emploi, quoique restreint (ne supporte que les GPUs, qui plus est, de marque NVIDIA) et laissant également transparaître les détails de l'implémentation sous-jasante (ce qui pose nombre de problèmes à ladite marque).

    Enfin, un langage ne doit pas se résumer à ce que l'on peut faire, mais comment et en combien de temps une telle tâche peut être réalisée ! En ce sens, les langages devraient incorporés nativement nombre de fonctions, jusqu'ici apportées par des libraires.

  6. #6
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par Marvell Voir le message
    ce sens, les langages devraient incorporés nativement nombre de fonctions, jusqu'ici apportées par des libraires.
    Dans le langage lui-même, non !

    Que les fonctionnalités pour lequel un consensus suffisant a pu être établi soient proposées dans la bibliothèque standard du langage plutôt que dans des bibliothèques tierces, oui je suis tout à fait d'accord.
    Mais mettre une fonctionnalité dans le cœur du langage alors qu'elle aurait tout aussi bien fonctionner en étant dans la bibliothèque standard, je suis beaucoup moins chaud. Je préfère largement un langage qui reste simple et minimaliste en proposant les briques de base permettant de construire de bonne bibliothèque par dessus et accompagné d'une bonne bibliothèque standard plutôt qu'un langage embarquant lui-même une tonne de fonctionnalité. Ne serait-ce que pour l'extensibilité.

  7. #7
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Citation Envoyé par Marvell Voir le message
    Je pense, bien au contraire, que les nouveaux langages doivent supporter nativement les fils d'exécution. Leur absence est préjudiciable. Elle revient à sous-entendre qu'il s'agit là d'une fonctionnalité exotique, optionnelle, qui ne concerne qu'un public averti, en quête des meilleures performances et ce au prix de grands efforts.
    Je ne crois pas, je pense que cette séparation entre les sources pour CPU et les sources pour GPU, avec deux langages distincts, est naturelle et découle des différences d'architectures matérielles, les GPU étant des brutasses du SIMD mais aux capacités restreintes une fois sorti de ça (branchements limitatifs, mémoire à haute latence et importance de la localité du cache, etc). Cela étant dit, oui, c'est une fonctionnalité exotique car peu de problèmes, et encore moins de bonnes conceptions logicielles, se prêtent à ces architectures si particulières.

    Il est certain que deux logiques sont nécessaires et une tentative d'unification du langage imposerait inévitablement d'avoir de nombreuses fonctionnalités exclusives à une partie ou une autre. Le seul intérêt que je vois à unifier plus ou moins ces deux langages c'est pour faciliter le marshaling des structures de données entre les deux univers et pour pouvoir entretisser leurs sources, notamment pour placer une petit source de l'un au sein d'un fichier source de l'autre.

    À mon goût, OpenCL est une erreur. Demander au programmeur de gérer des ressources de bas-niveau est un non-sens.
    Je ne vois pas du tout de quoi tu parles. Je n'ai aucune expérience avec CUDA mais de ce que j'en sais les deux sont extrêmement similaires du point de vue des fonctionnalités. Qui plus est je t'ai relu plusieurs fois pour être sûr de t'avoir bien compris puisque d'abord tu affirmes que OpenCL est trop bas-niveau avant de soutenir que l'un des avantages de CUDA serait qu'il expose les détails de l'architecture.

    Enfin, un langage ne doit pas se résumer à ce que l'on peut faire, mais comment et en combien de temps une telle tâche peut être réalisée ! En ce sens, les langages devraient incorporés nativement nombre de fonctions, jusqu'ici apportées par des libraires.
    Je ne vois pas en quoi une inclusion dans le langage lui-même pourrait améliorer les performances, sauf éventuellement si le langage est de haut niveau et que tu proposes d'écrire ces fonctionnalités dans un langage de plus bas niveau. Ce qui ne se justifie que pour une poignée de classes et fonctions à mon avis (notamment structures de données principales et chaînes).

  8. #8
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 41
    Par défaut
    Citation Envoyé par DonQuiche Voir le message
    Je ne crois pas, je pense que cette séparation entre les sources pour CPU et les sources pour GPU, avec deux langages distincts, est naturelle et découle des différences d'architectures matérielles […]
    C'est un point de vue. Pour ma part, j'estime que le programmeur ne devrait pas avoir à se soucier des détails concernant l'architecture sous-jasante. À cela, plusieurs raisons… Les systèmes tendent à être hétérogènes. Un utilisateur peut disposer d'un grand nombre de cœurs scalaires, et d'un GPU d'appoint. À contrario, un autre peut avoir un CPU plus modeste, mais un puissant GPU. De plus, les architectures évoluent rapidement : les GPU délaissent le modèle SIMD pour le SIMT, plusieurs ISAs cohabitent sur un même SoC, etc.
    D'autre part, les programmes n'ont pas l'exclusivité sur les ressources du système ! Une charge de travail conséquente peut être initiée par n'importe quel application, sans que les autres en aient conscience. Laisser les développeurs choisir entre le GPU ou le CPU ne requiert que pure spéculation de leur part ! Là, le système d'exploitation – ayant connaissance des performances relatives offertes par chacune des unités de traitements, ainsi que de leur charge – peut réaliser un bien meilleur choix.

    Citation Envoyé par DonQuiche Voir le message
    […] tu affirmes que OpenCL est trop bas-niveau avant de soutenir que l'un des avantages de CUDA serait qu'il expose les détails de l'architecture.
    Peut-être me suis-je mal exprimé. Je remarquais simplement que CUDA, comme OpenCL, laissait transparaître les détails de l'architecture sous-jasante. Aucunement je ne l'approuve ! (Je ne faisait qu'un constat.)
    Pour revenir à OpenCL, son usage est bien différent de CUDA. Avec OpenCL, le programmeur a à charge de créer un contexte d'exécution et des queues de commande, de compiler manuellement les kernels, de choisir où les lancer, etc., là où un simple appel de kernel suffit avec CUDA ! Cela convient à certains…

  9. #9
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 41
    Par défaut
    Ensuite, chacun a son point de vue. Le but de cette discussion est bien sûr de partager nos opinions !

  10. #10
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Citation Envoyé par Marvell Voir le message
    C'est un point de vue. Pour ma part, j'estime que le programmeur ne devrait pas avoir à se soucier des détails concernant l'architecture sous-jasante. À cela, plusieurs raisons… Les systèmes tendent à être hétérogènes. Un utilisateur peut disposer d'un grand nombre de cœurs scalaires, et d'un GPU d'appoint. À contrario, un autre peut avoir un CPU plus modeste, mais un puissant GPU. De plus, les architectures évoluent rapidement : les GPU délaissent le modèle SIMD pour le SIMT, plusieurs ISAs cohabitent sur un même SoC, etc.
    D'autre part, les programmes n'ont pas l'exclusivité sur les ressources du système ! Une charge de travail conséquente peut être initiée par n'importe quel application, sans que les autres en aient conscience. Laisser les développeurs choisir entre le GPU ou le CPU ne requiert que pure spéculation de leur part ! Là, le système d'exploitation – ayant connaissance des performances relatives offertes par chacune des unités de traitements, ainsi que de leur charge – peut réaliser un bien meilleur choix.
    Donc ce que tu veux toi c'est un langage qui pourrait compiler à la volée ton code pour le CPU ou le GPU indifféremment ? Mais pour moi ça n'a pas grand sens tant ces architectures et leurs capacités sont différentes. Tu ne choisis carrément pas les mêmes algos, la même écriture ou les mêmes optimisations selon que tu cibles le CPU ou le GPU. Passer de l'un à l'autre avec la même approche c'est diviser les perfs par 10 dans le sens GPU -> CPU et par 100 dans l'autre sens. Et puis vu les grosses limitations des GPU, autant dire qu'il vaut mieux que le compilateur te renvoie une erreur si par mégarde tu dépasses les 80 registres permis ou si tu utilises la récursion plutôt que d'accepter ton code mais de refuser ensuite de l'exécuter sur le GPU sans que tu comprennes pourquoi.


    Pour revenir à OpenCL, son usage est bien différent de CUDA. Avec OpenCL, le programmeur a à charge de créer un contexte d'exécution et des queues de commande, de compiler manuellement les kernels, de choisir où les lancer, etc., là où un simple appel de kernel suffit avec CUDA ! Cela convient à certains…
    D'accord je vois ce que tu veux dire. Plusieurs réponses à ça :
    * OpenCL demande une plomberie initiale plus importante, oui. Mais elle est quand même facile à factoriser en une simple fonction adaptée à tes besoins et si tu n'as pas besoin d'un contrôle fin aujourd'hui tu en auras peut-être besoin demain, le prix est faible à payer. J'admets cependant qu'il est préférable d'avoir une petite bibliothèque d'utilitaires.

    * Tu peux demander un choix automatique du périphérique (le meilleur sera alors choisi) et c'est presque toujours suffisant.

    * Pour les raisons que j'ai expliquées au-dessus je considère qu'une architecture hétérogène n'introduit pas de besoin de répartir dynamiquement la charge entre CPU ou le GPU. Toutefois pour les rares cas où ça pourrait avoir du sens (machine dédiée avec un CPU qui se tourne les pouces et permettant de gagner 5% ou alors plusieurs GPU de modèles différents), OpenCl expose un système d'événements permettant de détecter les périphériques inactifs pour leur assigner de nouveaux éléments. Je conçois que tu voudrais que ce soit automatisé mais pour être bien fait cela requiert une connaissance a priori des calculs réalisés et des futurs points de contention. Le problème n'existe pas quand tu répartis tes travaux sur des coeurs identiques avec une granularité assez fine mais il apparaît si certains périphériques risquent d'être des goulets d'étranglement pénalisant tout le monde aux étapes de synchronisation.

  11. #11
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 41
    Par défaut
    Citation Envoyé par DonQuiche Voir le message
    Tu ne choisis carrément pas les mêmes algos, la même écriture ou les mêmes optimisations selon que tu cibles le CPU ou le GPU. Passer de l'un à l'autre avec la même approche c'est diviser les perfs par 10 dans le sens GPU -> CPU et par 100 dans l'autre sens. Et puis vu les grosses limitations des GPU, autant dire qu'il vaut mieux que le compilateur te renvoie une erreur si par mégarde tu dépasses les 80 registres permis ou si tu utilises la récursion plutôt que d'accepter ton code mais de refuser ensuite de l'exécuter sur le GPU sans que tu comprennes pourquoi.
    Pas nécessairement ! Le monde des GPU est très hétérogène, tant au niveau des générations que des concepteurs. À titre d'exemple, les prochains GPUs NVIDIA Maxwell supporteront 255 registres par fil d'exécution, là ou Kepler (1ère génération) n'en disposait que de 63. De plus, la logique de contrôle a été revue. L'architecture SIMT assure une distribution toujours plus efficasses des unités, à mesure que le nombre de fils supportés grandit ! CUDA est donc plus souple que les architectures SIMD, et c'est une bonne chose…

    Pour moi, un bon langage ferait de bons compromis. La distribution des tâches sur le CPU ou GPU devrait être dynamique, partiellement gérée par le système d'exploitation, mais au regard d'informations communiquées par ledit programme (sous forme d'annotations, permettant de préciser que ledit thread devrait préférentiellement être porté sur le CPU/GPU) ! Ce choix reposerait également sur la prise en compte des détails sous-jasants à l'architecture (banc de registre, support des divergences, modèle d'exécution, etc.)

  12. #12
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Citation Envoyé par Marvell Voir le message
    Pas nécessairement
    Mais si parce que les CPU et GPU seront toujours très différents, sinon les GPU n'auraient intérêt. Les GPU sont et seront des brutasses à SIMD inadaptés aux traitements conventionnels. Tu peux toujours augmenter le nombre de registres il n'en demeurera pas moins que tu en auras toujours 1000fois moins que ce qu'il te faudrait pour supporter une pile d'appels, que ton architecture sera toujours extrêmement lente pour des problèmes séquentiels parce que pas faîte pour ça du tout, que ta mémoire aura toujours une très grande latence, que tes branchements conditionnels amputeront tes performances, etcétéra. Ca ne changera pas.

    Et d'ailleurs les nouveautés dans le domaine du GPGPU ne portent pas du tout sur une transformation en super-CPU mais sur un tout autre problème, à savoir l'interfaçage avec le CPU qui est aujourd'hui le gros frein aux performances : mémoire partagée avec le CPU, minimisation des transferts mémoire avec les pipes, minimisation des retours vers le CPU avec la création de kernels depuis les kernels, etcétéra. Autrement dit on cherche à accroître la ségrégation et non pas à l'éteindre.

Discussions similaires

  1. Parts de marchés des langages de programmation
    Par Marc Lussac dans le forum Langages de programmation
    Réponses: 51
    Dernier message: 21/05/2013, 13h51
  2. Réponses: 19
    Dernier message: 08/04/2011, 17h46
  3. Réponses: 0
    Dernier message: 29/03/2011, 14h36
  4. L'avenir des langages de programmation
    Par LordBob dans le forum Langages de programmation
    Réponses: 14
    Dernier message: 02/04/2006, 23h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo