C11 n'est pas encore mort

Posté par  . Édité par Bruno Michel, Benoît Sibaud, baud123, Nÿco et claudex. Modéré par Nÿco.
59
26
déc.
2011
C et C++

La dernière norme du langage C a été publiée le 8 décembre 2011, la pré-version finale étant accepté le 10 octobre, peu avant le décès du regretté Dennis Ritchie à l'origine du langage.

C11 intègre principalement la gestion du multithreading et rend optionnelles certaines fonctionnalités afin de faciliter la conformité des compilateurs vis-à-vis de la norme. La précédente norme C99 a eu beaucoup de mal à s'imposer auprès de certains éditeurs, certains refusant même de l'implémenter (notamment un vendeur d'environnement Basic, situé à Redmond).

Les principaux changements par rapport à C99 :

  • possibilité d'aligner les structures : introduction des mot-clés _Alignas (spécifier l'alignement), _Alignof (récupérer l'alignement) (cf. entête <stdalign.h>) et apparition de la fonction aligned_alloc permettant d'allouer une structure tout en spécifiant l'alignement

  • gestion du multithreading : mot-clé _Thread_local pour spécifier la classe de stockage (Thread_Local_Storage), API pour créer, gérer les threads/mutex/conditions (cf. entête <threads.h>). Possibilité de gérer des opérations atomiques et introduction du mot-clé _Atomic pour spécifier les types atomiques (Cf. entête <stdatomic.h>)

  • gestion des chaînes unicode : les types char16_t et char32_t permettent de stocker respectivement des chaînes UTF-16 et UTF32. On peut désormais préfixer les chaînes constantes par u8, u, U pour indiquer l'encodage utilisé (respectivement UTF-8, UTF-16, UTF-32).

  • l'infâme gets (obsolète en C99) à l'origine de nombreux buffer overflows cède la place à gets_s, alternative plus sûre (car vérifiant les limites).

  • support des structures et unions anonymes, pratique pour les structures imbriquées.

// avant
struct A {
  int a;
  struct {
    int b;
    int c;
  } B;
};
...
A bidule;
bidule.B.b = 3;

// après
struct A {
  int a;
  struct {
    int b;
    int c;
  };
};
...
A bidule;
bidule.b = 3;
  • sélection générique de fonctions : il est désormais possibilité de sélectionner dans une macro la fonction à exécuter en fonction du type des paramètres à l'aide du mot-clé _Generic. Dans l'exemple ci-dessous, la macro cbrt(x) exécutera la fonction cbrtl si x est de type double, cbrtf est de type float ou cbrt par défaut.
#define cbrt(X) _Generic((X), long double: cbrtl, \
                              default: cbrt, \
                              float: cbrtf)(X)
  • introduction du mode create-and-open pour fopen (qualificatif 'x'), qui se comporte comme le mode POSIX O_CREAT|O_EXCL, utilisé entre autre par les fichiers verrou.

  • introduction de la fonction quick_exit (et de son homologue at_quick_exit) qui permet de quitter un programme en effectuant les déinitialisations requises quand exit échoue (seules les fonctions enregistrées par at_quick_exit sont exécutées).

  • une des critiques faites au C est le fait que celui-ci fasse confiance au programmeur pour vérifier que la taille des données allouées est suffisante, ce qui est source de nombreuses failles. Désormais, la bibliothèque standard offre des interfaces sûres pour ces fonctions. (cf. Annexe K de la norme)

  • une autre nouveauté pour encourager les vendeurs à prendre en charge la dernière norme est l'optionnalité de certaines parties de la norme. Sont optionnels :

    • les tableaux à longueurs variables,
    • la prise en charge des nombres complexes (obligatoires dans C99),
    • les interfaces sûres,
    • la prise en charge du multithreading, etc.

La norme C11 est en cours d'implémentation dans GCC 4.6.x et suivants (switch -std=c1x ou -std=gnu1x pour inclure les extensions GNU) et CLang (switch -std=c11). Comme on peut le voir, C est un langage encore actif et qui a de beaux jours devant lui !

Aller plus loin

  • # Bibliothèque de base pure C ?

    Posté par  . Évalué à 8.

    Je profite de cette dépêche pour demander s'il existe des bibliothèques de base pure C (pas C++) ?

    Ce que j'entends par bibliothèque de base, c'est une bibliothèque qui inclus les structures et concepts important ; je veux dire liste chaînés, arbres B, pool de Threads ? Car à part la GLib, je n'en connais pas. Y en aurait-il d'autres ? Plus ou moins légères ?

    Knowing the syntax of Java does not make someone a software engineer.

  • # sélection générique de fonctions

    Posté par  . Évalué à 2.

    sélection générique de fonctions : il est désormais possibilité de sélectionner dans une macro la fonction à exécuter en fonction du type des paramètres à l'aide du mot-clé _Generic. Dans l'exemple ci-dessous, la macro cbrt(x) exécutera la fonction cbrtl si x est de type double, cbrtf est de type float ou cbrt par défaut.

    Du coup le choix de fonction se fait à la compilation ou à l'exécution ?

    Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

  • # phk n'aime pas C11

    Posté par  (site web personnel) . Évalué à 10.

    https://www.varnish-cache.org/docs/trunk/phk/thetoolsweworkwith.html

    pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.

    • [^] # Re: phk n'aime pas C11

      Posté par  (site web personnel) . Évalué à 10.

      c'est vrai que les nouveaux mots clés en mixed case et avec des underscores pètent complètement les précédentes conventions de nommages de C.

      Dennis, reviens, ils sont devenus fous!

      • [^] # Re: phk n'aime pas C11

        Posté par  . Évalué à 6. Dernière modification le 27 décembre 2011 à 11:38.

        Il a clairement pas tord, c'est vraiment moche ce qu'ils ont définit et l'apport est bien maigre.

         #define cbrt(X) _Generic((X), long double: cbrtl, \
                                      default: cbrt, \
                                      float: cbrtf)(X)
        
        

        C'est quoi cette syntaxe qui ne ressemble pas du tout au C (une sorte de case sur un type) ?

        La gestion des threads peut être pas mal (notamment le _Thread_local qui évite de passer par l'API pthread qui est moins naturelle), mais ca impose tout un nombre de contrainte sur l'os qui est derrière (et oui le C tourne aussi sur des os minimaliste)?

        Et par contre ils n'ont rien proposé sur l'API string qui est assez dangereuse...

        • [^] # Re: phk n'aime pas C11

          Posté par  . Évalué à 2.

          Je me suis permis d'éditer ton commentaire pour rendre le code plus lisible. J'ai remplacé les marques de citation :

          >
          
          

          Par les balises de code :

           ```c
           ```
          
          

          « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

        • [^] # Re: phk n'aime pas C11

          Posté par  . Évalué à 1.

          La gestion des threads peut être pas mal (notamment le _Thread_local qui évite de passer par l'API pthread qui est moins naturelle), mais ca impose tout un nombre de contrainte sur l'os qui est derrière (et oui le C tourne aussi sur des os minimaliste)?

          C'est pour ça que des morceaux de la norme (dont les threads) ont été rendus optionnels.

          • [^] # Re: phk n'aime pas C11

            Posté par  . Évalué à 4.

            C'est pour ça que des morceaux de la norme (dont les threads) ont été rendus optionnels.

            Oui mais dans ce cas ça perd tout son intérêt, autant utiliser une bibliothèque externe qui est présente de manière optionnelle ou encore les extensions gcc...

            Le C est un langage bas niveau, autant se concentrer sur le langage (attribut, typeof, ...) sans forcement chercher a étendre l'API de la libc.

        • [^] # Re: phk n'aime pas C11

          Posté par  . Évalué à 2.

          Quelle est la différence avec __thread qui était dans C99 ? http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Thread_002dLocal.html

          • [^] # Re: phk n'aime pas C11

            Posté par  . Évalué à 6.

            __thread était une extension de gcc, pas du C99 (de mémoire). Et du coup ça doit etre la meme chose

          • [^] # Re: phk n'aime pas C11

            Posté par  (site web personnel) . Évalué à 2.

            Il n'y a pas de __thread en C99. Le keyword __thread est une extension de gcc (GNU C).

      • [^] # Re: phk n'aime pas C11

        Posté par  (site web personnel) . Évalué à 10.

        Je trouve aussi ces keywords très laids mais contrairement à ce que dit phk ils sont consistants.

        Précisons d'abord que des keywords qui commencent par un underscore suivi d'une majuscule sont apparus déjà avec C99 (avec l'introduction de _Bool, _Complex et _Imaginary). En effet, les identifiers qui commencent par un underscore suivi d'une majuscule sont réservés depuis le premier standard C (C90). L'avantage est du point vue des indentifiers qu'un code valide en C90 sera aussi valide en C99 et en C11.

        Ajoutons ensuite que pour pour la plupart de ces keywords, C définit des macros avec des noms plus simples. Ces macros sont accessibles via des headers standards et le C encourage leur utilisation pour du nouveau code.

        Par exemple, dans le header standard stdalign.h, les macros suivantes sont définies:
        - la macro alignof pour l'opérateur _Alignof.

        - la macro alignas pour le specifier _Alignas.

        Et cela de la même manière qu'est défini par exemple depuis C99 la macro bool dans stdbool.h pour _Bool.

    • [^] # Re: phk n'aime pas C11

      Posté par  . Évalué à -9.

      C'est qui ce guignol ?

      Il commence par faire un caca nerveux sur la syntaxe de _Bool, _Noreturn & co et sur les headers std correspondant en sous-entendant que c'est crétin. Si cet imbécile prétend être un gourou ou une référence en C ou que sais-je, il devrait au moins savoir pourquoi cette manière de faire est employée.

      • [^] # Re: phk n'aime pas C11

        Posté par  . Évalué à 5.

        Et si on sait pourquoi mais qu'on trouve ça crétin quand même, qu'est-ce qui se passe ? Le monde s'écroule tout autour de nous ?

        Tous les nombres premiers sont impairs, sauf un. Tous les nombres premiers sont impairs, sauf deux.

        • [^] # Re: phk n'aime pas C11

          Posté par  . Évalué à -2.

          si on sait pourquoi

          Le môsieur connait assez bien les intentions des rédacteurs, la preuve :

          Next, they broke the upper/lower rule, by adding special keywords in mixed case, probably because they thought it looked nicer

          Un grand expert on vous le dit. ;)

      • [^] # Re: phk n'aime pas C11

        Posté par  . Évalué à 4.

        Hint: FreeBSD (VFS, Jails, GEOM, GDBE, DevFS et quelques autres KLOC), Varnish etc.

        • [^] # Re: phk n'aime pas C11

          Posté par  . Évalué à 0.

          Il est donc infiniment supérieur à tous les intervenants des organismes nationaux et internationaux normalisant le C, et habilité à râler sur des sujets triviaux pour enfoncer le clou et démontrer sa toute puissance sur ces nazes qui font que de la merde.

          Même Linus raconte de temps en temps des conneries sur le C. C'est pas parce que quelqu'un à un CV béton dans l'utilisation de X que c'est un grand maître dans l'architecture et la conception de X. Surtout que le C, c'est pas juste le C sur PC/serveur. Le C, ça tourne sur DSP, dans ton frigo, dans ta machine à laver, dans des satellites, ça peut même ptet tourner DTC si t'avales une capsule avec camera intégrée pour inspecter ton système digestif. Parmi les normalisateurs, il y a des dingues qui bouffent des compilos au petit déjeuné, parfois dans des domaines spécialisés dont tu peux même pas imaginer l'existence avant d'en avoir entendu parler.

          Si phk n'est pas content, qu'il se sorte les doigts et qu'il aille normaliser lui même le bousin. Il aura en face de lui des gents qui sauront le recevoir. Et l'écouter, s'il a quelque chose de plus sérieux à dire que OIN OIN YA _Bool et stdbool.h C LÈ.

          • [^] # Re: phk n'aime pas C11

            Posté par  . Évalué à 3.

            Non.

            Je dis juste que "C'est qui ce guignol ?" et "Un grand expert on vous le dit" ça me semble un poil déplacé. On peut ne pas être d'accord, et j'ai lâché le C depuis suffisamment longtemps pour ne pas avoir d'avis; mais il a un CV qui demanderait un peu plus de subtilité pour expliquer pourquoi il a tord. Surtout que phk n'est pas à classer dans la catégorie de ceux qui font du bruit, il a introduit le "bikeshed color".

            • [^] # Re: phk n'aime pas C11

              Posté par  . Évalué à -3.

              "Un grand expert on vous le dit" ça me semble un poil déplacé.

              Mon argument et la citation que je donne ne repose sur aucune expertise technique, si ce n’est un petit cours d’auto-défense intellectuelle : le monsieur prête à ses contradicteurs, c.-à-d. les rédacteurs de la norme, des arguments qu’ils n’ont vraisemblablement pas. Ceci afin de pouvoir mieux démonter leur choix. Comme je n’ose croire que le groupe de personnes qui a rédigé la norme, aux CV très certainement aussi conséquents que le monsieur, soient des branquignols il faut bien se rendre à l’évidence : soit le monsieur est de mauvaise foi, soit il ne sait pas de quoi il parle. Ce texte est peu complaisant envers l’expertise des rédacteurs de la norme. Et ce que vous dites à propos du monsieur vaut aussi à propos des rédacteurs de la norme : c’est déplacé.

              De plus, son texte n’est techniquement pas à l’image de son expertise technique défendue ici. Notons par ailleurs que le commentaire à l’orgine du fil, se trouve être appuyé par une explication technique détaillée ici même explication dans laquelle j’ai bien plus appris que du texte du monsieur-au-CV-bêton et qui consolide notamment mon intuition à propos de include. Alors le monsieur a beau avoir un CV en bêton, lorsqu’il s’agit d’argumenter sur un choix technique de la norme, entre :
              probably because they thought it looked nicer et autres phrases du même acabit qui rendent le rapport signal/bruit de son texte ridiculement bas ;
              — et le commentaire d’Ouah ;
              je choisis le second, parce que je me laisse convaincre par les arguments du texte, et pas par le CV de la personne. Quand bien même ce serait Jésus je ne prendrai pas tout ce qu’il fait pour pain béni.

          • [^] # Re: phk n'aime pas C11

            Posté par  . Évalué à 2.

            C'est vrai qu'il faut être un dingue de la théorie des compilateurs pour pondre une convention de nommage.
            Tu as d'autres âneries du même calibre ?

            • [^] # Re: phk n'aime pas C11

              Posté par  . Évalué à 3.

              Et toi t'es content de résumer implicitement le C11 à un problème de convention de nommage et de faire semblant de pas comprendre que se focaliser là-dessus au point atteint par phk dans son torchon est justement un des problèmes, décrédibilisant toute personne qui en fait un caca nerveux, quelque soit les logiciels merveilleux qu'elle code en C ?

              D'autant qu'il parle de C11 et ne fait même pas remarquer que _Bool date de C99, point qui ferait perde du poids à sa complainte.

              Alors c'est peut-être pas très sympa de le traiter d'idiot, mais juste ouvrez les yeux et voyez que ce génie nous pond des :

              Unfortunately C fell in bad company over the years, and the reason for this outburst is that I just browsed the latest draft from the ISO-C standardisation working-group 14.
              [...]
              Let me give you an example of their utter sillyness:"

              [ suit son délire anal sur le _Xcasing ]

              Alors si le ISO-C standardisation working-group 14 fait preuve de utter sillyness vu ce qu'ils ont produit, il me suffit de justement comparer cette production au rant de PHK pour en déduire que ce dernier fait preuve de connerie profonde.

              C99 contenait déjà _Bool, _Complex et _Imaginary.

              Comme phk est trop occupé à coder varnish et à écrire des rants idiots pour avoir le temps de s'informer sur le langage qu'il utilise, et que les défenseurs de phk ici présents sont trop occupés à me moinser pour avoir le temps de lire "The New C Standard An Economic and Cultural Commentary" version 1.2 de Derek M. Jones, voici en exclusivité pour ces derniers la raison TRÈS TRÈS DURE À IMAGINER TOUT SEUL surtout quand on fait plein de C tout le temps de la syntaxe bizarre de _Bool et ses amis :

              476
              An object declared as type _Bool is large enough to store the values 0 and 1.
              large enough to store 0 and 1
              Commentary
              Many existing programs contain a type defined, by developers, with these properties. The C committee did not want to break existing code by introducing a new keyword for an identifier that was likely to be in widespread use. _Bool was chosen. The header was also created and defined to contain more memorable identifiers. Like other scalar types, _Bool is specified in terms to the values it can hold, not the number of bits in its representation.

              La partie de phk sur les threads est plus intéressante (quoiqu'à plusieurs autres reprises, il démontre qu'il ne comprend pas très bien à quoi sert la standardisation internationale d'un langage, mais c'est noyé au milieu de remarques et infos intéressantes donc ça passe), mais son pétage de plomb sur le casing est ridicule au possible.

              Sa conclusion malheureusement est à classer du côté du pire et non du meilleur. À moins qu'il tente de lancer un énorme troll (je ne sais pas s'il tente, mais clairement il réussit), comparer The C Programming Language à un standard ISO C relève de la connerie incurable. De même que penser que l'"ISO WG14 are destroying the C language I use and love" : rien ne l’empêche de continuer à utiliser les pthreads et de compiler avec -ansi.

  • # Commentaire supprimé

    Posté par  . Évalué à 1.

    Ce commentaire a été supprimé par l’équipe de modération.

    • [^] # Re: _Generic et surcharge de fonction

      Posté par  (site web personnel) . Évalué à 4.

      Le problème de la surcharge des fonctions est que il est alors nécessaire de mangler [1] les types des argument dans le nom du symbole. comme en C++ on se retrouverais avec des nom de symbole du genre _Z3fooEii, et ça c'est pas top niveau compatibilité.

      _Generic devrais aider pour implémenter tgmath.h j'imagine:
      http://carolina.mff.cuni.cz/~trmac/blog/2005/the-ugliest-c-feature-tgmathh/

      [1] Comment traduire en français ?

    • [^] # Re: _Generic et surcharge de fonction

      Posté par  . Évalué à 0. Dernière modification le 27 décembre 2011 à 12:10.

      J'aurais aimé qu'ils permettent au compilateur la surcharge de fonction comme en C++

      Oh non, pitié, pas d'overloading en C! C'est l'une des pires erreurs que l'on peut faire dans un langage, parce que le programmeur n'a plus de moyen simple de déterminer quelle fonction va être exécutée (à la différence, par exemple, d'un mécanisme clair comme le polymorphisme en orienté objet sans héritage multiple). Le pire, c'est que cette "fonctionnalité" te pourrit la vie même si tu ne l'utilises pas (surtout avec les conversions implicites du C).

      De plus, elle n'apporte qu'un léger confort dans quelques exemples triviaux. Cas qui sont la plupart du temps symptômes d'un problème de conception.

      • [^] # Commentaire supprimé

        Posté par  . Évalué à 5.

        Ce commentaire a été supprimé par l’équipe de modération.

        • [^] # Re: _Generic et surcharge de fonction

          Posté par  . Évalué à 1.

          Donc, exactement kifkif.

          Non: lorsque le langage supporte l'overloading, tu dois non seulement savoir le nom et le type de la fonction que tu veux appeler, mais aussi être sûr qu'il n'y a aucune autre fonction avec le même nom et une signature compatible. Parce que dans le cas contraire, une petite erreur de type peut passer à la compilation, ce qui remet en question un des principes fondamentaux du typage statique.

          Dans un projet un peu large, demander au programmeur de garder à l'esprit l'ensemble de toutes les fonctions existantes est irréaliste.

          Et savoir que les conversions implicites sont dangereuses n'est pas le problème. Le problème est que, le duo overloading + conversion implicite fait que le compilateur va chercher silencieusement à "réparer" une erreur de type, comme par exemple un int à la place d'un float (voire pire, un float à la place d'un double). Et lorsqu'on a besoin de ces différents types dans un même projet, ces erreurs arrivent fatalement, même au meilleur programmeur.

          Je trouve ça étrange que tu compares avec le polymorphisme

          (Note: le polymorphisme peut être tout aussi bien statique que dynamique). J'ai pris l'exemple du polymorphisme par c'est un mécanisme similaire (permet d'utiliser le même nom de fonction pour des objets différents), mais avec une sémantique claire (un nom dans une classe = une fonctionnalité, éventuellement avec plusieurs implémentations).

          Il en va de même avec la surcharge des opérateurs en C: la sémantique est claire, tout le monde connaît les règles mathématiques. Ton exemple avec les matrices tombe aussi dans cette catégorie.

          Naturellement, on peut donner des milliers d'exemples de mauvaise utilisation de l'overloading. Mais de la mauvaise programmation peut être faite dans n'importe quel paradigme.

          Je suis entièrement d'accord, et j'ai horreur qu'on justifie la suppression d'une fonctionnalité sous prétexte qu'elle peut-être mal utilisée.

          Mais le cas de l'overloading est différent: il induit invariablement des erreurs, même lorsque l'on ne l'utilise pas. Et, encore une fois, je n'ai jamais vu de situation où il n'y avait pas une solution plus élégante.

          S'il fallait absolument introduire quelque chose de ce genre en C, l'approche prise par le langage Go (les interfaces) me parait nettement plus saine.

          • [^] # Re: _Generic et surcharge de fonction

            Posté par  (site web personnel) . Évalué à 2.

            J'avais cru comprendre que les problèmes de l'overloading était surtout un problème à cause des conversions implicites ou dans un langage objet, de l'héritage, ou pire l'héritage multiple.

            La notion d'interface est une sorte d'héritage simple.

            Concernant l'élégance, que fais-tu pour la gestion des flottants, de matrice, ou de vecteurs ? L'appel de fonction est quand même très moche non ?

            "La première sécurité est la liberté"

            • [^] # Re: _Generic et surcharge de fonction

              Posté par  . Évalué à 3.

              Comme je le disais plus haut, la surcharge des opérateurs mathématiques constitue justement une exception. Elle obéit à des règles universellement connues et ne pose donc pas (ou beaucoup moins) de problème. De plus, ces opérateurs sont déjà une exception syntaxique (notation infixe ou préfixe au lieu d'un appel de fonction).

              Il est certain que dans un langage sans aucune forme d'héritage (ni de conversion implicite), l'overloading est beaucoup moins dangereux. Mais, à choisir entre les deux…

              Je suis vraiment étonné de la popularité que semble avoir cette "fonctionnalité" ici.

              • [^] # Re: _Generic et surcharge de fonction

                Posté par  . Évalué à -1.

                tout simplement parce qu'en théorie, ça permet d'avoir un code plus concis et lisible (en limitant la longueur des lignes), et tant qu'il n'y a pas besoin de debugger c'est bon ;)
                Ensuite y a toujours rbreak dans gdb qui permet de poser une plâtrée de breakpoint en même pas 10s.

                Il ne faut pas décorner les boeufs avant d'avoir semé le vent

        • [^] # Re: _Generic et surcharge de fonction

          Posté par  . Évalué à 0.

          grep

      • [^] # Re: _Generic et surcharge de fonction

        Posté par  . Évalué à 5.

        Oh non, pitié, pas d'overloading en C!

        Et puis quand tu debug c'est sympa, entre le namespace, l'overloading, pour poser un breakpoint il faut tout spécifier.

        Moi ce que j'aurais aimé, c'est un moyen de remplacer toute les horreurs du préprocesseur, par quelque chose géré par le compilo (les static inline était un premier pas).

  • # Quel livre conseillez vous ?

    Posté par  . Évalué à 2.

    Quel livre (papier) conseillez vous pour bien programmer en C99 et/ou C11 ?

  • # Bof

    Posté par  (site web personnel) . Évalué à 10.

    Si C99 ne s'est pas imposé, je vois vraiment pas pourquoi celle-ci y réussira.
    J'aurai tendance à considérer cela comme inhérent au coeur de cible de C : La programmation système.
    Je ne pense pas que les professionnels du secteur seront près à modifier les compilo (et donc ajouter de l'incertitude dans un maillon capital de leur chaîne) pour supporter une nouvelle norme qui de toute façon ne sera pas appliqué par les vieux barbus du C "-ansi -pedantic" qui ont déjà tout ce qu'ils veulent en C : de la simplicité, de la liberté et de la puissance.

    À vu de nez, on va se retrouver, comme pour C99, avec une implémentation dans gcc pour les grandes achitectures mainstream (x86, x86_64, arm, ect...) et toujours les vieux compilos limite K&R sur tout le reste (coucou TexasInstrument et consors !). Ce n'est plus une norme, c'est une option de non portabilité !

    PS : Et pour la prochaine norme, les mot clés ils nous les mettent en 1337_5P33K ??

    • [^] # Re: Bof

      Posté par  . Évalué à 5.

      Certains ont quand même adopté le C99. Le compilo ARM est C99 par exemple.
      Et je trouve qu'il y a quand même des choses pratiques dans le C99 qui rendent le code plus lisible. Pour les initialisations par exemple.

    • [^] # Re: Bof

      Posté par  . Évalué à 10.

      Je ne pense pas que les professionnels du secteur seront près à modifier les compilo (et donc ajouter de l'incertitude dans un maillon capital de leur chaîne) pour supporter une nouvelle norme qui de toute façon ne sera pas appliqué par les vieux barbus du C "-ansi -pedantic" qui ont déjà tout ce qu'ils veulent en C : de la simplicité, de la liberté et de la puissance.

      Si tu mates la page de C99, tu verras que les compilateurs pour les gros systèmes UNIX (et clones) et Windows ont adapte leur compilateur: IBM C for AIX, PGI C Compiler, GCC (presqu'entièrement), ICC (presqu'entièrement), Sun C Compiler -- bref, les compilateurs qui comptent.

      Et ce n'est pas parce que certains grincheux ont décidé que seule la norme C89 compte que ça va rester ainsi. Si on va par là, on devrait suivre les coding styles de la fondation GNU: utiliser la syntaxe pré-ANSI pour definir les fonctions. Quelque chose du genre:

      int foo(a,b,c) 
      char *a, float b, unsigned c {
      }
      
      

      ... Juste parce que "tous les compilateurs n’implémentent pas encore la norme ANSI". Crois-moi, il y a tout un tas de gens très contents du fait que C99 ait été inventé et qui programment avec, car le langage fournit tout un tas de mécanismes utiles pour le programmeur, tout en limitant la complexité (l'alternative bas-niveau devenant C++, autrement plus compliqué).

      Concernant l'ajout de constructions visant la programmation concurrente et parallèle : il s'agit d'ajouts fondamentaux. Un langage système, même bas-niveau, doit désormais être capable de gérer la concurrence. Les systèmes du futur seront très certainement des processeurs de type "manycore", avec plus de 60 coeurs sur une seule puce. Il existe déjà des processeurs de ce type, certains utilisables en production (d'autres sont réservés à la recherche, et d'autres ne sont produits que pour certaines agences dont le nom est un acronyme à trois lettres que nous ne nommerons pas) :

      • Cyclops-64 (IBM C64) a produit un processeur avec 160 coeurs, avec une unité flottante partagée par deux coeurs. Il y a un micro-OS (proprio) pour booter le processeur, pas de mémoire virtuelle, pas de caches de données (uniquement des scratchpads, i.e. des mémoires locales aux coeurs, adressables directement par le programmeur). Le processeur est cadencé à 500MHz.

      • Single Cloud on a Chip (Intel SCC) est un processeur qui comprend 4 zones. Chaque zone embarque 6 tuiles. Chaque tuile comporte 2 coeurs, chacun ayant 2 niveaux de cache (un L1D et un L2 unifié données +instructions), sans protocole de cohérence. Chaque tuile comporte aussi un "Message Passing Buffer" (MPB), qui est en gros un scratchpad pour communiquer avec les autres tuiles. SCC est un processeur intéressant pour tester des politiques de gestion de puissance et d’énergie (pas simplement l'ajustement de fréquence, mais aussi la variation de tension). Il y a donc 48 coeurs (à base de Pentium classique) sur un chip. Il existe deux modes : l'un où un Linux tourne par tuile (c'est le coté "cloud"), et l'autre où on boote un noyau Linux sur une tuile, et le reste est à programmer par le programmeur système.

      • Les processeurs de la compagnie Tilera (TileGX, etc.) sont des processeurs de 32 ou 64 coeurs, qui ont la particularité de proposer un système de cache cohérent (en fait si je me souviens bien, il y a cinq réseaux différents sur le chip, mais je ne me souviens plus exactement quels sont les usages). La performance en virgule flottante est relativement pourrie, mais la performance sur valeurs entières reste plutôt intéressante. Le processeur est situee sur une carte avec interface PCIe. Aucun OS, rien sur le chip : il faut tout programmer soi-même.

      • Les accélérateurs d'Intel (famille MIC, Knight's Corner, Knight's Ferry, etc.) sont les descendants de feu le Larrabee. Pour le moment il s'agit d'une carte accélératrice (donc PCIe) avec 32 coeurs x86 modifies avec des unités SIMD (AVX, successeur de SSE, et dont les registres font 256 bits au lieu de 128).

      Il y a d'autres processeurs manycore qui vont pointer le bout de leur nez. Tous ont en commun de la mémoire partagée, un grand nombre de processeurs, une mémoire locale relativement petite (scratchpad et/ou cache avec ou sans cohérence), etc. Essayer de les programmer sans avoir du parallélisme en tête ne peut mener qu'à une perte de performance globale (dans le meilleur des cas) ou à des bugs très difficilement corrigeables (dans le pire).

      Ajouter des constructions pour gérer la concurrence en C et C++ et en règle générale dans les langages orientées programmation système est à mon sens inévitable.

      • [^] # Re: Bof

        Posté par  . Évalué à 0.

        Et ce n'est pas parce que certains grincheux ont décidé que seule la norme C89 compte que ça va rester ainsi.

        N'empêche que si on vise la compatibilité Windows (et ses outils natifs, pas cygwin ou mingw), on est obligé de se limiter peu ou prou à C89.

        • [^] # Re: Bof

          Posté par  . Évalué à 3.

          MSVC++ ne supporte que OpenMP 2.0 alors qu'on en est à OpenMP 3.0 (et bientot 3.5 si je ne me trompe pas). Ça n’empêche pas les gens de programmer avec la dernière version d'OpenMP. MS devra finir par accepter certaines mises à niveau (que ce soit C99 ou C11 peut importe).

          • [^] # Re: Bof

            Posté par  . Évalué à 3.

            Je ne suis pas sûr de voir le rapport. OpenMP est très spécialisé par rapport à la quantité d'usages du C.
            Sinon, je suis d'accord, MS devra bien se mettre à la page un jour, mais quand ?

            • [^] # Re: Bof

              Posté par  . Évalué à 3.

              Je voulais juste expliquer que la demande finira par orienter l'offre. Les fonctionnalités d'OpenMP 3 (gestion du parallélisme de taches en plus du parallélisme de données) font qu'OpenMP devient une alternative intéressante pour le programmeur scientifique (généralement un physicien ou ingénieur en mécanique, etc., qui n'a pas de formation initiale en informatique) qui a besoin de faire plus qu'un #pragma omp parallel for dans son code. Or Microsoft essaie lentement mais surement d'entrer dans le domaine du calcul scientifique. Ça ne peut fonctionner que si les outils existent pour ceux qui font du HPC.

      • [^] # Re: Bof

        Posté par  (site web personnel) . Évalué à 3.

        J'aime bien suivre de loin ce que fais Charles H Moore, inventeur du Forth, et qui cherche toujours une voie parallèle intéressante. Il participe depuis des années à un processeur fortement parallèle dont la dernière version semble le GA144...

        http://www.greenarraychips.com/

        Évidement, Moore et son équipe ne programment pas en C ;-)

      • [^] # Re: Bof

        Posté par  . Évalué à 2.

        Juste une remarque, vu la description que tu en fais, il me semble que les fonctions de multithreading du C peuvent difficilement faciliter l'exploitation de l'Intel SCC.

        • [^] # Re: Bof

          Posté par  . Évalué à 3.

          Voyons voir. Avant, pas de multithreading et le C avait une sémantique séquentielle. Maintenant, le langage C a une sémantique qui admet l’exécution concurrente de plusieurs fils d’exécution, et donc de parallélisme potentiel. Avant, il fallait une bibliothèque externe au langage (mais il faut reconnaître que les bons compilo ont tous une certaine connaissance du modèle de threading lié à l'OS pour lequel ils génèrent du code). Désormais, il s'agit d'appels à une bibliothèque standard, ce qui implique que le compilo connait officiellement son existence et peut faire des trucs automagiques avec. Dans tous les cas il s'agit d'un mieux : avant C ne pouvait meme pas concevoir que SCC "existe" (techniquement il ne peut toujours pas, mais tu vois ce que je veux dire j’espère).

          Désormais, il est donc possible d'obtenir un code C multithreadé portable (et pas juste "conforme POSIX" ou "conforme WinThread" ou ...).

          Pour ce qui est de SCC spécifiquement, le MPB (message passing buffer) est une sorte de scratchpad utilisé pour 2 coeurs, et visible de tous les autres. Y accéder se fait via des coordonnées (x,y) sur la grille de processeurs. C64 dont je parlais précédemment a un scratchpad par coeur. Je ne vois pas trop la différence au final (mis à part les caches qui existent sur SCC que n'a pas C64 -- mais il se rattrape ailleurs).

          • [^] # Re: Bof

            Posté par  . Évalué à 2.

            Je vois ce que tu veux dire à propos du fait que la norme prévoit dorénavant le multithreading, mais en fait ce que je voulais dire, c'est précisément que C ne permet précisément pas en lui même une exploitation (du moins une exploitation efficace) du SCC. (et d'ailleurs je pense que ça serait une mauvaise idée de chercher à le faire, et que le "secret" de l'exploitation efficace d'une telle archi doit résider ailleurs, du moins tant que l'archi en question ne domine pas le monde)

            Après c'est une avancée sur le papier qui a été devancée par le fait que tout les environnements avec cibles dans laquelle le multithreading était pertinent autorisaient déjà le multithreading. C'est une avancée de par la précision que ça va apporter sur la normalisation de la sémantique et sur les possibilités de portabilité, mais ça reste limité aux cas classiques qui étaient déjà couverts, avec de la cohérence de cache et tout.

      • [^] # Re: Bof

        Posté par  (site web personnel) . Évalué à 2.

        (pas simplement l'ajustement de fréquence, mais aussi la variation de tension)

        Je ne comprends pas bien cette phrase, si le but est de baisser la consommation de la puce, baisser uniquement la fréquence fait augmenter la consommation de la puce (à cause des fuites statiques, la conso dynamique étant proportionnel à la fréquence et la durée d'une tache augmente avec la baisse de la fréquence).

        Est-ce que tu connais le document suivant ?
        http://mrl.cs.vsb.cz/people/gaura/agu/TimHPG2009.pdf

        Pour l'auteur, l'augmentation du temps de conception d'un code pour GPU devient tellement long, que bientôt, il sera plus simple et rapide d'avoir la même chose sur un cpu plus lent mais plus simple à coder. Il demande juste des instructions SIMD plus étendus.

        "La première sécurité est la liberté"

        • [^] # Re: Bof

          Posté par  . Évalué à 5.

          A propos de fréquence vs tension:

          Je ne comprends pas bien cette phrase, si le but est de baisser la consommation de la puce, baisser uniquement la fréquence fait augmenter la consommation de la puce (à cause des fuites statiques, la conso dynamique étant proportionnel à la fréquence et la durée d'une tache augmente avec la baisse de la fréquence).

          Alors d'une, je ne suis pas un expert, loin de la (d'ailleurs si tu regardes mes commentaires sur LinuxFR, j'ai plus tendance à parler compilos et programmation parallèle avec des bouts d'archi haut-niveau que de machins genre conception des processeurs ;-)). Donc je vais très probablement dire des conneries, et ce sera uniquement ma faute, pas celle des ingénieurs avec qui je bosse et qui expliqueraient ça bien mieux que moi.

          Tu as raison, en baissant la fréquence, on ne change rien a la conso statique. Cependant, l’idée est de pouvoir déterminer dynamiquement la charge des coeurs, et d'adapter en conséquence la fréquence du processeur. L'autre idée est que parfois, avec des puces qui contiendront des centaines, voire des milliers de coeurs, que la puce chauffera un peu trop. Plusieurs mécanismes devront du coup être disponibles sur architectures "manycore": la possibilité de couper un (ensemble de) CPU mais pas le cache/scratchpad ("clock gating"), couper totalement le cpu+mémoire locale ("power gating"), mais aussi simplement réduire la tension appliquée à un (ensemble de) coeur(s), ou simplement réduire la fréquence. La réduction de fréquence peut être utile si un coeur est peu chargé (mais a quand même du boulot ca faire qui arrive régulièrement) et attend que des requêtes vers la mémoire reviennent (le plus souvent des requêtes de type DMA, ou bien si tu as une techno de type SMT, un autre thread prend la main). La réduction de tension est bien entendu bien plus efficace, mais de ce que j'ai compris, c'est loin d’être instantané, i.e. pour la fréquence, on peut s'arranger en quelques cycles, alors que pour la tension, il faut attendre plusieurs centaines/milliers de cycles (encore une fois, j'ai peut-être mal compris ce que m'expliquaient les ingés).

          Concernant la présentation que tu donnes en lien : j'avais vu d'autres présentations par la même personne je crois bien (il a des présentations intéressantes en règle générale). Perso je déteste Cuda. C'est un mal nécessaire en attendant que certains modèles de programmation arrivent à s'imposer (ou que les langages "standard" intègrent ce qu'il faut de constructions concurrentes/parallèles pour devenir utilisables en environnement multithreadé), mais l'idée de devoir gérer explicitement ca peu pres tout, j'ai vraiment horreur de ça. D'ailleurs, Nvidia le sait bien, et ils se sont alliés avec Cray et 2-3 autres boites pour proposer une sorte de "standard" concurrent à OpenCL, mais plutôt à base de pragmas que d'API (comme cela si tu as un compilo intelligent, il peut générer de l'OpenMP, du Cuda, ou d'autres trucs en fonction du type d'accélérateur dispo sur la machine).

          Par contre, pour bosser sur un projet de système (système = cpu + softs bas-niveau + compilateurs haut niveau + demos sur applications réelles) "manycore" d'ici à l'horizon 2020, je pense que le monsieur ne se rend pas du tout compte de ce qui va être proposé et des contraintes dont il va falloir jouer pour arriver à produire des puces réellement dotées de centaines ou milliers de coeurs. Il veut absolument de la cohérence de cache par exemple, et tout laisse à penser que celle-ci ne sera au mieux que partielle -- i.e. soit on aura des scratchpads, soit des caches gérés par un logiciel (donc en gros il faudra un cache logiciel, ou bien l'application se chargera elle-même d'invalider les lignes), soit un hybride entre les deux. La cohérence totale est très probablement impossible pour un nombre de coeurs par puce élevé. J'aurais vraiment plein plein plein d'autres trucs à dire sur le sujet, mais j'ai déjà écrit un roman ... :-P

          • [^] # Re: Bof

            Posté par  (site web personnel) . Évalué à 2.

            Je suis de formation microelec, et j'ai bosser pour TI sur la lib de gestion de l'énergie bas niveau.

            Il utilisait 4 points de fonctionnement (0 25 50 100 % de fréquence avec la tension qui va avec), pour changer de tension, les latences étaient de l'ordre de la ms (commande d'un chip externe ). C'est pas grave pour diminuer la fréquence, mais il faut anticiper pour la remonter, sinon on plante le chip.

            Cette répartition "spread to deadline" est à la mode, mais je n'y crois pas trop. A l'utilisation, à part pour écouter un mp3, on a besoin du processeur à fond, pour que les applications soient fluides. Pour écouter un mp3, un arm7 suffit et consommera bien moins.

            De plus, on ne réduit que la consommation dynamique. Or avec les finesses de gravure actuelle, la conso statique est forte (fuite) et même dominante sur la dynamique. Cette conso est proportionnel à la tension et la surface du bloc. Dans le cas du passage à 50% de cpu, le cpu baisse sa conso mais celle du cache est toujours la même, ce qui fait que dans certain cas, le système consomme plus pour une tache à 50% qu'à 100% ! (c'est le cas des cpu intel, dont la baisse de puissance est juste une protection thermique)

            Je crois plus à un système stop-and-go et selon le temps prévu d'endormissement, on diminue (ou coupe) la tension ou pas. Dans certain système, il mette sur la ligne de l'alim une diode interne, pour tomber à une tension de rétention (genre 0.6V). Le système consomme beaucoup moins, juste parce que la tension appliqué à l'ensemble est plus faible. C'est bien plus rapide que de faire varier l'alim à découpage et cela fonctionne aussi pour les caches.

            Concernant la cohérence mémoire, je comprend le problème technique. Mais Cray a failli mourir en pensant que les codeurs arriveraient à s'en sortir. Il y a peut être un mode intermédiaire, par exemple avec une instruction barrière de cohérence mémoire explicite.

            je pense que le monsieur ne se rend pas du tout compte de ce qui va être proposé et des contraintes dont il va falloir jouer pour arriver à produire des puces réellement dotées de centaines ou milliers de coeurs. Il veut absolument de la cohérence de cache par exemple,

            Je pense au contraire qu'il est très conscient et dis que cela sera inutilisable, tellement cela sera compliqué.

            D'ailleurs, en regardant l'architecture des gpu nvidia, je me suis demandé pourquoi il n'existait pas de cpu équivalent. En gros, 16 MAC, un load/store avec un adressage complexe(2D ou 3D, +extraction de valeur), plusieurs milliers de registres pour diminuer la pression sur la mémoire, et un jeu d'instruction qui gèrent les matrices/vecteurs et d'autre type de donné vectoriel comme la couleurs de pixel en format exotique. Pourquoi un tel cpu ne pourrait pas exister ?

            "La première sécurité est la liberté"

            • [^] # Re: Bof

              Posté par  . Évalué à 4.

              De plus, on ne réduit que la consommation dynamique. [...] Dans le cas du passage à 50% de cpu, le cpu baisse sa conso mais celle du cache est toujours la même, ce qui fait que dans certain cas, le système consomme plus pour une tache à 50% qu'à 100% ! (c'est le cas des cpu intel, dont la baisse de puissance est juste une protection thermique)

              Alors, j'essaie de parler sans révéler quoi que ce soit de confidentiel, ce qui rend mes propos un peu trop vagues. Je vais essayer de préciser.

              L'idée est de pouvoir couper l'alimentation d'une partie des caches/scratchpads et de la RAM quand on se fiche de ce qu'ils contiennent (le write-back est terminé, etc.).

              Pour ce qui est de la cohérence mémoire, je ne dis pas qu'il ne faut pas fournir des garanties, juste que le modèle de « cohérence » (memory consistency, et pas memory coherence) doit être capable de passer à l'échelle. En l'occurrence, si on te file un software cache, tu peux changer la politique de gestion de la mémoire en fonction de ce que tu désires. Et oui, bien entendu, s'il n'y a pas de mécanisme implicite de cohérence mémoire, alors l'archi propose les briques de base pour avoir des barrières mémoire. L'idée n'est pas de déporter tout le poids de la cohérence sur les épaules du programmeur, loin de là. L'idée est de fournir les blocs hardware de base, et ensuite de laisser les programmeurs de middleware programmer le cache logiciel qui convient en fonction des objectifs.

              J'aurais beaucoup plus de choses à dire, mais je crois qu'à ce niveau, il faudrait que je me sorte les doigts, et que j'écrive un journal sur le sujet des super-calculateurs de demain. :)

          • [^] # Re: Bof

            Posté par  . Évalué à 1.

            je pense que le monsieur ne se rend pas du tout compte de ce qui va être proposé et des contraintes dont il va falloir jouer pour arriver à produire des puces réellement dotées de centaines ou milliers de coeurs.

            Quel est l'intérêt exactement d'avoir des centaines ou milliers de coeurs ? Il n'y a quasiment pas d'applications qui vont passer à l'échelle, de toute façon.

            La tendance actuelle montre que le nombre de coeurs va augmenter lentement plutôt que rapidement, les constructeurs en profitant pour ajouter des possibilités d'exécution à chaque coeur, pour grossir les caches et pour intégrer de plus en plus de fonctions système (autrefois dévolues aux chipsets).

            • [^] # Re: Bof

              Posté par  (site web personnel) . Évalué à 2.

              Les GPU ont déjà plusieurs milliers de shader.

              Ensuite, c'est vrai que j'ai du mal à comprendre pourquoi il n'existe pas plus d'instructions rapides dédiés comme les nouvelles instructions pour faire de l'AES. Le jeu d'instruction du supercalculateur hitachi suit ce principe.

              Les x86 pourrait avoir un banc de registre de stockage de 256 registres ayant pour seul fonctionnalité, l'échange avec la mémoire ou avec les registres généraux, ensuite le coeur out-of-order pourrait faire ce qu'il veut de l'information. Cela diminuerait la pression sur la mémoire si plus de registre était disponible.

              "La première sécurité est la liberté"

              • [^] # Re: Bof

                Posté par  . Évalué à 2.

                Les GPU ont déjà plusieurs milliers de shader.

                Oui, les GPU existent déjà, et on voit bien qu'il y a très peu de tâches qui profitent d'un portage vers le GPU.

                Cela diminuerait la pression sur la mémoire si plus de registre était disponible.

                Je ne comprends pas trop l'intérêt. Le stockage de valeurs temporaires sera toujours en cache, il n'y a donc pas de pression sur la mémoire.

                • [^] # Re: Bof

                  Posté par  (site web personnel) . Évalué à 2.

                  Le cache est derrière le système mémoire. Cela reste interne à la puce, mais c'est toujours plus lent que l'accès aux registres. De plus, le instructions mémoires sont les instructions les plus lente avec le plus de latence potentiel (page miss, cohérence de cache, alias avec un write buffer en lecture, etc...)

                  Si tu regardes un cpu classique, 2 alu sont saturé avec une seul unité de load/store. Alors avec 16 ALU, les besoins sont encore supérieurs.

                  "La première sécurité est la liberté"

                  • [^] # Re: Bof

                    Posté par  . Évalué à 2.

                    Que veux-tu faire avec 16 ALU par coeur (sauf SMT) ? La majorité du code est beaucoup trop séquentiel pour exploiter un tel nombre d'unités en parallèle.

                    • [^] # Re: Bof

                      Posté par  (site web personnel) . Évalué à 2.

                      D'où la proposition de manipuler de base des types plus complexe comme des matrices, des vecteurs et de matrice diagonale. De toute façon, un tel cpu serait là pour faire du calcul, qui a besoin 90% du temps de faire des MAC, et le reste de faire des load en mémoire, avec des calculs d'adresse plus ou moins simple.

                      "La première sécurité est la liberté"

                      • [^] # Re: Bof

                        Posté par  . Évalué à 2.

                        De toute façon, un tel cpu serait là pour faire du calcul, qui a besoin 90% du temps de faire des MAC, et le reste de faire des load en mémoire, avec des calculs d'adresse plus ou moins simple.

                        C'est un GPU, quoi ? :)

                        • [^] # Re: Bof

                          Posté par  (site web personnel) . Évalué à 2.

                          Sauf pour la cohérence mémoire, la pagination, le changement de contexte et la gestion des interruption. C'est pas grand chose, mais ce ne sont pas des détails :)

                          "La première sécurité est la liberté"

                    • [^] # Re: Bof

                      Posté par  (Mastodon) . Évalué à 2.

                      Dans des codecs vidéos, il y a pas mal de parallélisme (surtout à grain fin) assez peu exploité pour l'instant. Après, on peut aussi penser à avoir des environnements graphiques qui ne calcule plus des triangles mais des rayons et là, c'est la fête, c'est le prototype même du truc complètement parallèle (il y avait eu un journal il y a quelques années sur le sujet).

                      • [^] # Re: Bof

                        Posté par  (site web personnel) . Évalué à 2.

                        Chaque rayon est indépendant. Un gusse avait même fait un hardware avec un simple accumulateur pour faire le calcul, mais il restait quand même le problème de l'accès rapide à la mémoire.

                        "La première sécurité est la liberté"

              • [^] # Re: Bof

                Posté par  . Évalué à 2.

                Ensuite, c'est vrai que j'ai du mal à comprendre pourquoi il n'existe pas plus d'instructions rapides dédiés comme les nouvelles instructions pour faire de l'AES. Le jeu d'instruction du supercalculateur hitachi suit ce principe.

                C'est pas une histoire d'architecture RISC vs CISC ?

                Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

                • [^] # Re: Bof

                  Posté par  (site web personnel) . Évalué à 4.

                  Non, cette opposition est parfaitement stupide. En premier lieu, elle qualifie le jeu d'instruction et non l'architecture du cpu.

                  La création des sparc et mips (début année 80) est venu du constat que les instructions complexes du VAX n'étaient jamais générés par un compilateur C. De plus, les instructions multicycles se pipelinent mal et donc ralentissent le processeur. Pour raccourci le pipeline, on met cote à cote ALU et unité mémoire, au lieu de pouvoir faire une lecture mémoire, une opération, et une écriture mémoire. Chaque accès mémoire passe par un registre, cela diminue la latence du CPU.

                  Aujourd'hui, si on regarde le jeu d'instruction PPC, il ne lui reste plus que la taille fixe de l'instruction à 32 bits, pour diminuer la complexité du décodeur (la grammaire du jeu d'instruction x86 est ambigu !). Même ARM est passé à un mode mixte 16/32 bits pour diminuer la taille du binaire tout en restant performant (thumb v2)

                  Un x86 passe aujourd'hui par un mode de traduction en µinstruction interne qui sont gérés par un cpu d'architecture différente (le P4 en interne, était une sorte de VLIW). Le jeu d'instruction est maintenant bien décorrélé de l'architecture.

                  "La première sécurité est la liberté"

                  • [^] # Re: Bof

                    Posté par  . Évalué à 2.

                    Il y a quand même une différence entre avoir juste un mode 16/32bit, qui est plus compliqué a décoder qu'un mode 32bit seulement ok mais bien plus simple qu'un jeu d'instruction avec la possibilité d'avoir des instructions énormes à la CISC x86|VAX.

                    "Le jeu d'instruction est maintenant bien décorrélé de l'architecture."
                    Ce n'est pas vraiment nouveau.
                    Le jeu d'instruction a quand même des conséquences: un registre caché ou un registre accessible par le compilateur, ce n'est pas la même chose..

            • [^] # Re: Bof

              Posté par  . Évalué à 2.

              Quel est l'intérêt exactement d'avoir des centaines ou milliers de coeurs ? Il n'y a quasiment pas d'applications qui vont passer à l'échelle, de toute façon.

              C'est parce que tu penses en termes de threads « lourds ». Quand tu as 2000 cœurs à ta disposition, du moment que tu as suffisamment de tâches à effectuer en parallèle, même s'il y a des dépendances, il suffit de « penser grain fin ».

              • [^] # Re: Bof

                Posté par  . Évalué à 2.

                Quand tu as 2000 cœurs à ta disposition, du moment que tu as suffisamment de tâches à effectuer en parallèle, même s'il y a des dépendances, il suffit de « penser grain fin ».

                Ah, c'est tout bête, pourquoi n'y a-t-on pas pensé auparavant.
                Sérieusement, dans quelle situation as-tu 2000 tâches à effectuer en parallèle ? Je parle de tâches qui bouffent du CPU, pas qui attendent qu'une I/O s'effectue.

                • [^] # Re: Bof

                  Posté par  . Évalué à 2.

                  Pour toutes les applications scientifiques, où tu as un maximum de traitement basique (souvent identique) à faire en parallèle.

                  • [^] # Re: Bof

                    Posté par  . Évalué à 2.

                    Il me semble que les applications scientifiques profitent en général assez bien de la vectorisation ?

                • [^] # Re: Bof

                  Posté par  . Évalué à 2.

                  Ah, c'est tout bête, pourquoi n'y a-t-on pas pensé auparavant.

                  Il existe bien entendu des modèles d'exécutions qui privilégient le grain fin (l'un des plus connus est l'exécution par flot de données, le dataflow).

                  En pratique tu as tout plein de cas où effectivement les gens ne pensent pas de cette manière, et les modèles d'exécution « à grain fin » ne sont pas si courants que ça. Bon, je vais essayer de faire au moins un journal qui va parler de tout ça.

          • [^] # Re: Bof

            Posté par  (site web personnel) . Évalué à 1.

            Il y a aussi des CPUs montres recemment dans des expos qui ont des instructions type STM
            pour faire des transactions / rollbacks.
            Le concept est present dans Haskell.

  • # Question d'alignement

    Posté par  (site web personnel) . Évalué à 3.

    J'ai une question qui peut paraitre un peu con mais dans les jeux d'optimisation par défaut, les compilateurs n'alignent pas déja les structures ?

    Je ne sais pas ce qu'il en est pour le x86 mais sur les archis héritées du 68k le non alignement se paye au prix fort.

    Par exemple sur coldfire, le processeur peut fonctionner en mode 8, 16 ou 32 bits. Une fois que tu as choisis, il est impératif (pas obligatoire hein) d'aligner tes datas sur cette taille sinon ton temps d’exécution explose.

    • [^] # Re: Question d'alignement

      Posté par  (site web personnel) . Évalué à 5.

      Alignée oui... mais sur combien ?
      Personnellement (pour des questions de perfs) je veux des allocations alignées sur des pages (4Ko), voire des grandes pages (4Mo), fort heureusement, le compilo ne le fait pas de base.

    • [^] # Re: Question d'alignement

      Posté par  (site web personnel) . Évalué à 2.

      Ah et d'ailleurs l'alignement dont tu parles (sur un mot processeur) est requis par la norme je crois. (mais je n'affirmerais pas)

    • [^] # Re: Question d'alignement

      Posté par  . Évalué à 2.

      Oui mes des fois tu veux justement que ce ne soit pas aligné. Dans certains cas tu préfères économiser de la place plutôt que de gagner en performance. Tu as aussi les cas où les données viennent d'un autre monde avec des règles d'alignement différentes. Il y a aussi les cas où tu imbriques des structures. Bref au final les compilo ont chacun leurs directives pour gérer l'alignement. Donc que ce soit standardisé n'est finalement pas plus mal.

  • # Vendeurs : faux ami ?

    Posté par  . Évalué à 7.

    La précédente norme C99 a eu beaucoup de mal à s'imposer auprès de certains vendeurs, certains refusant même de l'implémenter (notamment un vendeur d'environnement Basic, situé à Redmond).

    J'aurais plutôt mis ici éditeur. Il est souvent plus judicieux de remplacer ce mot lors de la traduction d'un texte anglais par un mot un peu plus approprié.

  • # Incompatibilité ?

    Posté par  . Évalué à 4.

    Est-moi qui comprends mal ou rendre facultative « la prise en charge des nombres complexes » alors qu'ils étaient « obligatoires dans C99 » est une aberration pour un standard ? La compatibilité ascendante n'est pas assurée ?

    • [^] # Re: Incompatibilité ?

      Posté par  . Évalué à -2. Dernière modification le 27 décembre 2011 à 23:57.

      Comme dit dans la news, C99 n'est pas/peu utilise. Donc la compatiblite sur un standard non implemente... c'est peut etre pas si grave.

      • [^] # Re: Incompatibilité ?

        Posté par  . Évalué à 2.

        La dépêche dit que « C99 a eu beaucoup de mal à s'imposer auprès de certains vendeurs » pas qu'elle n'est pas implémentée (à l'exception de Microsoft).

        • [^] # Re: Incompatibilité ?

          Posté par  (site web personnel) . Évalué à 2.

          Surtout que bon, certes je suis loin d'être très calée en développement de compilateurs et tout ça, mais gérer les nombres complexes ça doit quand même pas être le truc le plus compliqué à faire, Si ?

          • [^] # Re: Incompatibilité ?

            Posté par  . Évalué à 0.

            Des langages tel que Fortran, Common Lisp, Ada les implémentent en standard. Quant à la complexité de la chose elle ne doit pas être si terrible puisqu’elle était la norme en C99.

          • [^] # Re: Incompatibilité ?

            Posté par  (site web personnel) . Évalué à 4.

            Il faut quand-même implémenter un petit paquet de fonctions numériques, et si on produit un compilateur C pour un type de processeur principalement utilisé dans le petit électro-ménager, je comprends que la pression ne soit pas énorme, énorme…

            • [^] # Re: Incompatibilité ?

              Posté par  . Évalué à 2.

              Bon comme ça me tarabuste j'ai été voir le dernier brouillon de la norme C99 ISO/IEC 9899:TC3 WG14/N1256, « Committee Draft », 7 septembre 2007 : les complexes sont en annexe G, annexe qui est facultative (voir page 467) !

              Annex G

              (informative)

              IEC 60559-compatible complex arithmetic

              G.1 Introduction

              1 This annex supplements annex F to specify complex arithmetic for compatibility with
              IEC 60559 real floating-point arithmetic. Although these specifications have been
              carefully designed, there is little existing practice to validate the design decisions.
              Therefore, these specifications are not normative, but should be viewed more as
              recommended practice. An implementation that defines
              _STDC_IEC_559_COMPLEX _ should conform to the specifications in this annex.

  • # moar features

    Posté par  . Évalué à 8.

    Certains ont parlé de surcharge des fonctions, mais une feature du C++ que je trouverais bien plus utile serait d'ajouter au C une forme simple (sans arguments optionnels ni variadiques) de templates. C'est vraiment ce qui me manque le plus, l'absence de types paramétrés interdit d'écrire des structures de données génériques (maps, vecteurs, etc.). Je ne dis pas qu'il faut quelque chose d'aussi compliqué que la STL, mais pouvoir écrire map simplifierait énormément la vie... et diminuerait le copier-coller de code.

    Sur ce je me prépare à me faire huer :)

    The cake is a lie.

    • [^] # Re: moar features

      Posté par  (Mastodon) . Évalué à 2.

      En fait, c'est pas si simple que ça. Déjà premièrement, les structures de map, il en existe dans toutes les bonnes bibliothèques C de base (GLib, Eina, etc). Si on prend l'exemple de la GLib, elle stocke un pointeur, c'est-à-dire une référence. Et c'est, à mon avis, la meilleure façon de faire. Parce que dans le cas de la STL, le stockage se fait par valeur, ce qui implique (souvent) une copie (quand on n'utilise pas de pointeur). Et donc, ça implique d'avoir un opérateur de copie pour ne pas leaker à la moindre insertion d'une structure avec des indirections. Et si vraiment tu veux stocker des valeurs, comme indiqué plus haut, il existe sys/queue.h (sur les BSD du moins).

      • [^] # Re: moar features

        Posté par  . Évalué à 5.

        Ceci dit, avec la glib, souvent tu te retrouves à devoir gérer des listes ou des tables de hashage remplies de pointeurs vers une structure de données qui fait à peine plus que la taille dudit pointeur (genre une structure à deux ou trois éléments, comme une GValue par exemple). À ce moment-là, je doute que la copie implique un problème de performance (je dirais plutôt le contraire), par contre ça simplifie beaucoup la gestion du cycle de vie de tels petites structures fonctionnelles.

        En fait, en pratique, quand tu as une table de hashage celle-ci a le plus souvent l'ownership sur les objets qu'elle contient, donc ça a du sens d'"include" par valeur les éléments dans la structure de données, même si on peut éventuellement les accéder par référence par la suite.

        C'est probablement le cas où les templates sont les plus utiles en fait, et réduisent beaucoup le bookkeeping et les bugs. Après, on peut appeler ça templates, types paramétriques ou génériques, osef. Mais la fonctionnalité serait sympa.

        • [^] # Re: moar features

          Posté par  (Mastodon) . Évalué à 1.

          En fait, en pratique, quand tu as une table de hashage celle-ci a le plus souvent l'ownership sur les objets qu'elle contient,

          C'est marrant, mon expérience me dit exactement l'inverse, que la table n'a pas l'ownership et que l'appelant doit se démerder pour gérer sa mémoire. Ce qui fait qu'on peut y mettre des pointeurs vers des structures statiques sans problème.

          • [^] # Re: moar features

            Posté par  . Évalué à 1.

            Bha au niveau de la glib, tu associes un callback avec la hashtable pour détruire les objets que tu mets dedans. En C on ne peut pas détruire un objet de façon générique, il suffit d'avoir un pointeur dans le tas...

            Mettre des objets statiques dans une hashtable est facile, suffit de mettre un callback qui fait rien... Par contre mettre des éléments statiques dans une hashtable me paraît avoir un effet limité la plupart du temps par rapport à une structure statique un tant soit peu efficace...

          • [^] # Re: moar features

            Posté par  . Évalué à 2.

            Je pense qu'il voulait parler de l'ownership conceptuel, pas de l'ownership physique d'une implémentation donnée.

      • [^] # Re: moar features

        Posté par  . Évalué à 6.

        C'est justement le problème, en stockant un void* on perd à la fois l'information de type (donc de la sécurité), et on oblige potentiellement à allouer quelque chose sur le tas. Par exemple, si ma valeur est un uint32_t, il me faut l'allouer sur le tas pour qu'il persiste. Avec une map C++ j'aurais pu faire map et c'est plus efficace en stockage.

        Les templates laissent le choix, je pense, si tu veux stocker un pointeur tu peux, si tu veux stocker une valeur (primordial quand tu écris un vector générique, par exemple, ou une matrice) c'est possible aussi. En C si tu veux stocker par valeur faut coder une structure de donnée par type (ou utiliser des macros immondes).

        Après pour l'opérateur de copie, en C, je vois pas trop d'inconvénient à utiliser memcpy ^^

        The cake is a lie.

        • [^] # Re: moar features

          Posté par  (Mastodon) . Évalué à 1.

          en stockant un void* on perd à la fois l'information de type (donc de la sécurité)

          Normalement, tu ne stockes qu'un seul type de données dans une map. La seule contrainte, c'est que tu ne peux pas le vérifier à la compilation, c'est au programmeur de faire attention.

          on oblige potentiellement à allouer quelque chose sur le tas

          Si pour toi, pointeur == alloué sur le tas, je crois que tu n'as pas bien saisi ce qu'est un pointeur.

          Avec une map C++ j'aurais pu faire map et c'est plus efficace en stockage.

          Effectivement, pour chaque élément ajouté à la map (implémenté avec un arbre bicolore), tu as déjà 3 pointeurs (fils droit, fils gauche et parent) et une couleur. Donc, ton économie de bout de chandelle, elle ne change pas grand chose...

          Après pour l'opérateur de copie, en C, je vois pas trop d'inconvénient à utiliser memcpy ^^

          Sauf que si ta structure contient un pointeur vers une structure allouée dynamiquement, tu ne sauras jamais quand tu dois la désallouer.

          • [^] # Re: moar features

            Posté par  . Évalué à 3.

            Normalement, tu ne stockes qu'un seul type de données dans une map. La seule
            contrainte, c'est que tu ne peux pas le vérifier à la compilation, c'est au
            programmeur de faire attention.

            Quand j'utilise une map donnée, elle a effectivement un type de clé et un type de valeur bien définis. Le problème reste que je n'ai pas envie d'écrire une structure de map pour chaque paire de types avec lesquels je compte l'utiliser, c'est bien mieux d'avoir une seule définition de map générique... Et avec du void*, à l'utilisation, pas moyen de savoir ce que contient réellement cette map, ce qui fait que C n'est pas très type-safe.

            on oblige potentiellement à allouer quelque chose sur le tas

            Si pour toi, pointeur == alloué sur le tas, je crois que tu n'as pas bien saisi ce
            qu'est un pointeur.

            Note le "potentiellement". Si je veux stocker un int dans un vecteur qui dure plus longtemps que mon scope actuel, avec la solution à base de void* je suis bien obligé d'allouer sur le tas de quoi stocker mon int, puisque les adresses sur la pile ne seront pas "valides" suffisamment longtemps. Allouer n'est pas gratuit, surtout dans un langage tel que C.

            Effectivement, pour chaque élément ajouté à la map (implémenté avec un arbre
            bicolore), tu as déjà 3 pointeurs (fils droit, fils gauche et parent) et
            une couleur. Donc, ton économie de bout de chandelle, elle ne change pas grand chose...

            Si j'implémente une liste générique et que je l'utilise pour stocker des int, il faut que j'alloue une cellule sur le tas par int ? Et un pointeur n'est pas gratuit, c'est une source possible de cache miss chaque fois que tu le déréférences (alors que si tu stockes l'int dans la cellule de liste, cette cellule est déjà dans le cache).

            Sauf que si ta structure contient un pointeur vers une structure allouée
            dynamiquement, tu ne sauras jamais quand tu dois la désallouer.

            Ca je suis d'accord, mais en général dans une structure on déplace, on ne fait pas vraiment de copie. Si tu veux gérer le cas de la délétion de la structure, 1/ avec des void* le problème se pose aussi, 2/ tu peux donner une fonction "destructeur" au moment de détruire la structure (ou avant), qui se chargera (ou pas) de désallouer ce qu'il faut. Ce problème est inhérent aux langages à gestion manuelle de la mémoire, pas aux templates...

            The cake is a lie.

        • [^] # Re: moar features

          Posté par  . Évalué à 3.

          Par exemple, si ma valeur est un uint32_t, il me faut l'allouer sur le tas pour qu'il persiste.

          Non, tu le convertis en void*.
          (ça ne marche pas si les pointeurs font moins de 32 bits, mais bon)

  • # Structures anonymes

    Posté par  (site web personnel) . Évalué à 2.

    OK, j'avoue que j'ai la flemme de me taper la norme ISO pour avoir la réponse à ma question, mais je me demandais :

    Si au lieu de l'exemple qui est montré dans le journal, on met plutôt :

    struct A {
      int b;
      int c;
    };
    
    struct B {
      int a;
      struct B;
    };
    ...
    B bidule;
    bidule.b = 3;
    
    

    C'est censé marcher aussi, ou pas ? Je constate qu'avec gcc 4.6.2, l'exemple donné dans le journal compile, mais pas celui-ci (sauf à ajouter -fms-extensions), donc j'aurais tendance à dire que non, c'est pas dans la norme C11, mais comme c'est encore qu'une implémentation partielle, que la norme finale vient de sortir et que j'ai pas le courage de me la fader, je demande au cas où quelqu'un saurait :p

    En tout cas à vue de nez permettre cela m'a l'air plus intéressant, et je trouverais dommage que le C11 ne permette les structures anonymes qu'«à moitié» (notamment ça m'a l'air potentiellement pratique quand on fait de la programmation pseudo-objet en C, mais peut-être que je me trompe et que ce serait horriblement pas propre et source de bugs).

    • [^] # Re: Structures anonymes

      Posté par  . Évalué à 2.

      struct B {
        int a;
        struct B;
      };
      

      C'est censé marcher aussi, ou pas ?

      Encore heureux que ça ne passe pas. C'est une structure récursive...

      ça oui:

      struct B {
        int a;
        struct B *b;
      };
      
  • # C4droid

    Posté par  . Évalué à -10.

    Disponible pour ecrire, compiler et tester vos applications en C sur plateforme Android pour 1,5$. Le module GCC etant gratuit. ( Cela inclut-il C11, a priori non )
    De plus, des referentiels exhaustifs de langages sont disponibles gratuitement ( HTML5, CSS3, JavaScript, PHP, C, ActionScript, JQuery, etc ... ) Un apport non negligeable aux developpeurs debutants et nomades qu'Android. Et cela devrait aller en s'ameliorant avec les semaines qui passent.

    Bon code a tous :)

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.