Le C a été (est) utilisé pour les GPU parce que ceux-ci étaient (sont) primitifs. Il s'agissait de grosses usines vectorielles s'effondrant au premier branchement venu, dépourvu de mémoire virtuelle ou de mécanismes de protection, avec une synchronisation inexistante ou bancale, seulement capables de recevoir passivement des ordres du CPU et tout juste aptes à signaler la fin du boulot au CPU. On leur envoyait un gros paquet de données via un bus PCIe bien lent et un passage en kernel mode, puis on récupérait quelques microsecondes plus tard un gros paquet de données via un bus PCIe bien lent.
Ça c'était (c'est) le GPU de grand-papa. Ce qui est en train d'apparaître maintenant, notamment chez AMD (mais les autres suivent, y compris les éditeurs logiciels), ce sont des coeurs GPU intégrés au CPU, toujours vectoriels mais beaucoup pus généralistes, ayant résolu à peu près tous les points mentionnés ci-dessus. Ne reste plus que l'absence de pile d'appels, ce qui sera sans doute résolu dans une ou deux générations.
Donc oui on va faire de plus en plus appel au GPU, mais ce ne sera certainement pas avec du C.
* D'abord parce que personne ou presque n'a envie de programmer en C : peu productif, risqué, etc.
* Ensuite parce qu'écrire ton code dans deux langages, ça veut dire écrire plein de plomberie pour faire cohabiter les deux et beaucoup de redondance.
* Enfin parce que beaucoup d'algorithmes perdent de leur intérêt si tu dois préalablement transformer tes données d'un format vers un autre, et vice-versa au retour.
Sceptique ? Jette un coup d'oeil au
projet Sumatra. C'est un gros effort d'AMD et d'autres pour programmer le GPU directement en Java (avec bien sûr des limitations concernant les parties à exécuter sur le GPU mais pas tant que ça).
Plus généralement tout ce problème s'inscrit dans la perspective du calcul hétérogène dans le nuage: autrement dit la capacité à exploiter des architectures spécifiques dans le nuage, tout en payant la plus petite taxe de virtualisation possible. Un acteur comme Microsoft mise pour ça sur un bytecode dont certaines propriétés (isolation mémoire, absence de deadlock avec l'extérieur, etc) sont prouvables (de façon à lever la taxe) et qui aura pour cibles de compilation tant des CPU que des GPU ou autres. Si ce bytecode sera vraisemblablement de plus bas niveau que celui de dotnet, je doute qu'on puisse y compiler efficacement du C. D'ailleurs MS développe un langage de plus haut niveau et plus sécurisé que le C mais d'assez bas niveau pour être dédié à la programmation système tout en tournant sur ce bytecode ; il serait destiné aux pilotes de péirphériques et au coeur du système.
Non. Mais coûteux, oui, tout comme l'ensemble shared_ptr + weak_ptr + allocateur par tas. Souvent moins en fait.
Non, pas des millions d'objets. D'abord parce qu'on n'a pas à visiter les anciens objets (génération 2 - il faudra seulement visiter les pages mémoire modifiées) ni les objets inaccessibles. Ensuite parce que la pile d'appels est en général assez compacte. Enfin parce que c'est un problème mémory-bound mais que les nouveaux objets sont tous dans le cache L3 ou inférieur.
Des algos de ce genre existent, oui, mais ils obligent à utiliser des formes de synchronisation à tel ou tel moment et ne sont donc pas forcément plus intéressants. Comme d'hab il n'y a pas de magie. A ma connaissance (mais je ne suis pas spécialiste) il est généralement plus rapide d'arrêter les threads (voire de les arrêter indépendamment pour les serveurs webs) mais de ne faire que le strict minimum à ce moment-là et reporter le reste de la charge à plus tard.
Partager