Wikilivres
frwikibooks
https://fr.wikibooks.org/wiki/Accueil
MediaWiki 1.45.0-wmf.4
first-letter
Média
Spécial
Discussion
Utilisateur
Discussion utilisateur
Wikilivres
Discussion Wikilivres
Fichier
Discussion fichier
MediaWiki
Discussion MediaWiki
Modèle
Discussion modèle
Aide
Discussion aide
Catégorie
Discussion catégorie
Transwiki
Discussion Transwiki
Wikijunior
Discussion Wikijunior
TimedText
TimedText talk
Module
Discussion module
États généraux du multilinguisme dans les outre-mer/Thématiques/Les technologies de la langue, la présence des langues sur la toile et sur les réseaux sociaux
0
48208
744334
677605
2025-06-08T19:40:25Z
2A01:CB18:1150:4600:C5FF:3372:4F9:EE19
/* Expert 2 : Marcel Diki Kidiri (Groupe MAAYA) */Correction "en train" (et pas entrain qui est un nom commun)
744334
wikitext
text/x-wiki
==Présentation générale==
Internet et les technologies du numérique offrent de nouvelles opportunités pour la vitalité des langues, leur valorisation, leur transmission et leur enseignement. Les technologies de la langue, si elles sont développées pour les langues régionales, sont de nature à répondre aux besoins d’aide à la traduction et à l’interprétation pour les usagers des services publics.
Dans cette perspective, il était nécessaire de faire un point sur la nature et l’avancée des technologies de la langue, de mener une réflexion sur la façon dont elles pourraient être utilisées pour faciliter le multilinguisme et d’évaluer la nature et la taille de l’effort à effectuer pour doter les langues d’outre-mer de telles technologies.
Le développement de la diversité culturelle et linguistique sur internet nécessite également une meilleure connaissance de la présence des langues sur internet, ainsi qu’un accompagnement pour la constitution de réseaux sociaux et de communautés de locuteurs.
==Table-ronde==
===Propos introductif : [http://www.wikimedia.fr/salari%C3%A9s Adrienne Alix] ([[w:Wikimedia|Wikimédia]] France)===
Je vais vous parler ici avec un regard très naïf et qui découvre, je ne suis ni spécialiste des langues, ni des outre-mer, par contre, un peu plus du numérique et je vais essayer d’introduire cette deuxième table ronde en montrant un peu les opportunités et l’intérêt du numérique et d’internet pour la valorisation, la préservation, la diffusion des langues d’outre-mer tout en vous faisant part de mon étonnement, ce matin, de ne pas avoir vu ou entendu parler à aucun moment d’internet ou de quoi que ce soit qui puisse faire penser au numérique. Cela me démangeait d’en parler et je me suis dit que j’allais attendre cet après-midi pour pouvoir en parler tous ensemble.
Pour schématiser très rapidement, ce qui est pour moi le fondement d’internet, c’est tout d’abord un réseau décentralisé, quelque chose qui, dans sa conception, est totalement indépendant techniquement de toute structure étatique ou autre, cela n’a pas été construit pour ça, c’est quelque chose qui a été fait pour le partage, pour la circulation de l’information, c’est un réseau qui permet l’initiative individuelle et l’initiative collective sans demander à qui que ce soit avant de le faire. C’est donc, à mon sens, un des outils les plus pratiques, un outil idéal pour la diffusion, la préservation et le travail sur les langues.
J’ai entendu, ce matin, beaucoup de réflexions sur les problèmes avec l’institution Éducation nationale par exemple, ou ce qu’on en attend, ce qu’on lui reproche. S’il y a un espace de liberté beaucoup plus grand où l’on a pas à demander ou avoir besoin d’une loi, c’est bien internet.
Si vous voulez voir comment on peut faire démarrer une langue rare, une langue peu parlée, peu dotée, comme le dit monsieur [http://llacan.vjf.cnrs.fr/pers/p_diki.htm Diki Kidiri], je vous invite à lire le rapport qu’il a fait il y a déjà cinq ans, sur comment assurer la présence d’une langue sur le [[w:Cyberespace|cyberespace]] et qui, pour moi, était quelque chose d’assez fondamental pour comprendre comment une langue qu’il appelle « peu dotée », avec peu de ressources écrites et peu de ressources numériques, peut avoir sa place sur internet.
Je vais vous parler de quelque chose que je connais plus particulièrement et qui me semble être un excellent vecteur des langues, c’est [[w:Wikipédia|Wikipédia]]. Je vais d’abord faire un petit point sur les problématiques que j’ai pu relever sur les langues. Quelle est la place que peuvent prendre les langues d’outre-mer, les langues de France sur Internet ? Il y a un certain nombre de problématiques pas forcément insurmontables mais qui se posent actuellement.
*La première, c’est la mesure de la place des langues. Mesurer combien il y a de pages web en français, en allemand, en anglais, en créole, dans n’importe quelle langue est quelque chose de difficile. Les moteurs de recherche n’indexent pas toutes les pages. C’est à dire que, sans savoir ce qui existe, c’est difficile de pouvoir promouvoir une langue, donc c’est un des problèmes pour trouver la place des langues sur le numérique. Google, le moteur de recherche le plus pratiqué au monde, ne propose son interface qu’en cent cinquante langues, ce qui n’est pas énorme, et fait un travail sérieux de résultats de moteur de recherche qu’en environ trente cinq langues, donc on est très loin de pouvoir faire émerger la diversité.
*Deuxième problématique importante, celle de la fixation écrite de la langue, qui n’est pas spécifique au numérique mais qui se pose forcément sur internet puisque internet est principalement un internet écrit.
*Troisième point, vouloir faire exister une langue sur internet nécessite une traduction des interfaces des logiciels qui permettent de produire du contenu pour qu’il y ait une réelle appropriation par les locuteurs.
*Et puis, dernier problème, beaucoup plus pratique, celui de la connexion à internet qui n’est pas forcément très évidente suivant là où l’on se trouve.
Donc, les bases d’un multilinguisme sur internet assumé, où on puisse s’exprimer sans aucun problème, ne sont pas forcément simples, mais on a quand même la possibilité, pour chaque langue, de trouver sa place, si elle est portée par une communauté de locuteurs active, motivée et qui intègre les enjeux du numérique pour la diffusion d’une langue en dehors d’une communauté.
J’en arrive maintenant au sujet que je connais le mieux et qui me semble être un bon exemple de multilinguisme, qui est l’encyclopédie Wikipédia que vous connaissez probablement en français, en anglais, peut-être moins dans d’autres langues, et qui a la particularité d’être collaborative, ouverte à tous, il n’y a pas de barrière à l’écriture pour tous ceux qui veulent contribuer, qui est diffusée sous une [[w:Licence libre|licence libre]] qui permet donc une réelle diffusion, redistribution, réappropriation, remixage, sous n’importe quel support et qui est, dans son essence même, multilingue, c’est-à-dire qu’on n’est pas dans un concept de traduction d’une langue à l’autre, mais de développement totalement autonome de chaque langue, à partir du moment où elle a une communauté de locuteurs qui a pris en charge la création d’une version linguistique de l’encyclopédie.
Pour vous donner une idée, en dix ans, on est passé du Wikipédia en anglais né en 2001 à 283 éditions linguistiques totalement autonomes, dont une quarantaine ont plus de cent mille articles, et qui comportent des langues extrêmement parlées mais aussi des langues extrêmement peu parlées suivant la communauté qui va la porter. En français on est à un million deux cent mille articles.
Autour de Wikipédia gravitent d’autres sites qui sont d’autres moyens de couvrir les champs du savoir, les champs de la culture et de la contribution. Parmi ceux-ci, j’en distingue trois, une médiathèque qui s’appelle [[w:Wikimedia Commons|Wikimédia commons]] qui héberge tous les fichiers multimédias, vidéos, photos, qui n’est pas multilingue mais unilingue avec des interfaces, par contre, dans différentes langues, et qui compte plus de onze millions de fichiers, [[w:Wikisource|Wikisource]] qui existe dans une cinquantaine de langues et qui est une bibliothèque de textes sous licences libres ou dans le domaine public et puis, le [[w:Wiktionnaire|Wiktionnaire]] dont je vous parlerai plus longuement tout à l’heure qui est un dictionnaire multilingue qui existe dans plusieurs dizaines de langues et qui, en français, compte plus de deux millions d’entrées.
Quelle est la place des langues d’outre-mer sur Wikipédia ? C’est une présence extrêmement faible. On a que deux langues qui ont une version linguistique autonome de Wikipédia réellement active, le [[w:Tahitien|tahitien]] et le [[w:Haïtien|créole haïtien]], avec assez peu d’articles quant on compare avec d’autres langues. Trois versions linguistiques sont en cours de création, à un tout premier stade, le [[w:Créole guadeloupéen|créole guadeloupéen]] qui ne compte que quatre articles encyclopédiques, ce qui, rapporté au nombre de locuteurs potentiels, est très faible, le [[w:Langues hmong|hmong]] et le [[w:Wallisien|wallisien]].
Alors est-ce que la solution serait d’adopter une démarche de traduction systématique qui n’est pas la démarche originelle de Wikipédia, et de faire travailler les gens systématiquement en français et dans leur langue, pour créer des contenus dans les langues d’outre-mer sur tous types de sujets encyclopédiques et aussi créer des contenus en français sur les thématiques de l’outre-mer ?
Pour vous donner une image de ce qui peut se faire dans l’autre sens, sur Wikipédia en français, en revanche, l’outre-mer est très présent. On a à peu près 6000 articles qui concernent très précisément les outre-mer, cela va de 60 articles pour Wallis et Futuna à 2400 pour la Réunion, c’est donc très disparate mais très comparable au traitement des autres régions françaises, rapportée au nombre d’habitants la couverture des sujets sur l’outre-mer est plutôt bien faite alors qu’à l’inverse, la couverture de n’importe quel sujet n’est absolument pas faite dans les langues locales. Peut-être que le préalable à l’écriture encyclopédique et le partage du savoir encyclopédique dans les langues locales doit se faire d’abord par la mise à disposition de plus de vocabulaire écrit, d’un dictionnaire plus accessible à tous.
Un des projets Wikimédia, le Wiktionnaire, est intéressant dans son approche multilingue. Il va exister dans plusieurs dizaines de langues et, en français, va donner des définitions de mots de différentes langues. Pour vous donner un exemple, le Wiktionnaire francophone compte un peu plus de deux millions de définitions et propose des définitions de ces mots dans 987 langues différentes. 14 langues d’outre-mer sont représentées, plus que dans Wikipédia et dans ces principales langues on retrouve le tahitien, le créole haïtien et celui de Guadeloupe. À noter que certaines langues comme le malgache ont un Wiktionnaire extrêmement fourni, bien plus que d’autres langues bien plus dotées. Donc ce Wiktionnaire est une aide au travail d’écriture des langues, de traduction, de transcription d’une langue à une autre et je me pose la question de savoir si ça ne serait pas un préalable à la création de contenu encyclopédique, c’est-à-dire d’abord décrire les mots et, une fois ces mots décrits, une fois les concepts posés, pouvoir ensuite entamer ce travail encyclopédique qui pour l’instant n’existe pas vraiment.
Pour terminer, quelques questions avant les ateliers, sur la place des langues sur le numérique, quelle est la place écrite de ces langues ? Je pense que c’est l’un des points fondamentaux, comment écrire, comment avoir une graphie commune ? Est-on obligé d’avoir cette stabilisation écrite pour aller sur internet ou y a-t-il un moyen de faire autrement ? Comment donner de la visibilité à une langue ? Et est-ce que, pour vous, la valorisation de la langue par le numérique est quelque chose de naturel qu’il convient de développer ou pas ? Qui est à même de prendre en charge ces actions, est-ce à l’État ou aux individus ? Les pratiques sur internet sont des pratiques individuelles ou par communauté plutôt que des pratiques étatiques, êtes-vous prêts ou motivés pour prendre en charge des actions de valorisation sur le numérique ? Enfin, est ce que cette démarche de co-construction par la traduction systématique français et langue locale pour faire progresser les contenus dans les deux langues et faire progresser la connaissance et la langue dans les deux langues est ce une bonne solution ?
En tous cas, sachez que l’association Wikimédia France pour laquelle je travaille et qui s’occupe de valoriser et diffuser Wikipédia sur le territoire français et non pas forcément que en langue française, est tout à fait disposée à vous aider si vous avez une envie de valoriser vos langues sur Wikipédia et on aura tout à l’heure, dans un atelier, l’occasion d’entrer plus en détail dans cela. Voilà, pour ma part, la réflexion que je me faisais sur le numérique.
:''Merci Adrienne. Rozenn Milin de l’Association Sorosoro, je vous donne la parole.''
===Expert 1 : [[w:Rozenn Milin|Rozenn Milin]] ([[w:Sorosoro|SOROSORO]])===
Je vais essayer d’être brève pour vous parler de Sorosoro. C’est un programme qui travaille à la sauvegarde des [http://www.unesco.org/new/fr/culture/themes/endangered-languages/ langues en danger] sur des supports audiovisuels et numériques, pas seulement sur l’outre-mer, c’est un programme généraliste qui s’occupe de toutes les langues du monde, mais qui a aussi travaillé sur l’outre-mer, la Guyane et la Nouvelle-Calédonie en particulier, grâce à la [[w:Délégation générale à la langue française et aux langues de France|DGLFLF]] du ministère de la Culture et de la Communication qui nous accueille ici et encore merci de cette invitation.
Le sujet est donc ici, la présence des langues sur la toile et les [[w:Réseau social|réseaux sociaux]]. J’ai pensé qu’il fallait remettre tout cela en contexte même si cela a été fort bien fait par Adrienne et que Marcel le fera également, je vais juste reprendre les critères qui sont donnés par les experts de l’[[w:Organisation des Nations unies pour l'éducation, la science et la culture|UNESCO]] pour évaluer les critères de vitalité des langues.
Il y a bien sûr le nombre de locuteurs, il y a aussi la transmission de génération en génération, on a beaucoup évoqué la [[w:Bretagne|Bretagne]] je suis bretonne, je parle [[w:Breton|breton]] et j’en sais quelque chose de ce problème de transmission quand la majorité des locuteurs a plus de soixante ans et qu’elle ne transmet plus sa langue, c’est que la langue est très mal en point, la présence de l’éducation est, bien sûr, un sujet majeur, mais il y a aussi la présence dans la vie publique qui est un des critères retenus par l’UNESCO pour déterminer la vitalité des langues. Qui dit vie publique, dit beaucoup présence dans les médias, alors si on reprend chronologiquement, il y avait la presse écrite, il y a eu la radio, la télé et aujourd’hui internet qui bouleverse un peu tout. Si je reprends quelques chiffres de 2008 d’une étude de [[w:TNS Sofres|TNS Sofres]] qui dit que la consommation moyenne par français de télévision par jour était, en 2008, de trois heures et sept minutes. Dans le même temps, la consommation internet de loisirs était de deux heures dix sept minutes par jour. Aujourd’hui on est passé à trois heures trente pour la télévision et je n’ai pas le chiffre pour internet, mais on est très certainement proche du même temps en consommation internet qu’on l’est en consommation télévisuelle. C’est dire si le monde des médias est en train d’être bouleversé et il est clair que, pour des langues minoritaires, pour qu’elles aient une chance de survivre à l’avenir dans ce monde qui est très technologique et globalisé, il faudra être présent sur internet.
Je peux vous donner un autre chiffre qui n’est pas récent mais je ne pense pas qu’il ait changé beaucoup, quatre vingt dix pourcent des pages disponibles sur internet sont en seulement douze langues. Il est difficile d’avoir des données récentes car tout passe par des moteurs de recherche et Google est un peu avare d’informations, mais s’intéresse de près aux langues en danger puisqu’ils ont l’intention de lancer une plateforme autour de ces langues en début d’année prochaine. C’est donc un sujet qui devient assez chaud.
Alors comment renforcer la présence de langues minoritaires sur le net, et comment fait-on ? Déjà beaucoup de langues qui sont parlées minoritairement, de petites langues en nombre de locuteurs, sont parlées dans des endroits où il n’y a pas d’ordinateurs, pas d’accès internet et parfois même pas d’électricité. Ce n’est pas forcément le cas pour les langues d’outre-mer, mais d’autres questions se posent de façon cruciale, comment fait-on pour poster des contenus sur internet quand la langue n’est pas codifiée ? Si elle est codifiée, combien de personnes savent l’écrire ? Et quand on sait l’écrire, qui va contribuer, parce qu’il faut du temps pour contribuer sur internet ? Ces populations ont généralement un nombre de locuteurs relativement bas, les langues ne sont pas forcément codifiées, pas forcément écrites et il faut encore que les locuteurs se saisissent de leur langue et produisent des contenus pour internet. Cela fait beaucoup de « il faudrait que » et, très souvent, ces communautés ont d’autres priorités que de poster des contenus sur internet. Ce sont des questions qui se posent, on a pas forcément les réponses mais en tous cas, ce qu’on fait nous à Sorosoro, c’est qu’on exploite une autre voie qui est celle de l’audiovisuel, qui suit un schéma de tradition orale puisque notre objet est d’envoyer sur le terrain, un peu partout dans le monde, des équipes filmer ce qu’on espère être la substantifique moelle de ces langues et des cultures qu’elles véhiculent bien entendu. Donc nous partons sur le terrain, avec des linguistes et des anthropologues parfois, et nous ramenons des dizaines d’heures de rushes qui sont tout ce que l’on peut collecter de [[w:Tradition orale|tradition orale]] : des [[w:Conte|contes]], des [[w:Récit|récits]], des [[w:Rite|rites]], de la [[w:Pharmacopée|pharmacopée]], des connaissances diverses et variées, des savoir-faire, la vie quotidienne etc… Puis tout cela est dérushé, archivé, indexé, déposé à l’[[w:Institut national de l'audiovisuel|INA]] et toute une partie de cela est montée et mis en ligne sur internet sur notre site internet qui s’appelle http://www.sorosoro.org/ que certains d’entre vous connaissent ici probablement.
Alors nous avons déjà, notamment grâce à la DGLFLF, commencé à travailler sur les outre-mer et espérons pouvoir poursuivre, nous avons filmé en Nouvelle-Calédonie, merci Claire Moyse qui était la linguiste qui accompagnait notre équipe de tournage, merci aussi à l’[[w:Académie des langues kanak|Académie des Langues Kanak]] qui a effectué les traductions en [[w:Xârâcùù|xârâcùù]] puisque nous avons filmé trois langues kanak, le xârâcùù, le [[w:Xârâgurè|xârâgurè]] et le [[w:Xâmea|xâmea]], vous pouvez d’ailleurs voir dans le hall d’entrée des vidéos qui passent sur Sorosoro, sur la construction des cases, mais aussi sur les bébé lecture dont parlait Marie Adèle Jorédié, et on la voit avec ses enfants.
Le travail que nous faisons sert à la recherche mais peut également servir à l’enseignement ou l’accompagnement à l’enseignement des langues, puisqu’on filme à chaque fois des tas de petits mots de la vie quotidienne, on fait donner les chiffres de un à dix, les couleurs, les jours de la semaine, les parties du corps, toutes ces choses qui peuvent être utilisées dans un cadre d’enseignement, de transmission de la langue et puis toute cette tradition orale que l’on filme et qu’on met en ligne progressivement peut également servir pour transmettre tous ces savoirs et cette tradition orale à tous ceux qui sont désireux de les apprendre. Internet sert également à cela. Nous avons également filmé cet été, avec Maurice Tiouka, dans sa propre communauté [[w:Kali'na|Kali'na]] en Guyane, qui sera en ligne après un long processus de traduction.
Voilà, nous espérons pouvoir continuer ce travail, je vous invite à aller voir sur le site pour mieux comprendre ce que nous faisons, qui n’est pas une solution universelle mais qui contribue à cette présence des langues de l’outre-mer et, au-delà, de toutes les langues en danger dans le monde sur internet.
:''Merci. Marcel Diki Kidiri vous faites partie du Réseau Maaya qui essaye de mesurer la présence des langues sur internet.''
===Expert 2 : Marcel Diki Kidiri ([http://maaya.org/spip.php?article12 Groupe MAAYA])===
En 2005, à l’occasion du [http://www.itu.int/wsis/index-fr.html sommet mondial pour la société de l’information] qui s’est tenu à Tunis, a été créé à l’initiative de l’[[w:Académie africaine des langues|Académie Africaine des Langues]] le réseau Maaya qui est un réseau mondial pour la diversité linguistique. Maaya est un mot [[w:Mandingue (langue)|mandingue]] qui se traduit en français par humanitude et en [[w:Langues bantoues|langue bantoue]] par un mot qui renvoie à la divinité de l'homme. Depuis sa création, ce réseau a organisé un forum international à Bamako en 2007 sur la diversité linguistique dans le monde et quatre symposium internationaux, deux en [[[w:Russie|Russie]], un à [[w:Barcelone|Barcelone]] et un à [[w:Brasilia|Brasilia]] sur la diversité linguistique dans le cyberespace. La question de la diversité linguistique dans le cyberespace est très présente dans les activités de Maaya qui est en train de mettre en chantier un très ambitieux programme de création ou de production d’un nouveau moteur de recherche pour une meilleure mesure de la diversité linguistique dans le cyberespace.
Dans la mesure où Google n’est plus du tout capable de le faire et les moteurs de recherche actuels ne donnent pas l’image de la réalité de l’internet. Ceci est confirmé par nos collègues de Maaya mais également l’[[w:Université technique de Nagaoka|université de Nagaoka]] au [[w:Japon|Japon]] qui observe aussi la diversité des langues dans le cyberespace. Je remercie la DGLFLF de m’avoir invité ici au nom de réseau Maaya pour vous parler un peu de ce que nous faisons.
Je veux vous parler de mon intérêt pour les langues dans le cyberespace. Cela m’est venu du fait, qu’au départ, j’étais uniquement linguiste africaniste décrivant la langue [[w:Sango|Sango]] de la [[w:République centrafricaine|République Centrafricaine]] qui est aujourd’hui une des deux langues officielles du pays, le Sango et le Français et, avant de devenir langue officielle, le Sango était considérée comme une non-langue et le chemin a été très long pour qu’elle devienne, aujourd’hui, langue officielle.
En 1991 j’ai créé un premier site sur le Sango en me disant, personne ne le lira, je le fais pour moi. Trois mois après je reçois des mails du [[w:Canada|Canada]], du Japon, de France, de gens qui étaient émus de voir le Sango sur internet. J’étais très surpris de voir que des gens pouvaient s’intéresser à cette langue. Cela m’a beaucoup encouragé à dire comment on peut faire pour mettre sur internet une langue inconnue pour qu’elle devienne connue. Bien sûr l’internet de 1991 n’est pas celui d’aujourd’hui où tout site digne de ce nom est interactif et social. En 1991 n’importe qui pouvait créer une page internet et mettre sa langue dessus. C’est comme si on mettait un poster sur des murs. Cela fait de ma langue une langue morte sur internet. Pour qu’elle devienne langue vivante, il faut qu’il y ait derrière une communauté. Des gens qui s’écrivent, se répondent, qui réagissent. Donc il faut la formation d’une ressource humaine, d’une communauté qui communique et travaille dans cette langue. Avant même de mettre cette langue sur internet il faut qu’elle soit écrite. Si elle n’est pas écrite, il faut passer par des techniques de reconnaissance vocale qui ne sont pas à la portée de tout le monde, c’est réalisable mais il faut des spécialistes pour le faire. Une fois que la langue est écrite, vous savez tout le débat que l’on a à se mettre d’accord sur une orthographe, il faut pouvoir collecter des textes, créer des forums de discussions.
J’ai été amené à écrire cet ouvrage qui est diffusé en [[w:portugais|portugais]], en [[w:russe|russe]], en français, en [[w:anglais|anglais]] et en [[w:espagnol|espagnol]] « [http://www.unesco.org/new/fr/communication-and-information/resources/publications-and-communication-materials/publications/full-list/securing-a-place-for-a-language-in-cyberspace/ Comment assurer la présence d'une langue dans le cyberespace ?] ». Moi je suis parti d’une langue très petite, parlée par deux ou trois personnes, dans la mesure où ces deux ou trois personnes sont décidées à la faire connaître, il faut développer les ressources linguistiques — décrire la langue, écrire la grammaire, écrire les dictionnaires — et aussi traduire le vocabulaire technique pour qu’elle puisse être vivante sur internet, comment on dit naviguer, cliquer,… ce sont des métaphores qu’on doit culturellement intégrer.
Il faut également développer les ressources culturelles. Les gens qui parlent cette langue ont une culture. Comment faire pour transmettre cette culture pour faire partager cela ? Hier j’étais très heureux de voir l’excellence du spectacle fourni par ces enfants. Je me suis dit, y a t-il un moyen de le mettre sur internet pour que ce soit partagé jusqu’au fin fond de l’univers ? Ce que les enfants ont dit est universel. Comment constituer les ressources culturelles locales sous un format partageable sur internet ? Il y a donc la langue, les ressources linguistiques, les ressources culturelles et ensuite les ressources humaines, former les gens pour qu’ils puissent travailler avec internet et enfin, développer les technologies pour l’accès.
:''Merci Marcel Diki Kidiri . Le représentant de l’institution auquel nous avons demandé d’apporter son point de vue à cette table ronde est chargé de la publication au Centre National de Documentation Pédagogique et s’intéresse particulièrement au support virtuel.''
===Représentant de l'institution : Bruno Dairou ([[w:Centre national de documentation pédagogique|Centre national de documentation pédagogique]])===
Le représentant de l’institution est là, très modestement, pour vous dire que justement, tout ce qu’on a développé autour de l’enseignement des langues est finalement très proprement enrichi par les langues régionales. Et, évidemment, pour différentes raisons, sans doute le poids de l’enseignement de la langue française dans le socle commun, des motifs politiques, des motifs linguistiques bien sûr avec une insuffisante description des langues, donc on vient plutôt dans l’idée de voir comment on peut travailler ensemble, beaucoup plus qu’on ne l’a fait jusque là.
Pour autant, ce n’est pas négliger la place des langues sur internet et dans les nouvelles technologies. En tous cas, le CNDP s’est saisi à bras le corps de tout cela et pour plusieurs raisons. D’abord, bien évidemment, parce que la demande était forte.
Il y avait à la fois une nouvelle façon d’enseigner les langues vivantes et il y avait, de manière complémentaire, le problème du français langue étrangère, langue seconde, langue de scolarisation. Cet ensemble a fait qu’il a fallu développer des outils. Ces outils qui nous posent des tas de problèmes et je pense qu’il faut se parler franchement, de validation des contenus, il est certain que c’est de la qualité pédagogique qu’il nous faut sur ces outils, donc des circuits de validation. Le CNDP fournit les ressources pour les enseignants donc il faut que ces contenus soient validés, fiables et qu’on arrive à les reproduire et les utiliser.
On a développé des outils, je pense - en vous laissant de côté tout ce qui sera les tableaux blancs interactifs - au fait de remplir les espaces numériques de travail qui a occupé beaucoup de forces vives au CNDP, en matière de langues vivantes, et cela a décentré la position de l’enseignant dans la classe. Donc ce n’était plus un dispositif frontal, c’était une utilisation active de ces méthodes grâce aux nouvelles technologies. Ce qui a permis de nouveaux rebonds, d’utiliser et de créer de nouveaux outils, tablettes numériques que nous fournissons très pauvrement en contenus, nous n’en sommes qu’au début et, ce matin dans les ateliers, cela a été évoqué très richement et il faudrait que l’on puisse évoquer des partenariats, mais il y a aussi ce que l’on appelle et que nous tirons de chez nos amis canadiens, la [http://eduscol.education.fr/langues/usages/baladodiffusion baladodiffusion], donc le fait qu’on utilise désormais ce qui est de l’univers des élèves, donc la possibilité de descendre de l’information sur leurs baladeurs, que ce soit en audio ou vidéo, que ce soient eux-même qui génèrent le flux. Donc le CNDP fournit des ressources dans ces domaines. Mais ce qui est intéressant et qu’on doit essayer de bâtir ensemble, et cela ressortait des ateliers de ce matin, c’est d’aboutir à des ressources et là aussi, je crois qu’il y a des partenariats à bâtir.
Cela ne veut pas dire qu’il n’y a rien d’existant, les CRDP ont beaucoup travaillé sur des ouvrages imprimés, mais aussi pour fournir des contenus numériques. L’intérêt pour nous, serait de travailler ensemble et je vous dis ce que le CNDP développe, nous développons les télévisions permettant d’aborder l’étude des langues, on essaye de le généraliser mais je crois qu’il y aurait un travail en commun à faire, des projets voient le jour, de plateformes de vidéo qui restent à nourrir, et il y aurait la possibilité d’introduire les langues régionales de manière pertinente, les langues en ligne, nous avons des séquences nombreuses, mais sur les langues régionales cela reste encore à développer et à bâtir. C’est le cas aussi de sites gratuits très consultés, plus d’un million de clics par an, sur lesquels la place des langues régionales reste à faire.
C’est vous dire que le CNDP est partie prenante de cela et on continue d’accompagner les langues des outre-mer mais c’est à l’état embryonnaire et je crois que cela peut être un effet de ces états généraux, se dire qu’il est grand temps qu’on travaille plus grandement ensemble.
==Restitution des ateliers==
===Les possibilités offertes par les technologies de la langue pour améliorer la relation aux usagers dans les services publics===
*Modérateur : [http://perso.limsi.fr/Individu/mariani/ Joseph Mariani] ([http://www.immi-labs.org/?lang=en Institut des technologies Multilingues et Multimédias de l’Information] / CNRS)
Cette thématique de l’atelier portait sur « les technologies de la langue pour l’aide aux usagers des services publics ». L’atelier a commencé par faire une description de ce que sont les technologies de la langue et également de l’importance de pouvoir disposer de données afin de pouvoir développer ces technologies. Je crois qu’il y a eu un accord unanime au sein de l’atelier, pour dire que les technologies de la langue sont nécessaires et, pour certains, sont même indispensables si on veut permettre le multilinguisme.
On note actuellement une explosion des applications de ces technologies et, en particulier, sur l’internet, mais également sur les terminaux mobiles. Mais on constate également et donc, là, c’est souligné très justement par [http://llacan.vjf.cnrs.fr/pers/p_diki.htm Marcel Diki Kidiri], ces technologies n’existent que pour 1% des langues qui sont parlées dans le monde. Donc elles existent pour une soixantaine de langues sur les quelques 6000 qui sont parlées dans le monde. Et je pense que c’est une constatation qui est tout à fait essentielle.
Les propositions que l’on fait sont de se donner pour objectif de développer les technologies de la langue pour toutes les langues de France et en particulier pour les langues d’outre-mer, et donc pas uniquement pour le français, et ce dans le cadre d’une recherche coordonnée, d’adapter les technologies qui existent pour ces langues, de produire les données, les corpus, les lexiques qui sont nécessaires au développement de ces technologies et d’évaluer systématiquement les performances qui sont obtenues pour les comparer aux besoins les applications que l’on vise.
Alors quelles technologies ? On ne va pas brasser l’ensemble des technologies pour commencer, donc en choisir quelques unes.
On a pensé qu’il fallait peut-être privilégier les technologies qui ont trait à l’oral. Donc la reconnaissance de la parole, la synthèse vocale, cela parce qu’il y a un intérêt pour les langues à tradition orale sans système d’écriture, parce qu’il y a un intérêt également pour les cas d’[[w:Illettrisme|illettrisme]] ou d’[[w:Analphabétisme|analphabétisme]], parce qu’on peut profiter de cette manière-là du formidable déploiement de la téléphonie mobile que j’évoquais et enfin, parce qu’en permettant le passage de l’écrit à l’oral et réciproquement, c’est également une aide qu’on peut apporter au [[w:Handicap|handicap]] dans l’accessibilité à l’information et ce, donc, pour les [[w:Malvoyant|malvoyants]] et les [[w:Hypoacousie|malentendants]]. Donc une contribution à cette notion d’accessibilité.
Les autres technologies auxquelles on peut penser en priorité sont la traduction automatique et la traduction vocale. Cela permettrait peut-être de résoudre le problème de la traduction simultanée en 50 langues, soit 2500 paires de langues, pour ces États-Généraux qu’évoquait tout à l’heure Xavier North.
Dans le cadre de ces développements de technologies, peut-être faut-il privilégier tout ce qui est [[w:Logiciel libre|logiciel libre]] et donnée libre.
Quelles langues ? On ne va pas attaquer de front les dizaines de langues auxquelles on pourrait penser, mais peut-être choisir quelques langues, 4 à 5 pour commencer, travailler peut-être par famille de langues en les identifiant, avec peut-être un intérêt particulier, ça a été souligné, pour les langues véhiculaires, et, en ce qui concerne la traduction, peut-être commencer par la traduction de et vers le français puisque nous avons le français en partage.
Quelles applications pour les besoins des usagers des services publics ? On entrevoit quelques pistes qui sont encore à approfondir, peut-être en lançant une enquête auprès des usagers.
A été mentionnée la traduction pour les usagers de la poste, des banques, dans les hôpitaux, puisque qu’on voit qu’il existe actuellement une barrière des langues qui constitue un obstacle à la qualité du service rendu au public. Cela a été mentionné pour plusieurs de ces services. Traduction pour les soins médicaux et là, on peut penser que la machine pourrait assurer une confidentialité que ne permet pas à l’heure actuelle l'intervention de médiateurs humains. Cela a aussi été souligné au tout début de cet après-midi. Également traduction pour pouvoir publier dans sa langue maternelle et accéder aux ouvrages et aux documents que l’on peut trouver sur les bibliothèques numériques.
Quelques autres exemples d’applications auxquelles on peut penser : des bornes vocales plurilingues dans les musées ou dans les administrations, l’aide en ligne pour l’apprentissage des langues. Et également tout ce qui concerne le sous-titrage automatique et peut-être même la traduction à la demande des émissions radio ou télédiffusées.
En résumé, le principe fondateur est de permettre à chacun, quelle que soit la langue qu'il parle, d’accéder à l’information, à la connaissance, quelle que soit la langue dans laquelle elle a été codée.
===Présence et dialogue des langues et des cultures sur internet===
*Modérateure : Rodica Ailincai / IUFM de l’[[w:Université de la Polynésie française|université de la Polynésie française]]
Je ne vais pas résumer l'atelier parce que Thibault Grouas a fait un document très fidèle aux échanges qu’on a eus. Donc je présenterai l’ambiance générale, les idées qui se sont dégagées seulement. Échanges riches, beaucoup de participants, beaucoup de propositions, de discussions, de débats, de partages d’expérience, des pratiques, une atmosphère créative et productive donc l’ensemble des préconisations, selon moi, se sont situées d’un point de vue matériel, d’un point de vue contenu.
D’un point de vue matériel, il s’agit de la création de points d’accès à internet dans tous les villages et sites isolés. Parce qu’on a des paraboles, mais il faut qu’elles fonctionnent encore parce que les dispenser à internet donc pourquoi pas les écoles et les villages. Équipement aussi des sites isolés et éloignés, des communes pratiquant les langues autochtones et s’assurer des aspects techniques de la gestion de ces centres. Et de leur bon fonctionnement.
Au niveau contenu, il y a aussi deux volets, parce qu’il y a toujours le formel donc l’école et il y a aussi l’informel.
Dans le formel, il s’agissait des sites en langues outre-mer avec une exigence de contenu des qualités. Si on écrit en créole sur le site créole, il ne faut pas faire de fautes d’orthographe, il ne faut pas raconter n’importe quoi si le professeur voit ça. Versus, l’espace libre d’échanges sans exigence de forme et d’orthographe où les enfants peuvent s’exprimer librement, dire ce qu’ils veulent sans se soucier de l’orthographe, ce qui les empêcherait de s’exprimer librement.
Dans le cadre du formel, on a aussi eu une proposition très intéressante : l’introduction des nouvelles technologies dès la maternelle avec une vraie formation, parce qu’on sait aujourd’hui que, parfois, on forme les parents à travers les enfants. À cet âge-là, les parents se soucient beaucoup de ce que l’enfant a appris à l’école donc ce partage peut être aussi très bénéfique pour les parents.
Partage des faits culturels, savoirs, savoir-faire au niveau communauté. Enregistrement sons, fiches techniques, je n’entrerai pas dans les détails, mettre des faits culturels, donc, avec l’accord des communautés, sur internet, faire partager la culture. Il y a eu beaucoup d’autres idées. Comment faire vivre le site une fois qu’on l’a créé ? Traduction ou pas ?
Et il y a une autre idée très intéressante qui s’est dégagée ici, l’utilisation d’un site dans sa langue maternelle peut parfois favoriser une intimité culturelle (on a retenu ce terme), on a parfois envie de dire une chose sans la traduire et si on a envie de la traduire, on la traduit soi-même. Donc cette idée de traduction où on sait que les machines ne le font pas bien aujourd’hui, où ce n’est pas satisfaisant, on peut faire le choix de le faire soi-même ou, quand on a besoin de savoir ce qui se dit, on peut le demander et on trouvera de l’autre côté des interlocuteurs qui vont le faire.
===Atelier d’écriture [[w:Wikipédia|Wikipédia]]===
*Modérateure : [http://www.wikimedia.fr/salari%C3%A9s Adrienne Alix] ([[w:Wikimedia|Wikimédia]] France)
Pour l’atelier « Wikipédia » qui était donc très centré sur un sujet et en petit comité, on a d’abord fait le constat que wikipédia était très peu investi par les langues d’outre-mer contrairement au contenu concernant l’outre-mer dans la langue française. Donc il y a un très fort déséquilibre entre le français et les langues d’outre-mer.
La discussion avec les différentes personnes a montré ensuite que c’est pourtant un outil qui peut être assez fondamental dans la légitimation des langues, dans leur diffusion, dans leur transmission, pourquoi pas aussi un outil de stabilisation écrite des langues par le dialogue et le consensus entre les différents contributeurs. Et contribuer sur wikipedia en français à propos de l’outre-mer et contribuer dans les langues de l’outre-mer sur tous les sujets encyclopédiques, scientifiques, culturels, littéraires, etc. pouvait être un outil vraiment intéressant pour lutter contre cette idée de complexe de dévalorisation qui est quand même très présent et favoriser le sentiment de légitimité des langues locales sur internet.
Ce que je retiens aussi, c’est que les personnes présentes se sont trouvées extrêmement motivées pour créer des versions linguistiques de wikipédia dans leur langue, donc c’est un très bon espoir et j’espère que ce sera concrétisé. Et une préconisation que l’on pourrait faire, c’est de proposer que l’association Wikimédia France qui a pour objectif de favoriser l’émergence de wikipédia travaille avec les différentes communautés et avec les différentes institutions, et notamment la DGLFLF, au soutien et à la coordination de créations de versions linguistiques de wikipédia dans les différentes langues locales, avec le bémol de la question à régler des langues qui ne sont pas encore écrites et donc là, on se retrouve avec l’éternel problème de l’oral et de l’écrit.
==Recommandations==
* Renforcer de manière significative les infrastructures permettant l’accès à l’internet sur les territoires de l’outre-mer, notamment dans les zones les plus isolées, les établissements publics, les écoles.
* Mettre en place un véritable programme pour faire entrer l’internet dans les écoles dès la maternelle, et développer l’usage des technologies pour l’apprentissage des langues maternelles, l’éducation à la maîtrise de l’écrit, la lutte contre l’absentéisme et l’[[w:illettrisme|illettrisme]].
* Mettre en place un programme d’introduction des outils d’aide à la traduction et à l’interprétation, et de bornes vocales plurilingues dans les services publics, pour améliorer les services aux usagers.
* Encourager l’usage de l’internet par les citoyens dans leur langue maternelle, notamment au moyen des réseaux sociaux, de la messagerie instantanée, des tchats, ou des sites de partage de vidéos, avec pour objectif de briser le complexe qui empêche les citoyens de s’exprimer dans leur langue maternelle.
* Mettre en place une action stratégique appuyée ou coordonnée par le ministère de la Culture et de la Communication en faveur du développement des pratiques d’écriture en langues de France sur [[w:Wikipédia|Wikipédia]] notamment à l’école, et encourager l’émergence de communautés de contributeurs sur les territoires d’outre-mer.
* Développer les technologies de traduction automatique du texte et de la parole, pour toutes les langues de France, et en particulier pour les langues d’outre-mer, dans le cadre d’une action de recherche coordonnée impliquant une évaluation systématique les performances obtenues par ces technologies au fur et à mesure de leur développement, et une mesure régulière des besoins des usagers.
* Disposer de systèmes de traduction et de référencement en langues régionales, pour accéder aux ouvrages, ou plus généralement aux documents dans les bibliothèques numériques.
* Développer les applications et interfaces orales avec restitution orale (reconnaissance vocale, aide à la traduction) pour les langues minoritaires et non écrites, et à destination des publics fragilisés ([[w:illettrisme|illettrisme]], [[w:Analphabétisme|analphabétisme]], [[w:Déficience visuelle|handicaps visuel]] et [[w:Surdité|auditif]]).
* Développer les corpus en langues régionales, en quantité et de qualité suffisantes pour développer les technologies de la langue. On pourra s’appuyer notamment sur les ressources de Wikipédia et du [[w:Wiktionnaire|Wiktionnaire]] en langues de France.
* Encourager le développement ou l’utilisation de [[w:Logiciel libre|logiciels libres]], de [[w:Plate-forme collaborative|plates-formes collaboratives]] et de données libres de droits pour le développement des technologies de la langue.
* Mettre à disposition du public des outils pour le sous-titrage automatique et la traduction à la demande des émissions radio ou télédiffusées.
* Répertorier la présence sur internet des langues parlées en outre-mer.
[[Catégorie:États généraux du multilinguisme dans les outre-mer]]
srzes9qixr281k1ixzqw6vywlc7y5gm
États généraux du multilinguisme dans les outre-mer/Thématiques/L’emploi des langues : plurilinguisme, pratiques individuelles et pratiques sociales/Table ronde plénière : transcription thématique 4
0
48266
744337
677647
2025-06-09T05:20:03Z
92.133.223.238
/* Expert 2 : Marcel Diki Kidiri (Groupe MAAYA) */ Correction de "entrain" (nom) par "en train" (locution)
744337
wikitext
text/x-wiki
==Propos introductif : [http://www.wikimedia.fr/salari%C3%A9s Adrienne Alix] ([[w:Wikimedia|Wikimédia]] France)==
Je vais vous parler ici avec un regard très naïf et qui découvre, je ne suis ni spécialiste des langues, ni des outre-mer, par contre, un peu plus du numérique et je vais essayer d’introduire cette deuxième table ronde en montrant un peu les opportunités et l’intérêt du numérique et d’internet pour la valorisation, la préservation, la diffusion des langues d’outre-mer tout en vous faisant part de mon étonnement, ce matin, de ne pas avoir vu ou entendu parler à aucun moment d’internet ou de quoi que ce soit qui puisse faire penser au numérique. Cela me démangeait d’en parler et je me suis dit que j’allais attendre cet après-midi pour pouvoir en parler tous ensemble.
Pour schématiser très rapidement, ce qui est pour moi le fondement d’internet, c’est tout d’abord un réseau décentralisé, quelque chose qui, dans sa conception, est totalement indépendant techniquement de toute structure étatique ou autre, cela n’a pas été construit pour ça, c’est quelque chose qui a été fait pour le partage, pour la circulation de l’information, c’est un réseau qui permet l’initiative individuelle et l’initiative collective sans demander à qui que ce soit avant de le faire. C’est donc, à mon sens, un des outils les plus pratiques, un outil idéal pour la diffusion, la préservation et le travail sur les langues.
J’ai entendu, ce matin, beaucoup de réflexions sur les problèmes avec l’institution Éducation nationale par exemple, ou ce qu’on en attend, ce qu’on lui reproche. S’il y a un espace de liberté beaucoup plus grand où l’on a pas à demander ou avoir besoin d’une loi, c’est bien internet.
Si vous voulez voir comment on peut faire démarrer une langue rare, une langue peu parlée, peu dotée, comme le dit monsieur [http://llacan.vjf.cnrs.fr/pers/p_diki.htm Diki Kidiri], je vous invite à lire le rapport qu’il a fait il y a déjà cinq ans, sur comment assurer la présence d’une langue sur le [[w:Cyberespace|cyberespace]] et qui, pour moi, était quelque chose d’assez fondamental pour comprendre comment une langue qu’il appelle « peu dotée », avec peu de ressources écrites et peu de ressources numériques, peut avoir sa place sur internet.
Je vais vous parler de quelque chose que je connais plus particulièrement et qui me semble être un excellent vecteur des langues, c’est [[w:Wikipédia|Wikipédia]]. Je vais d’abord faire un petit point sur les problématiques que j’ai pu relever sur les langues. Quelle est la place que peuvent prendre les langues d’outre-mer, les langues de France sur Internet ? Il y a un certain nombre de problématiques pas forcément insurmontables mais qui se posent actuellement.
*La première, c’est la mesure de la place des langues. Mesurer combien il y a de pages web en français, en allemand, en anglais, en créole, dans n’importe quelle langue est quelque chose de difficile. Les moteurs de recherche n’indexent pas toutes les pages. C’est à dire que, sans savoir ce qui existe, c’est difficile de pouvoir promouvoir une langue, donc c’est un des problèmes pour trouver la place des langues sur le numérique. Google, le moteur de recherche le plus pratiqué au monde, ne propose son interface qu’en cent cinquante langues, ce qui n’est pas énorme, et fait un travail sérieux de résultats de moteur de recherche qu’en environ trente cinq langues, donc on est très loin de pouvoir faire émerger la diversité.
*Deuxième problématique importante, celle de la fixation écrite de la langue, qui n’est pas spécifique au numérique mais qui se pose forcément sur internet puisque internet est principalement un internet écrit.
*Troisième point, vouloir faire exister une langue sur internet nécessite une traduction des interfaces des logiciels qui permettent de produire du contenu pour qu’il y ait une réelle appropriation par les locuteurs.
*Et puis, dernier problème, beaucoup plus pratique, celui de la connexion à internet qui n’est pas forcément très évidente suivant là où l’on se trouve.
Donc, les bases d’un multilinguisme sur internet assumé, où on puisse s’exprimer sans aucun problème, ne sont pas forcément simples, mais on a quand même la possibilité, pour chaque langue, de trouver sa place, si elle est portée par une communauté de locuteurs active, motivée et qui intègre les enjeux du numérique pour la diffusion d’une langue en dehors d’une communauté.
J’en arrive maintenant au sujet que je connais le mieux et qui me semble être un bon exemple de multilinguisme, qui est l’encyclopédie Wikipédia que vous connaissez probablement en français, en anglais, peut-être moins dans d’autres langues, et qui a la particularité d’être collaborative, ouverte à tous, il n’y a pas de barrière à l’écriture pour tous ceux qui veulent contribuer, qui est diffusée sous une [[w:Licence libre|licence libre]] qui permet donc une réelle diffusion, redistribution, réappropriation, remixage, sous n’importe quel support et qui est, dans son essence même, multilingue, c’est-à-dire qu’on n’est pas dans un concept de traduction d’une langue à l’autre, mais de développement totalement autonome de chaque langue, à partir du moment où elle a une communauté de locuteurs qui a pris en charge la création d’une version linguistique de l’encyclopédie.
Pour vous donner une idée, en dix ans, on est passé du Wikipédia en anglais né en 2001 à 283 éditions linguistiques totalement autonomes, dont une quarantaine ont plus de cent mille articles, et qui comportent des langues extrêmement parlées mais aussi des langues extrêmement peu parlées suivant la communauté qui va la porter. En français on est à un million deux cent mille articles.
Autour de Wikipédia gravitent d’autres sites qui sont d’autres moyens de couvrir les champs du savoir, les champs de la culture et de la contribution. Parmi ceux-ci, j’en distingue trois, une médiathèque qui s’appelle [[w:Wikimedia Commons|Wikimédia commons]] qui héberge tous les fichiers multimédias, vidéos, photos, qui n’est pas multilingue mais unilingue avec des interfaces, par contre, dans différentes langues, et qui compte plus de onze millions de fichiers, [[w:Wikisource|Wikisource]] qui existe dans une cinquantaine de langues et qui est une bibliothèque de textes sous licences libres ou dans le domaine public et puis, le [[w:Wiktionnaire|Wiktionnaire]] dont je vous parlerai plus longuement tout à l’heure qui est un dictionnaire multilingue qui existe dans plusieurs dizaines de langues et qui, en français, compte plus de deux millions d’entrées.
Quelle est la place des langues d’outre-mer sur Wikipédia ? C’est une présence extrêmement faible. On a que deux langues qui ont une version linguistique autonome de Wikipédia réellement active, le [[w:Tahitien|tahitien]] et le [[w:Haïtien|créole haïtien]], avec assez peu d’articles quant on compare avec d’autres langues. Trois versions linguistiques sont en cours de création, à un tout premier stade, le [[w:Créole guadeloupéen|créole guadeloupéen]] qui ne compte que quatre articles encyclopédiques, ce qui, rapporté au nombre de locuteurs potentiels, est très faible, le [[w:Langues hmong|hmong]] et le [[w:Wallisien|wallisien]].
Alors est-ce que la solution serait d’adopter une démarche de traduction systématique qui n’est pas la démarche originelle de Wikipédia, et de faire travailler les gens systématiquement en français et dans leur langue, pour créer des contenus dans les langues d’outre-mer sur tous types de sujets encyclopédiques et aussi créer des contenus en français sur les thématiques de l’outre-mer ?
Pour vous donner une image de ce qui peut se faire dans l’autre sens, sur Wikipédia en français, en revanche, l’outre-mer est très présent. On a à peu près 6000 articles qui concernent très précisément les outre-mer, cela va de 60 articles pour Wallis et Futuna à 2400 pour la Réunion, c’est donc très disparate mais très comparable au traitement des autres régions françaises, rapportée au nombre d’habitants la couverture des sujets sur l’outre-mer est plutôt bien faite alors qu’à l’inverse, la couverture de n’importe quel sujet n’est absolument pas faite dans les langues locales. Peut-être que le préalable à l’écriture encyclopédique et le partage du savoir encyclopédique dans les langues locales doit se faire d’abord par la mise à disposition de plus de vocabulaire écrit, d’un dictionnaire plus accessible à tous.
Un des projets Wikimédia, le Wiktionnaire, est intéressant dans son approche multilingue. Il va exister dans plusieurs dizaines de langues et, en français, va donner des définitions de mots de différentes langues. Pour vous donner un exemple, le Wiktionnaire francophone compte un peu plus de deux millions de définitions et propose des définitions de ces mots dans 987 langues différentes. 14 langues d’outre-mer sont représentées, plus que dans Wikipédia et dans ces principales langues on retrouve le tahitien, le créole haïtien et celui de Guadeloupe. À noter que certaines langues comme le malgache ont un Wiktionnaire extrêmement fourni, bien plus que d’autres langues bien plus dotées. Donc ce Wiktionnaire est une aide au travail d’écriture des langues, de traduction, de transcription d’une langue à une autre et je me pose la question de savoir si ça ne serait pas un préalable à la création de contenu encyclopédique, c’est-à-dire d’abord décrire les mots et, une fois ces mots décrits, une fois les concepts posés, pouvoir ensuite entamer ce travail encyclopédique qui pour l’instant n’existe pas vraiment.
Pour terminer, quelques questions avant les ateliers, sur la place des langues sur le numérique, quelle est la place écrite de ces langues ? Je pense que c’est l’un des points fondamentaux, comment écrire, comment avoir une graphie commune ? Est-on obligé d’avoir cette stabilisation écrite pour aller sur internet ou y a-t-il un moyen de faire autrement ? Comment donner de la visibilité à une langue ? Et est-ce que, pour vous, la valorisation de la langue par le numérique est quelque chose de naturel qu’il convient de développer ou pas ? Qui est à même de prendre en charge ces actions, est-ce à l’État ou aux individus ? Les pratiques sur internet sont des pratiques individuelles ou par communauté plutôt que des pratiques étatiques, êtes-vous prêts ou motivés pour prendre en charge des actions de valorisation sur le numérique ? Enfin, est ce que cette démarche de co-construction par la traduction systématique français et langue locale pour faire progresser les contenus dans les deux langues et faire progresser la connaissance et la langue dans les deux langues est ce une bonne solution ?
En tous cas, sachez que l’association Wikimédia France pour laquelle je travaille et qui s’occupe de valoriser et diffuser Wikipédia sur le territoire français et non pas forcément que en langue française, est tout à fait disposée à vous aider si vous avez une envie de valoriser vos langues sur Wikipédia et on aura tout à l’heure, dans un atelier, l’occasion d’entrer plus en détail dans cela. Voilà, pour ma part, la réflexion que je me faisais sur le numérique.
:''Merci Adrienne. Rozenn Milin de l’Association Sorosoro, je vous donne la parole.''
==Expert 1 : [[w:Rozenn Milin|Rozenn Milin]] ([[w:Sorosoro|SOROSORO]])==
Je vais essayer d’être brève pour vous parler de Sorosoro. C’est un programme qui travaille à la sauvegarde des [http://www.unesco.org/new/fr/culture/themes/endangered-languages/ langues en danger] sur des supports audiovisuels et numériques, pas seulement sur l’outre-mer, c’est un programme généraliste qui s’occupe de toutes les langues du monde, mais qui a aussi travaillé sur l’outre-mer, la Guyane et la Nouvelle-Calédonie en particulier, grâce à la [[w:Délégation générale à la langue française et aux langues de France|DGLFLF]] du ministère de la Culture et de la Communication qui nous accueille ici et encore merci de cette invitation.
Le sujet est donc ici, la présence des langues sur la toile et les [[w:Réseau social|réseaux sociaux]]. J’ai pensé qu’il fallait remettre tout cela en contexte même si cela a été fort bien fait par Adrienne et que Marcel le fera également, je vais juste reprendre les critères qui sont donnés par les experts de l’[[w:Organisation des Nations unies pour l'éducation, la science et la culture|UNESCO]] pour évaluer les critères de vitalité des langues.
Il y a bien sûr le nombre de locuteurs, il y a aussi la transmission de génération en génération, on a beaucoup évoqué la [[w:Bretagne|Bretagne]] je suis bretonne, je parle [[w:Breton|breton]] et j’en sais quelque chose de ce problème de transmission quand la majorité des locuteurs a plus de soixante ans et qu’elle ne transmet plus sa langue, c’est que la langue est très mal en point, la présence de l’éducation est, bien sûr, un sujet majeur, mais il y a aussi la présence dans la vie publique qui est un des critères retenus par l’UNESCO pour déterminer la vitalité des langues. Qui dit vie publique, dit beaucoup présence dans les médias, alors si on reprend chronologiquement, il y avait la presse écrite, il y a eu la radio, la télé et aujourd’hui internet qui bouleverse un peu tout. Si je reprends quelques chiffres de 2008 d’une étude de [[w:TNS Sofres|TNS Sofres]] qui dit que la consommation moyenne par français de télévision par jour était, en 2008, de trois heures et sept minutes. Dans le même temps, la consommation internet de loisirs était de deux heures dix sept minutes par jour. Aujourd’hui on est passé à trois heures trente pour la télévision et je n’ai pas le chiffre pour internet, mais on est très certainement proche du même temps en consommation internet qu’on l’est en consommation télévisuelle. C’est dire si le monde des médias est en train d’être bouleversé et il est clair que, pour des langues minoritaires, pour qu’elles aient une chance de survivre à l’avenir dans ce monde qui est très technologique et globalisé, il faudra être présent sur internet.
Je peux vous donner un autre chiffre qui n’est pas récent mais je ne pense pas qu’il ait changé beaucoup, quatre vingt dix pourcent des pages disponibles sur internet sont en seulement douze langues. Il est difficile d’avoir des données récentes car tout passe par des moteurs de recherche et Google est un peu avare d’informations, mais s’intéresse de près aux langues en danger puisqu’ils ont l’intention de lancer une plateforme autour de ces langues en début d’année prochaine. C’est donc un sujet qui devient assez chaud.
Alors comment renforcer la présence de langues minoritaires sur le net, et comment fait-on ? Déjà beaucoup de langues qui sont parlées minoritairement, de petites langues en nombre de locuteurs, sont parlées dans des endroits où il n’y a pas d’ordinateurs, pas d’accès internet et parfois même pas d’électricité. Ce n’est pas forcément le cas pour les langues d’outre-mer, mais d’autres questions se posent de façon cruciale, comment fait-on pour poster des contenus sur internet quand la langue n’est pas codifiée ? Si elle est codifiée, combien de personnes savent l’écrire ? Et quand on sait l’écrire, qui va contribuer, parce qu’il faut du temps pour contribuer sur internet ? Ces populations ont généralement un nombre de locuteurs relativement bas, les langues ne sont pas forcément codifiées, pas forcément écrites et il faut encore que les locuteurs se saisissent de leur langue et produisent des contenus pour internet. Cela fait beaucoup de « il faudrait que » et, très souvent, ces communautés ont d’autres priorités que de poster des contenus sur internet. Ce sont des questions qui se posent, on a pas forcément les réponses mais en tous cas, ce qu’on fait nous à Sorosoro, c’est qu’on exploite une autre voie qui est celle de l’audiovisuel, qui suit un schéma de tradition orale puisque notre objet est d’envoyer sur le terrain, un peu partout dans le monde, des équipes filmer ce qu’on espère être la substantifique moelle de ces langues et des cultures qu’elles véhiculent bien entendu. Donc nous partons sur le terrain, avec des linguistes et des anthropologues parfois, et nous ramenons des dizaines d’heures de rushes qui sont tout ce que l’on peut collecter de [[w:Tradition orale|tradition orale]] : des [[w:Conte|contes]], des [[w:Récit|récits]], des [[w:Rite|rites]], de la [[w:Pharmacopée|pharmacopée]], des connaissances diverses et variées, des savoir-faire, la vie quotidienne etc… Puis tout cela est dérushé, archivé, indexé, déposé à l’[[w:Institut national de l'audiovisuel|INA]] et toute une partie de cela est montée et mis en ligne sur internet sur notre site internet qui s’appelle http://www.sorosoro.org/ que certains d’entre vous connaissent ici probablement.
Alors nous avons déjà, notamment grâce à la DGLFLF, commencé à travailler sur les outre-mer et espérons pouvoir poursuivre, nous avons filmé en Nouvelle-Calédonie, merci Claire Moïse qui était la linguiste qui accompagnait notre équipe de tournage, merci aussi à l’[[w:Académie des langues kanak|Académie des Langues Kanak]] qui a effectué les traductions en [[w:Xârâcùù|xârâcùù]] puisque nous avons filmé trois langues kanak, le xârâcùù, le [[w:Xârâgurè|xârâgurè]] et le [[w:Xâmea|xâmea]], vous pouvez d’ailleurs voir dans le hall d’entrée des vidéos qui passent sur Sorosoro, sur la construction des cases, mais aussi sur les bébé lecture dont parlait Marie Adèle Jorédié, et on la voit avec ses enfants.
Le travail que nous faisons sert à la recherche mais peut également servir à l’enseignement ou l’accompagnement à l’enseignement des langues, puisqu’on filme à chaque fois des tas de petits mots de la vie quotidienne, on fait donner les chiffres de un à dix, les couleurs, les jours de la semaine, les parties du corps, toutes ces choses qui peuvent être utilisées dans un cadre d’enseignement, de transmission de la langue et puis toute cette tradition orale que l’on filme et qu’on met en ligne progressivement peut également servir pour transmettre tous ces savoirs et cette tradition orale à tous ceux qui sont désireux de les apprendre. Internet sert également à cela. Nous avons également filmé cet été, avec Maurice Tiouka, dans sa propre communauté [[w:Kali'na|Kali'na]] en Guyane, qui sera en ligne après un long processus de traduction.
Voilà, nous espérons pouvoir continuer ce travail, je vous invite à aller voir sur le site pour mieux comprendre ce que nous faisons, qui n’est pas une solution universelle mais qui contribue à cette présence des langues de l’outre-mer et, au-delà, de toutes les langues en danger dans le monde sur internet.
:''Merci. Marcel Diki Kidiri vous faites partie du Réseau Maaya qui essaye de mesurer la présence des langues sur internet.''
==Expert 2 : Marcel Diki Kidiri ([http://maaya.org/spip.php?article12 Groupe MAAYA])==
En 2005 à l’occasion du [http://www.itu.int/wsis/index-fr.html sommet mondial pour la société de l’information] qui s’est tenu à Tunis a été créé à l’initiative de l’[[w:Académie africaine des langues|Académie Africaine des Langues]], le réseau Maaya qui est un réseau mondial pour la diversité linguistique. Maaya est un mot [[w:Mandingue (langue)|mandingue]] qui se traduit en français par humanitude et en [[w:Langues bantoues|langue bantoue]] par un mot qui renvoie à la divinité de l'homme. Depuis sa création, ce réseau a organisé un forum international à Bamako en 2007 sur la diversité linguistique dans le monde et quatre symposium internationaux, deux en [[[w:Russie|Russie]], un à [[w:Barcelone|Barcelone]] et un à [[w:Brasilia|Brasilia]] sur la diversité linguistique dans le cyberespace. La question de la diversité linguistique dans le cyberespace est très présente dans les activités de Maaya qui est en train de mettre en chantier un très ambitieux programme de création ou de production d’un nouveau moteur de recherche pour une meilleure mesure de la diversité linguistique dans le cyberespace.
Dans la mesure où Google n’est plus du tout capable de le faire et les moteurs de recherche actuels ne donnent pas l’image de la réalité de l’internet. Ceci est confirmé par nos collègues de Maaya mais également l’[[w:Université technique de Nagaoka|université de Nagaoka]] au [[w:Japon|Japon]] qui observe aussi la diversité des langues dans le cyberespace. Je remercie la DGLFLF de m’avoir invité ici au nom de réseau Maaya pour vous parler un peu de ce que nous faisons.
Je veux vous parler de mon intérêt pour les langues dans le cyberespace. Cela m’est venu du fait, qu’au départ, j’étais uniquement linguiste africaniste décrivant la langue [[w:Sango|Sango]] de la [[w:République centrafricaine|République Centrafricaine]] qui est aujourd’hui une des deux langues officielles du pays, le Sango et le Français et, avant de devenir langue officielle, le Sango était considérée comme une non-langue et le chemin a été très long pour qu’elle devienne, aujourd’hui, langue officielle.
En 1991 j’ai créé un premier site sur le Sango en me disant, personne ne le lira, je le fais pour moi. Trois mois après je reçois des mails du [[w:Canada|Canada]], du Japon, de France, de gens qui étaient émus de voir le Sango sur internet. J’étais très surpris de voir que des gens pouvaient s’intéresser à cette langue. Cela m’a beaucoup encouragé à dire comment on peut faire pour mettre sur internet une langue inconnue pour qu’elle devienne connue. Bien sûr l’internet de 1991 n’est pas celui d’aujourd’hui où tout site digne de ce nom est interactif et social. En 1991 n’importe qui pouvait créer une page internet et mettre sa langue dessus. C’est comme si on mettait un poster sur des murs. Cela fait de ma langue une langue morte sur internet. Pour qu’elle devienne langue vivante, il faut qu’il y ait derrière une communauté. Des gens qui s’écrivent, se répondent, qui réagissent. Donc il faut la formation d’une ressource humaine, d’une communauté qui communique et travaille dans cette langue. Avant même de mettre cette langue sur internet il faut qu’elle soit écrite. Si elle n’est pas écrite, il faut passer par des techniques de reconnaissance vocale qui ne sont pas à la portée de tout le monde, c’est réalisable mais il faut des spécialistes pour le faire. Une fois que la langue est écrite, vous savez tout le débat que l’on a à se mettre d’accord sur une orthographe, il faut pouvoir collecter des textes, créer des forums de discussions.
J’ai été amené à écrire cet ouvrage qui est diffusé en [[w:portugais|portugais]], en [[w:russe|russe]], en français, en [[w:anglais|anglais]] et en [[w:espagnol|espagnol]] « [http://www.unesco.org/new/fr/communication-and-information/resources/publications-and-communication-materials/publications/full-list/securing-a-place-for-a-language-in-cyberspace/ Comment assurer la présence d'une langue dans le cyberespace ?] ». Moi je suis parti d’une langue très petite, parlée par deux ou trois personnes, dans la mesure où ces deux ou trois personnes sont décidées à la faire connaître, il faut développer les ressources linguistiques — décrire la langue, écrire la grammaire, écrire les dictionnaires — et aussi traduire le vocabulaire technique pour qu’elle puisse être vivante sur internet, comment on dit naviguer, cliquer,… ce sont des métaphores qu’on doit culturellement intégrer.
Il faut également développer les ressources culturelles. Les gens qui parlent cette langue ont une culture. Comment faire pour transmettre cette culture pour faire partager cela ? Hier j’étais très heureux de voir l’excellence du spectacle fourni par ces enfants. Je me suis dit, y a t-il un moyen de le mettre sur internet pour que ce soit partagé jusqu’au fin fond de l’univers ? Ce que les enfants ont dit est universel. Comment constituer les ressources culturelles locales sous un format partageable sur internet ? Il y a donc la langue, les ressources linguistiques, les ressources culturelles et ensuite les ressources humaines, former les gens pour qu’ils puissent travailler avec internet et enfin, développer les technologies pour l’accès.
:''Merci Marcel Diki Kidiri . Le représentant de l’institution auquel nous avons demandé d’apporter son point de vue à cette table ronde est chargé de la publication au Centre National de Documentation Pédagogique et s’intéresse particulièrement au support virtuel.''
==Représentant de l'institution : Bruno Dairou ([[w:Centre national de documentation pédagogique|Centre national de documentation pédagogique]])==
Le représentant de l’institution est là, très modestement, pour vous dire que justement, tout ce qu’on a développé autour de l’enseignement des langues est finalement très proprement enrichi par les langues régionales. Et, évidemment, pour différentes raisons, sans doute le poids de l’enseignement de la langue française dans le socle commun, des motifs politiques, des motifs linguistiques bien sûr avec une insuffisante description des langues, donc on vient plutôt dans l’idée de voir comment on peut travailler ensemble, beaucoup plus qu’on ne l’a fait jusque là.
Pour autant, ce n’est pas négliger la place des langues sur internet et dans les nouvelles technologies. En tous cas, le CNDP s’est saisi à bras le corps de tout cela et pour plusieurs raisons. D’abord, bien évidemment, parce que la demande était forte.
Il y avait à la fois une nouvelle façon d’enseigner les langues vivantes et il y avait, de manière complémentaire, le problème du français langue étrangère, langue seconde, langue de scolarisation. Cet ensemble a fait qu’il a fallu développer des outils. Ces outils qui nous posent des tas de problèmes et je pense qu’il faut se parler franchement, de validation des contenus, il est certain que c’est de la qualité pédagogique qu’il nous faut sur ces outils, donc des circuits de validation. Le CNDP fournit les ressources pour les enseignants donc il faut que ces contenus soient validés, fiables et qu’on arrive à les reproduire et les utiliser.
On a développé des outils, je pense - en vous laissant de côté tout ce qui sera les tableaux blancs interactifs - au fait de remplir les espaces numériques de travail qui a occupé beaucoup de forces vives au CNDP, en matière de langues vivantes, et cela a décentré la position de l’enseignant dans la classe. Donc ce n’était plus un dispositif frontal, c’était une utilisation active de ces méthodes grâce aux nouvelles technologies. Ce qui a permis de nouveaux rebonds, d’utiliser et de créer de nouveaux outils, tablettes numériques que nous fournissons très pauvrement en contenus, nous n’en sommes qu’au début et, ce matin dans les ateliers, cela a été évoqué très richement et il faudrait que l’on puisse évoquer des partenariats, mais il y a aussi ce que l’on appelle et que nous tirons de chez nos amis canadiens, la [http://eduscol.education.fr/langues/usages/baladodiffusion baladodiffusion], donc le fait qu’on utilise désormais ce qui est de l’univers des élèves, donc la possibilité de descendre de l’information sur leurs baladeurs, que ce soit en audio ou vidéo, que ce soient eux-même qui génèrent le flux. Donc le CNDP fournit des ressources dans ces domaines. Mais ce qui est intéressant et qu’on doit essayer de bâtir ensemble, et cela ressortait des ateliers de ce matin, c’est d’aboutir à des ressources et là aussi, je crois qu’il y a des partenariats à bâtir.
Cela ne veut pas dire qu’il n’y a rien d’existant, les CRDP ont beaucoup travaillé sur des ouvrages imprimés, mais aussi pour fournir des contenus numériques. L’intérêt pour nous, serait de travailler ensemble et je vous dis ce que le CNDP développe, nous développons les télévisions permettant d’aborder l’étude des langues, on essaye de le généraliser mais je crois qu’il y aurait un travail en commun à faire, des projets voient le jour, de plateformes de vidéo qui restent à nourrir, et il y aurait la possibilité d’introduire les langues régionales de manière pertinente, les langues en ligne, nous avons des séquences nombreuses, mais sur les langues régionales cela reste encore à développer et à bâtir. C’est le cas aussi de sites gratuits très consultés, plus d’un million de clics par an, sur lesquels la place des langues régionales reste à faire.
C’est vous dire que le CNDP est partie prenante de cela et on continue d’accompagner les langues des outre-mer mais c’est à l’état embryonnaire et je crois que cela peut être un effet de ces états généraux, se dire qu’il est grand temps qu’on travaille plus grandement ensemble.
==Vos réactions sur cette table ronde==
[[Catégorie:États généraux du multilinguisme dans les outre-mer]]
l105op7wlggp3ejp62gmvone0o5elmj
Code de la route/Signalisation
0
64838
744336
742545
2025-06-09T00:08:23Z
2A01:CB15:1C6:3300:7697:79FF:FEEB:D56F
/* Balises et bornes */
744336
wikitext
text/x-wiki
<noinclude>{{Code de la route}}</noinclude>
La signalisation routière permet de gérer l'utilisation des routes par les usagers (automobiles et camions, deux-roues ou piétons). Elle consiste en deux grands ensembles, à savoir la signalisation routière verticale, qui comprend les panneaux, les balises et les feux tricolores et la signalisation routière horizontale, constituée des marquages au sol.
==Agents==
Les agents sont prioritaires sur toute autre forme de signalisation, leur intervention est généralement temporaire.
===Signaux imposant l'arrêt===
*l'agent lève le bras
*l'agent est de face ou de dos, les bras écartés
*l'agent tient un feu rouge clignotant
===Autres signaux===
*l'agent est de profil : ''passage autorisé''
*l'agent agite légèrement le bras de haut en bas : ''ralentir''
*l'agent vous indique une direction : ''serrer à droite ou à gauche''
*l'agent tend un bras et fais de grands mouvements de l'autre : ''accélérer
''
''Note'' : un motard peut également vous faire signe de vous arrêter en tendant un bras devant vous.
==Feux==
Les feux servent à réguler la circulation aux intersections.
===Feux tricolores===
Les feux ont trois couleurs différentes, s'animant en cycle du bas vers le haut :
<gallery>
Traffic light.gif|Un feu tricolore
Traffic_lights_green.svg|'''Vert''' : vous pouvez passer si la voie est libre
Traffic_lights_yellow.svg|'''Jaune''' : arrêt
Traffic_lights_red.svg|'''Rouge''' : arrêt obligatoire
</gallery>
====Formes particulières====
<gallery>
Feu cycles.svg|Feux pour les 2 roues (piste cyclable)
Feux bus.svg|Feux pour les bus (file des bus)
</gallery>
*'''Symboles''' : le feu concerne seulement les véhicules représentés
*'''Flèches''' : le feu ne concerne que les véhicules s'engageant sur les voix indiquées
====Cas particuliers====
*'''Jaune clignotant''' : vous pouvez passer, mais avec prudence, cela indique souvent un danger, une panne au niveau du feu ou des travaux.
*'''Feu éteint''' : vous devez suivre le reste de la signalisation tout en restant prudent bien sûr (panneaux, priorité à droite).
===Feux bicolores===
Ces feux permettent aux véhicules de passer un par un (lors d'un péage, de l'accès à un bac ou à un poste de douane par exemple).
*'''Rouge''' : accès impossible pour l'instant
*'''Vert''' : vous pouvez avancer, sous réserve d'absence de danger
===Feu rouge clignotant===
Il est interdit d'avancer tant que ce feu est allumé. Il protège généralement l'accès à une zone à risques.
=== Autres feux ===
Et quand le feu clignotant n'est ni jaune ni rouge, mais entre les deux, c'est-à-dire plutôt orange, comme certains feux pour le passage des tramways de Clermont-Ferrand ?
En tant que conducteur automobile dois-je passer prudemment comme pour un feu jaune clignotant ou stopper impérativement comme pour un feu rouge clignotant ?
<br clear="both">
==Panneaux==
Voir [[Code de la route/Liste des panneaux|la liste des panneaux]].
===Indications générales===
====Formes et couleurs====
La forme et la couleur des panneaux définit leur fonction :
*'''Triangle'''
**[[Image:A gamme normale.svg|25px]] ''Rouge'' : danger
**[[Image:PL road sign A-5.svg|25px]] ''Rouge et jaune'' : danger temporaire
*'''Rond'''
**[[Image:Spain traffic signal r100.svg|25px]] ''Rouge'' : interdiction
**[[Image:Zeichen 237 - Sonderweg Radfahrer, StVO 1992.svg|25px]] ''Bleu'' : obligation
*'''Carré/rectangle''' : indication/direction
====Panonceaux====
[[Image:Panneau A14.jpg|thumb|Un panneau muni d'un panonceau]]
Les panonceaux s'ajoutent à un panneau afin de compléter son information.
Un panonceau n'agit que sur le panneau situé directement au dessus de lui, sauf lorsque qu'un panneau de danger se trouve au dessus d'un panneau d'interdiction/obligation, alors le panonceau agit sur les deux panneaux.
Les différents types de panonceaux :
*'''Panonceau de distance''' : indique la distance à laquelle agit le panneau
*'''Panonceau d'étendue''' : indique la distance sur laquelle agit le panneau
*'''Panonceau de direction''' : indique la voie sur laquelle agit le panneau
*'''Panonceau de catégorie''' : indique la catégorie de véhicule concernée par le panneau
*'''Panneau d'indication''' : contient un texte précisant l'indication du panneau
*'''Panneau d'identification''' : indique l'accès à une route ou à un lieu (''ce sont les seuls panonceaux qui sont placés au-dessus du panneau'')
===Panneaux de danger===
Ils servent à attirer l'attention du conducteur sur un danger particulier et lui conseillent généralement de ralentir et d'augmenter sa vigilance.
====Implantation====
Les panneaux de danger sont placés :
*'''En agglomération''' : ''50 mètres'' avant le danger
*'''Hors agglomération''' : ''150 mètres'' avant le danger
La distance peut parfois être différente, elle est alors annoncée par un panonceau.
=====Exception=====
[[Image:France_road_sign_A18.svg|thumb|50px|Circulation dans les 2 sens]]
Il existe une seule exception, le panneau indiquant une circulation dans les deux sens est toujours placé à l'endroit où débute cette circulation (sauf indication contraire via un panonceau).
====Différents types de dangers====
=====Profil de la route=====
*[[Image:Vienna Convention road sign Aa-7a-V1.svg|25px]] Cassis ou dos-d'âne
*[[Image:France_road_sign_A16.svg|25px]] Descente dangereuse
*[[Image:France road sign A13b.svg|25px]] Passage piéton
=====Profil de la route=====
*[[Image:France_road_sign_A1a.svg|25px]] Virage à droite
*[[Image:Vienna Convention road sign Aa-1d-V1.svg|25px]] Succession de virages dont le premier est à droite
*[[Image:France road sign A3b.svg|25px]] Chaussée rétrécie par la gauche
=====État de la chaussée ou environnement particulier=====
*[[Image:France_road_sign_A4.svg|25px]] Chaussée particulièrement glissante
*[[Image:France_road_sign_A24.svg|25px]] Vent latéral
*[[Image:France_road_sign_A20.svg|25px]] Débouché sur un quai ou sur une berge
=====Passages à niveau=====
Ils sont annoncés par une balise avec 1, 2 ou 3 traits rouges.
Le nombre de balises dépend de l'implantation possible de ces balises.
Si la distance est entre 100 et 150 m il y aura 3 balises : 1 à la distance maximale et les 2 autres réparties au tiers et aux deux tiers de la distance. Elles portent 1 (la plus près du passage à niveau), 2 et 3 traits rouges (la plus éloignée du passage à niveau).
Si la distance est entre 50 et 100 m il y aura 2 balises : 1 à la distance maximale et la seconde à la moitié de la distance. Elles portent 1 (la plus près du passage à niveau) et 2 traits rouges (la plus éloignée du passage à niveau)
Si la distance est inférieure à 50 m il n'y aura qu'une seul balise portant une seule bande rouge.
Ces balises ne sont pas obligatoires en agglomération.
Il arrive que les services locaux implantent 3 balises malgré une distance réduite.
*[[Image:A7.svg|25px]] Passage à niveau muni de barrières à fonctionnement manuel
*[[Image:France_road_sign_A8.svg|25px]] Passage à niveau sans barrière
*[[Image:France road sign G1b.svg|25px]]Passage à niveau à voie unique : céder le passage
=====Autres voies de communication ou usagers=====
*[[Image:France_road_sign_A23.svg|25px]] Avions à basse altitude ou roulant au sol
*[[Image:France road sign A9.svg|25px]] Traversée de voies de tramways
*[[Image:France_road_sign_A6.svg|25px]] Pont mobile
*[[Image:France_road_sign_A13a.svg|25px]] Endroit fréquenté par des enfants
*[[Image:France road sign A21.svg|25px]] Débouché de cyclistes
*[[Image:France road sign A15c.svg|25px]] Passage de cavaliers
*[[Image:France_road_sign_A15b.svg|25px]] Passage d'animaux sauvages
*[[Image:France road sign A15a2.svg|25px]] Passage d'animaux domestiques
===Panneaux d'interdiction===
De forme circulaire à fond blanc et couronne rouge, ils signalent une interdiction d'accès ou de manœuvre, ou indiquent des règles de conduite spécifiques.
Blancs barrés de noir, ils annoncent la fin de l'interdiction.
===Panneaux d'obligation===
===Panneaux d'indication===
===Panneaux de direction===
===Panneaux de localisation===
==Balises et bornes==
Les balises comportent des bandes réfléchissantes pour une meilleure visibilité de nuit.
[[Fichier:Implantation-J4-virageàdroite.svg|thumb|300px|Implantation des chevrons dans un virage à droite.]]
<gallery>
J1.svg|Balise de virage
Balise J1 bis.webp|Balise de virage sur route fréquemment enneigée [[Fichier:N85 balises J1bis.jpg|150px]]
J3A.svg|Balise d'intersection
FR road beacon J4.svg|Chevron indiquant le sens du virage
J4A.svg|Balise de virage à 3 chevrons vers la droite
J4B.svg|Balise de virage à 3 chevrons vers la gauche
France road sign J5.svg|Balise d'ilôt, passer à droite
J6b.JPG|Délinéateur (Balisage des limites de chaussées) équipé d'un réflecteur catadioptrique destiné à effrayer les animaux sauvages
FR road beacon J7.svg|Manche à air. Balise indiquant l'endroit où souffle fréquemment un vent latéral violent ainsi que l'intensité et la direction de celui-ci
FR road beacon J11.svg|Dispositif de renforcement d'un marquage continu permanent
FR road beacon J12.svg|Dispositif de renforcement d'un marquage permanent en divergent
Balises J13.webp|Balise de signalisation d'obstacle [[Fichier:J13 et abri cantonnier.JPG|150px]]
FR road beacon J14a.svg|Balise de musoir signalant la divergence des voies [[Fichier:Pont de l'aire de Villeroy -3.jpg|150px]]
FR road beacon J14b.svg|Balises de musoir signalant la divergence des voies
</gallery>
[[Fichier:France road sign A1a.svg|64px|right]]
La signalisation des virages varie selon sa courbure, définissant une limite de vitesse pour le prendre sans danger.
Les virages sont classés en quatre catégories selon la différence entre la vitesse d’approche et la vitesse dans le virage.
Pour les classes A et B, un panneau pour annoncer le virage peut être présent en cas de mauvaise visibilité à l'approche.
<gallery widths="300px" heights="300px">
Virage cas1.svg|Aucune signalisation pour un virage de classe A.
Virage cas2.svg|Signalisation pour un virage de classe B.
Virage cas 3.svg|Signalisation pour un virage de classe C.
Virage cas 4.svg|Signalisation pour un virage de classe D.
</gallery>
==Marques sur la chaussée==
* Ligne continue blanche : Impossible de doubler.
* Ligne discontinue blanche : Possibilité de doubler.
* Ligne discontinue avec flèches blanche : Se rabattre sur la voie de droite.
* Ligne en zigzag jaune : Arrêt de bus.
=== Marquage des voies ===
Le diagramme ci-dessous montre trois voies dans un sens de circulation.
Une ligne discontinue à traits rapprochés marque la limite de la chaussée.
Une ligne discontinue à traits plus espacés marque la limite entre les voies.
[[Fichier:Marquage-route-3V.svg|center|500px]]
=== Lignes aux feux tricolores ===
La ligne d'effet de feux indique la limite d'arrêt du véhicule de tête.
Cette limite permet d'aménager un passage aux autres usagers de la route.
<gallery widths="250px" heights="250px">
Ligne-d'effet-de-feux.svg|'''Ligne d'effet de feux''' : les véhicules doivent s'arrêter au niveau de la ligne en pointillé.
Ligne-d'effet-de-feux-avec-sas.svg|'''Ligne d'effet de feux avec sas''' : les véhicules doivent s'arrêter au niveau de la première ligne en pointillé, laissant le couloir (« sas ») libre pour la traversée de cycles.
</gallery>
=== Flèches directionnelles sur les voies ===
Aux croisements permettant un changement de direction, il y a une flèche par voie indiquant aux véhicules quelles directions sont autorisées dans chacune des voies.
Si la voie sur laquelle il se trouve ne permet pas de prendre la direction voulue, le véhicule doit obligatoirement changer pour une voie permettant de la prendre.
Si aucune voie ne convient, le véhicule doit prendre l'une des directions autorisées.
[[Fichier:Flèches-directionnelles.svg|800px]]
=== Marquage au sol d'un ralentisseur ===
La présence d'un ralentisseur de type dos-d'âne est signalée par un marquage au sol constitué d'un ensemble de trois triangles blancs, disposés sur le ralentisseur dans l'axe de chaque voie de circulation et dont les pointes sont orientées dans le sens normal de la circulation.
Ce marquage n'est pas obligatoire dans les zones limitées à 30 km/h.
[[Fichier:Ralentisseur de type dos-d'âne et passage piétons - Aix-les-Bains.jpg|300px|thumb|Passage piétons sur un ralentisseur en ville.]]
[[Fichier:Marquage au sol réglementaire d'un ralentisseur (France).png]]
== Signalisation temporaire ==
La signalisation temporaire utilise des panneaux avec un fond jaune vif indiquant le danger temporaire (intempérie, accident, travaux...) au moins 200 mètres avant, avec des panneaux de restrictions à respecter pour éviter tout danger de circulation (limitation de vitesse, rabattement sur une autre voie, céder le passage, feu tricolore pour circulation alternée...).
{| class="wikitable"
|-
| [[Fichier:Balisage-danger-temporaire.svg|500px|center]]
| [[Fichier:Balisage-danger-urgence.svg|500px|center]]
|-
| [[Fichier:Chantier fixe alternat K10.svg|500px|center]]
| [[Fichier:Chantier fixe alternat feux.svg|500px|center]]
|-
| [[Fichier:Chantier-accotement.svg|500px|center]]
| [[Fichier:Chantier fixe alternat SP.svg|500px|center]]
|}
Le panneau de fin des restrictions temporaires est positionné au moins 50 mètres après le danger.
d6lbvfqtkxirrz7xyvx9vd3pdu6jsmr
Photographie/Personnalités/R/Jean Reutlinger/album n° 42
0
65217
744338
615015
2025-06-09T09:38:28Z
Yann
2
([[c:GR|GR]]) [[c:COM:FR|File renamed]]: [[File:Btv1b8596941p-p035.jpg]] → [[File:Album Reutlinger de portraits divers, vol. 42, btv1b8596941p-p035.jpg]]
744338
wikitext
text/x-wiki
{{Ph s Personnalités}}
<gallery widths="240px" heights="240px">
Btv1b8596941p-p005.jpg
Btv1b8596941p-p006.jpg
Btv1b8596941p-p007.jpg
Btv1b8596941p-p008.jpg
Btv1b8596941p-p009.jpg
Btv1b8596941p-p010.jpg
Btv1b8596941p-p011.jpg
Btv1b8596941p-p012.jpg
Btv1b8596941p-p013.jpg
Btv1b8596941p-p014.jpg
Btv1b8596941p-p015.jpg
Btv1b8596941p-p016.jpg
Demours, btv1b8596941p-p017.jpg
Btv1b8596941p-p018.jpg
Btv1b8596941p-p019.jpg
Btv1b8596941p-p020.jpg
Btv1b8596941p-p021.jpg
Btv1b8596941p-p022.jpg
Btv1b8596941p-p023.jpg
Btv1b8596941p-p024.jpg
Btv1b8596941p-p025.jpg
Btv1b8596941p-p026.jpg
Btv1b8596941p-p027.jpg
Btv1b8596941p-p028.jpg
Btv1b8596941p-p029.jpg
Btv1b8596941p-p030.jpg
Btv1b8596941p-p031.jpg
Btv1b8596941p-p032.jpg
Btv1b8596941p-p033.jpg
Btv1b8596941p-p034.jpg
Album Reutlinger de portraits divers, vol. 42, btv1b8596941p-p035.jpg
Btv1b8596941p-p036.jpg
Btv1b8596941p-p037.jpg
Btv1b8596941p-p038.jpg
Btv1b8596941p-p039.jpg
Btv1b8596941p-p040.jpg
Btv1b8596941p-p041.jpg
Btv1b8596941p-p042.jpg
Btv1b8596941p-p043.jpg
Btv1b8596941p-p044.jpg
Btv1b8596941p-p045.jpg
Btv1b8596941p-p046.jpg
Btv1b8596941p-p047.jpg
Btv1b8596941p-p048.jpg
Btv1b8596941p-p049.jpg
Btv1b8596941p-p050.jpg
Btv1b8596941p-p051.jpg
Btv1b8596941p-p052.jpg
Btv1b8596941p-p053.jpg
Btv1b8596941p-p054.jpg
Btv1b8596941p-p055.jpg
</gallery>
{{Ph Personnalités}}
oj03tvop7jri6btu1sgd17syq4oua64
Photographie/Personnalités/O/Stanislaw Julian Ostrorog
0
68502
744326
684418
2025-06-08T16:27:40Z
Gereon K.
50597
([[c:GR|GR]]) [[c:COM:FR|File renamed]]: [[File:Oscar Wilde (1854-1900), by Alfred Ellis & Walerie, 1892 2.jpg]] → [[File:Oscar Wilde (1854-1900), by Alfred Ellis & Walery, 1892 2.jpg]] [[c:COM:FR#FR3|Criterion 3]] (obvious error)
744326
wikitext
text/x-wiki
{{Ph s Personnalités}}
== Biographie ==
Le Comte '''Stanisław Julian Ostrorog''' (1830-1890), né à Mohylewo, en Lituanie, devint citoyen britannique en 1862 : il ouvrit un studio à Londres en 1883.
Stanislaw Ostrorog utilisa le pseudonyme de Walery en référence au prénom de sa femme, Waleria. Après sa mort en 1890, son fils Stanislaw Julian Ignacy, Comte Ostrorog (1863-1935), reprit le studio de son père, en association (entre 1890 et 1900) avec [[Alfred Ellis]], sous le nom ''Ellis et Walery''. Walery est connu pour son célèbre portrait de la Reine Victoria.
Le jeune Comte Ostrorog est souvent confondu avec [[Lucien Waléry]], qui vécut et travailla à Paris dans la période 1900 - 1930. Certains prétendent que Lucien Waléry était la même personne que le jeune Comte Ostrorog, qui est supposé avoir déménagé à Paris vers 1900, mais il s'agit plus probablement de deux personnes différentes.
== Publications ==
== Galerie de photographies ==
<gallery widths="240px" heights="240px">
Antoinette Trebelli 001.jpg
Baragnon, Louis Numa.jpg
Édouard Brissaud.jpg
Edna Loftus.jpg
Francisco Coello, de Wálery.jpg
Galli, Henri.jpg
Helen Mathers 0001.jpg
Hugo Walery 2.png
Hugo Walery phototypie.jpg
Hugo Walery.png
Jules de Lesseps.jpg
Lesseps, Jules.jpg
John Thomas North, entrepreneur.jpg
Oscar Wilde (1854-1900), by Alfred Ellis & Walery, 1892 2.jpg
Oscar Wilde (1854-1900), by Alfred Ellis & Walerie, 1892.jpg
Princess Beatrice 1886.jpg
Sir Arthur Seymour Sullivan.jpg
Victor Hugo by Walery c1875.jpg
Victor Hugo.jpg
Walery - Victor Hugo.jpg
Weedon Grossmith-Killiekrankie.jpg
William Lionel Wyllie - The Oceanic.jpg
</gallery>
== Bibliographie ==
{{Ph Personnalités}}
{{DEFAULTSORT:Nom, Prénom}}
elqshg2by4lrwu151aujvfo9orfd2eu
Code de la route/Intersections et priorités
0
75213
744335
725983
2025-06-08T23:48:43Z
2A01:CB15:1C6:3300:7697:79FF:FEEB:D56F
FR road sign G1c.svg
744335
wikitext
text/x-wiki
<noinclude>{{Code de la route}}</noinclude>
Les règles de circulation à l'approche d'une intersection de plusieurs routes ou d'un croisement entre routes et d'autres voies de transport (voie ferrée, fleuve, ...) doivent être respectées pour éviter les accidents.
De manière générale, quand une intersection est annoncée, la vigilance doit être accrue.
Diminuer sa vitesse aide à contrôler son véhicule en cas d'arrêt rapide à effectuer, et notamment pour ne pas freiner brusquement pour éviter les chocs avec les véhicules venant par l'arrière.
L'utilisation des clignotants est obligatoire pour les changements de direction, afin de signaler ses intentions.
== Intersections ==
[[Fichier:J3A.svg|left|120x120px|Balise d'intersection]]
Lorsque plusieurs routes de croisent, une signalisation permet de savoir quelle voie a la priorité pour passer.
La signalisation dépend du type de carrefour et de la visibilité.
À l'arrivée sur une intersection, les véhicules doivent diminuer leur vitesse afin de pouvoir s'arrêter facilement (rapidement mais pas brusquement) au cas où d'autres véhicules croiseraient la route.
En France, les panneaux annonçant l'arrivée à un carrefour sont à une distance minimale de 50 mètres en ville ou 150 mètres en dehors.
Des balises situées au croisement peuvent signaler l'intersection.
{{clr|left}}
=== Croisement ===
{|
|-
| [[Fichier:France road sign AB1.svg|120x120px]]
|
;Croisement, priorité à droite:Il s'agit de la priorité par défaut en l'absence de panneau. La voie à droite est prioritaire, et les véhicules venant de la gauche doivent donc céder la priorité.
|-
| [[Fichier:France road sign AB2.svg|120x120px]]
|
;Croisement d'une route prioritaire:La route est prioritaire, mais il faut rester prudent à l'intersection. Les routes croisées ont en général une signalisation d'arrêt ou de céder le passage.
|-
| [[Fichier:France road sign A17.svg|120x120px]]
|
;Croisement avec feux tricolores:Les feux ont trois couleurs différentes, s'animant en cycle du bas vers le haut :
<gallery widths="80px">
Traffic light.gif|Un feu tricolore
Traffic_lights_green.svg|'''Vert''' : vous pouvez passer si la voie est libre
Traffic_lights_yellow.svg|'''Jaune''' : arrêt
Traffic_lights_red.svg|'''Rouge''' : arrêt obligatoire
</gallery>
Voir aussi [[../Signalisation#Lignes aux feux tricolores|les lignes de feux]].
|}
=== Ronds-points ===
Les carrefours à sens giratoire (ou ronds-points) permettent le croisement d'un nombre quelconque de routes.
{|
|-
| [[Fichier:France road sign AB25.svg|120x120px]]
|
;Carrefour à sens giratoire:Le panneau indique le sens de circulation.
|-
| [[Fichier:France road sign B21-1.svg|120x120px]]
|
Ce panneau est présent sur le terre-plein central pour rappeler de contourner l'obstacle par la droite.
|}
À l'arrivée au carrefour, la présence d'une signalisation de « cédez le passage » indique aux véhicules qu'ils doivent céder le passage aux véhicules venant de la gauche, c'est-à-dire ceux qui sont déjà dans le rond-point.
En l'absence de cette signalisation, la priorité à droite s'applique, c'est-à-dire que les véhicules peuvent s'engager dans le rond-point, et doivent céder le passage à ceux qui s'y engagent car ils viennent de la droite.
=== Céder le passage ===
Les véhicules doivent ralentir. Si un autre véhicule arrive par l'une des routes croisées, il faut marquer l'arrêt pour lui céder le passage.
<gallery>
France road sign AB3b.svg|Panneau de signalisation avancée d'un cédez le passage
France road sign AB3a.svg|Cédez le passage à l'intersection
</gallery>
=== Arrêt obligatoire ===
L'arrêt est obligatoire, même si aucun véhicule ne semble arriver au croisement.
<gallery>
France road sign AB5.svg|Panneau de signalisation avancée d'un arrêt
France road sign AB4.svg|Arrêt à l'intersection
</gallery>
Le panneau stop est accompagné d'un marquage au sol : une large bande blanche que les véhicules ne doivent pas dépasser pour marquer l'arrêt.
[[Fichier:Cusset - Avenue Gilbert Roux, STOP en pleine voie.JPG|center|500px]]
=== Route prioritaire ===
En France, une portion de route peut être marquée comme prioritaire entre les deux panneaux suivants :
<gallery>
France road sign AB6.svg|Panneau annonçant la caractère prioritaire d'une route
France road sign AB7.svg|Panneau annonçant la fin du caractère prioritaire d'une route
</gallery>
== Croisée fluviale ==
[[Fichier:France road sign A6.svg|120x120px|left|Pont à bascule]]
[[Fichier:FR 17 Le Mung - Panneaux AB2 et A6 surmontés d'un feu.jpg|vignette|right|Panneaux surmontés d'un feu, en Charente-Maritime.]]
;Priorité:Les bateaux et navires ont toujours la priorité.
:La traversée d'un cours d'eau où les bateaux circulent peut se faire sur un pont basculant. Dans ce cas, un feu peut signaler à tous les usagers de s'arrêter pendant la levée du pont permettant ainsi le passage d'un ou plusieurs bateaux.
{{clr}}
Il existe différents types de ponts amovibles.
<gallery perrow="4" style="margin:auto;">
MovableBridge transport.gif|Pont transbordeur
Pont Transbordeur Rochefort 02.JPG|Pont transbordeur de Rochefort
MovableBridge swing.gif|Pont tournant
Pont caronte.jpg|Pont tournant ferroviaire de Caronte à Martigues
MovableBridge lift.gif|Pont levant
Canteleu003view.jpg|Pont levant Gustave Flaubert à Rouen
MovableBridge subm.gif|Pont submersible
20090731 korinthos canal18.jpg|Pont submersible d'Isthmia (canal de Corinthe, Grèce)
MovableBridge tilt.gif|Pont basculant
Gateshead Millennium Bridge Down.jpg|Pont basculant au dessus de la Tyne : Gateshead Millennium Bridge de Newcastle
Drawbridge.gif|Fonctionnement du pont-levis à chaînes sans flèche
Chateau Dinan1.jpg|Pont-levis sans flèche basculant en se relevant par l'avant du château de Dinan
MovableBridge draw.gif|Pont basculant (double tabliers)
Martigues — Pont levant sur le canal Galliffet.JPG|Pont basculant du canal Galliffet à Martigues
MovableBridge roll.gif|Pont basculant (simple tablier)
Pont basculant Rochefort 001.jpg|Pont basculant de Rochefort
</gallery>
== Croisée du chemin de fer ==
;Priorité:Les trains ont toujours la priorité.
[[Fichier:Panneaux A7 M9z signal automatique J10.jpg|center|thumb|400px|Annonce de passage à niveau gardé]]
Les passages à niveaux sont pré-annoncés avec l'un des panneaus de danger ci-dessous, avec un décompte d'approche signalé par 3 barres rouges en diagonal sur une balise, puis 2 barres, puis 1 barre.
<gallery>
France road sign A7.svg|Passage à niveau gardé
France road sign A8.svg|Passage à niveau non gardé
France road sign A9.svg|Passage de tramway
</gallery>
Le chemin de fer croise les voies de circulations des véhicules et piétons, aux passages à niveaux qui sont en général munis de barrières ou semi-barrières ainsi qu'un feu rouge.
* Une barrière bloque les voies des deux sens de circulation.
* Une semi-barrière ne bloque que les voies d'un seul sens de circulation. Lorsqu'elles sont disposées avant la voie ferrée dans chaque sens de circulation, elles permettent à un véhicule engagé sur les voies ferrées pendant l'abaissement des barrières de dégager (ce qui peut arriver notamment si le feu clignotant est en panne).
[[Fichier:Level crossing P1210798.jpg|thumb|center|400px|alt=Un passage à niveau à fonctionnement automatique|Passage à niveau automatique, à demi-barrières (France)]]
Lors de l'approche d'un train, le feu rouge clignote et les barrières s'abaissent ensuite, le temps qu'un véhicule qui serait engagé sur le chemin de fer puisse dégager. Tout usager (véhicules, piétons) doit s'arrêter à une distance suffisante du feu et des barrières.
Après le passage du ou des trains, les barrières de lèvent, puis le feu cesse de clignoter indiquant aux véhicules qu'ils peuvent traverser la voie ferrée.
<gallery mode="packed">
Tyne&Wear Metrotrain on level crossing.jpg|Passage à niveau sans barrières en Angleterre.
StGermain des Prés.Loiret-passage à niveau-20.jpg|Signalisation française d'un passage à niveau non protégé.
Passage à niveau vu du train.jpg|Passage à niveau à quatre demi-barrières vu d'un train.
</gallery>
Les panneaux ci-dessous servent à la signalisation de position d'un passage à niveau à une voie sans barrières ni demi-barrières et munis ou non de signalisation automatique, ou d'une aire de danger aérien où les mouvements d'avions à basse altitude constituent un danger pour la circulation routière.
<gallery>
FR road sign G1.svg|Passage à niveau à une voie ou aire de danger aérien, sans signalisation automatique.
FR road sign G1 bis.svg|Passage à niveau à une voie ou aire de danger aérien, avec signalisation automatique.
France road sign G1b.svg|Passage à niveau à une voie ou aire de danger aérien, sans signalisation automatique.
France road sign G1b bis.svg|Passage à niveau à une voie ou aire de danger aérien, avec signalisation automatique.
FR road sign G1c.svg|Passage à niveau à plusieurs voies, sans barrière ni demi-barrière, non munis de signalisation automatique.
</gallery>
Le panneau est vertical quand l'espace est insuffisant pour un panneau horizontal.
[[Fichier:FR 17 Saint-Laurent-de-la-Prée - PN 182 - Panneaux AB4 et G1a et M9z.jpg|thumb|center|400px|Arrêt obligatoire devant le passage à niveau non gardé à plusieurs voies.]]
== Piétons ==
En général, les passages piétons sont situés au niveau des intersections, particulièrement les carrefours avec feux tricolores, mais aussi au milieu d'une route quand le carrefour le plus proche est éloigné.
Pour plus de détails, voir [[../Piétons#Croisée de la chaussée|Passages piétons]].
m0101tn7glz088rl3dcsjotn5i9a7ks
Les cartes graphiques/Le support matériel du lancer de rayons
0
80578
744327
726011
2025-06-08T16:40:50Z
Mewtow
31375
/* Les circuits spécialisés pour les calculs liés aux rayons */
744327
wikitext
text/x-wiki
Les cartes graphiques actuelles utilisent la technique de la rastérisation, qui a été décrite en détail dans le chapitre sur les cartes accélératrices 3D. Mais nous avions dit qu'il existe une seconde technique générale pour le rendu 3D, totalement opposée à la rastérisation, appelée le '''lancer de rayons'''. Cette technique a cependant été peu utilisée dans les jeux vidéo, jusqu'à récemment. La raison est que le lancer de rayons demande beaucoup de puissance de calcul, sans compter que créer des cartes accélératrices pour le lancer de rayons n'est pas simple.
Mais les choses commencent à changer. Quelques jeux vidéos récents intègrent des techniques de lancer rayons, pour compléter un rendu effectué principalement en rastérisation. De plus, les cartes graphiques modernes incorporent quelques circuits pour accélérer le lancer de rayons, même s'ils restent marginaux des compléments au rendu par rastérisation. S'il a existé des cartes accélératrices totalement dédiées au rendu en lancer de rayons, elles sont restées confidentielles. Aussi, nous allons nous concentrer sur les cartes graphiques récentes, et allons peu parler des cartes accélératrices dédiées au lancer de rayons.
==Le lancer de rayons==
Le lancer de rayons et la rastérisation. commencent par générer la géométrie de la scène 3D, en plaçant les objets dans la scène 3D, et en effectuant l'étape de transformation des modèles 3D, et les étapes de transformation suivante. Mais les ressemblances s'arrêtent là. Le lancer de rayons effectue l'étape d'éclairage différemment, sans compter qu'il n'a pas besoin de rastérisation.
===Le ''ray-casting'' : des rayons tirés depuis la caméra===
La forme la plus simple de lancer de rayon s'appelle le '''''ray-casting'''''. Elle émet des lignes droites, des '''rayons''' qui partent de la caméra et qui passent chacun par un pixel de l'écran. Les rayons font alors intersecter les différents objets présents dans la scène 3D, en un point d'intersection. Le moteur du jeu détermine alors quel est le point d'intersection le plus proche, ou plus précisément, le sommet le plus proche de ce point d'intersection. Ce sommet est associé à une coordonnée de textures, ce qui permet d'associer directement un texel au pixel associé au rayon.
[[File:Raytrace trace diagram.png|centre|vignette|upright=2|Raycasting, rayon simple.]]
En somme, l'étape de lancer de rayon et le calcul des intersections remplacent l'étape de rasterisation, mais les étapes de traitement de la géométrie et des textures existent encore. Après tout, il faut bien placer les objets dans la scène 3D/2D, faire diverses transformations, les éclairer. On peut gérer la transparence des textures assez simplement, si on connait la transparence sur chaque point d'intersection d'un rayon, information présente dans les textures.
[[File:Anarch short gameplay.gif|vignette|Exemple de rendu en ray-casting 2D dans un jeu vidéo.]]
En soi, cet algorithme est simple, mais il a déjà été utilisé dans pas mal de jeux vidéos. Mais sous une forme simple, en deux dimensions ! Les premiers jeux IdSoftware, dont Wolfenstein 3D et Catacomb, utilisaient cette méthode de rendu, mais dans un univers en deux dimensions. Cet article explique bien cela : [[Les moteurs de rendu des FPS en 2.5 D\Le moteur de Wolfenstein 3D|Le moteur de rendu de Wolfenstein 3D]]. Au passage, si vous faites des recherches sur le ''raycasting'', vous verrez que le terme est souvent utilisé pour désigner la méthode de rendu de ces vieux FPS, alors que ce n'en est qu'un cas particulier.
[[File:Simple raycasting with fisheye correction.gif|centre|vignette|upright=2|Simple raycasting with fisheye correction]]
===Le ''raytracing'' proprement dit===
Le lancer de rayon proprement dit est une forme améliorée de ''raycasting'' dans la gestion de l'éclairage et des ombres est modifiée. Le lancer de rayon calcule les ombres assez simplement, sans recourir à des algorithmes compliqués. L'idée est qu'un point d'intersection est dans l'ombre si un objet se trouve entre lui et une source de lumière. Pour déterminer cela, il suffit de tirer un trait entre les deux et de vérifier s'il y a un obstacle/objet sur le trajet. Si c'est le cas, le point d'intersection n'est pas éclairé par la source de lumière et est donc dans l'ombre. Si ce n'est pas le cas, il est éclairé avec un algorithme d'éclairage.
Le trait tiré entre la source de lumière et le point d'intersection est en soi facile : c'est rayon, identique aux rayons envoyés depuis la caméra. La différence est que ces rayons servent à calculer les ombres, ils sont utilisés pour une raison différente. Il faut donc faire la différence entre les '''rayons primaires''' qui partent de la caméra et passent par un pixel de l'écran, et les '''rayon d'ombrage''' qui servent pour le calcul des ombres.
[[File:Ray trace diagram.svg|centre|vignette|upright=2|Principe du lancer de rayons.]]
Les calculs d'éclairage utilisés pour éclairer/ombrer les points d'intersection vous sont déjà connus : la luminosité est calculée à partir de l'algorithme d'éclairage de Phong, vu dans le chapitre "L'éclairage d'une scène 3D : shaders et T&L". Pour cela, il faut juste récupérer la normale du sommet associé au point d'intersection et l'intensité de la source de lumière, et de calculer les informations manquantes (l'angle normale-rayons de lumière, autres). Il détermine alors la couleur de chaque point d'intersection à partir de tout un tas d'informations.
===Le ''raytracing'' récursif===
[[File:Glasses 800 edit.png|vignette|Image rendue avec le lancer de rayons récursif.]]
La technique de lancer de rayons précédente ne gère pas les réflexions, les reflets, des miroirs, les effets de spécularité, et quelques autres effets graphiques de ce style. Pourtant, ils peuvent être implémentés facilement en modifiant le ''raycasting'' d'une manière très simple.
Il suffit de relancer des rayons à partir du point d'intersection. La direction de ces '''rayons secondaires''' est calculée en utilisant les lois de la réfraction/réflexion vues en physique. De plus, les rayons secondaires peuvent eux-aussi créer des rayons secondaires quand ils sont reflétés/réfractés, etc. La technique est alors appelée du ''lancer de rayons récursif'', qui est souvent simplement appelée "lancer de rayons".
[[File:Recursive raytracing.svg|centre|vignette|upright=2|Lancer de rayon récursif.]]
===Les avantages et désavantages comparé à la rastérisation===
L'avantage principal du lancer de rayons est son rendu de l'éclairage, qui est plus réaliste. Les ombres se calculent naturellement avec cette méthode de rendu, là où elles demandent des ruses comme des lightmaps, des textures pré-éclairées, divers algorithmes d'éclairage géométriques, etc. Les réflexions et la réfraction sont gérées naturellement par le lancer de rayon récursif, alors qu'elles demandent des ruses de sioux pour obtenir un résultat correct avec la rastérisation.
[[File:ViewFrustum.svg|vignette|upright=1|Volume délimité par la caméra (''view frustum'').]]
Pour ce qui est des performances théoriques, le lancer de rayons se débrouille mieux sur un point : l'élimination des pixels/surfaces cachés. La rastérisation a tendance à calculer inutilement des portions non-rendues de la scène 3D, et doit utiliser des techniques de ''culling'' ou de ''clipping'' pour éviter trop de calculs inutiles. Ces techniques sont très puissantes, mais imparfaites. De nombreux fragments/pixels calculés sont éliminés à la toute fin du pipeline, grâce au z-buffer, après avoir été calculés et texturés. Le lancer de rayons se passe totalement de ces techniques d'élimination des pixels cachés, car elle ne calcule pas les portions invisibles de l'image par construction : pas besoin de ''culling'', de ''clipping'', ni même de z-buffer.
Mais tous ces avantages sont compensés par le fait que le lancer de rayons est plus lent sur un paquet d'autres points. Déjà, les calculs d'intersection sont très lourds, ils demandent beaucoup de calculs et d'opérations arithmétiques, plus que pour l'équivalent en rastérisation. Ensuite, de nombreuses optimisations présentes en rastérisation ne sont pas possibles. Notamment, le lancer de rayon utilise assez mal la mémoire, dans le sens où les accès en mémoire vidéo sont complétement désorganisés, là où le rendu 3D a des accès plus linéaires qui permettent d'utiliser des mémoires caches.
==Les optimisations du lancer de rayons liées aux volumes englobants==
Les calculs d'intersections sont très gourmands en puissance de calcul. Sans optimisation, on doit tester l'intersection de chaque rayon avec chaque triangle. Mais diverses optimisations permettent d'économiser des calculs. Elles consistent à regrouper plusieurs triangles ensemble pour rejeter des paquets de triangles en une fois. Pour cela, la carte graphique utilise des '''structures d'accélération''', qui mémorisent les regroupements de triangles, et parfois les triangles eux-mêmes.
===Les volumes englobants===
[[File:BoundingBox.jpg|vignette|Objet englobant : la statue est englobée dans un pavé.]]
L'idée est d'englober chaque objet par un pavé appelé un ''volume englobant''. Le tout est illustré ci-contre, avec une statue représentée en 3D. La statue est un objet très complexe, contenant plusieurs centaines ou milliers de triangles, ce qui fait que tester l'intersection d'un rayon avec chaque triangle serait très long. Par contre, on peut tester si le rayon intersecte le volume englobant facilement : il suffit de tester les 6 faces du pavé, soit 12 triangles, pas plus. S'il n'y a pas d'intersection, alors on économise plusieurs centaines ou milliers de tests d'intersection. Par contre, s'il y a intersection, on doit vérifier chaque triangle. Vu que les rayons intersectent souvent peu d'objets, le gain est énorme !
L'usage seul de volumes englobant est une optimisation très performante. Au lieu de tester l'intersection avec chaque triangle, on teste l'intersection avec chaque objet, puis l'intersection avec chaque triangle quand on intersecte chaque volume englobant. On divise le nombre de tests par un facteur quasi-constant, mais de très grande valeur.
Il faut noter que les calculs d'intersection sont légèrement différents entre un triangle et un volume englobant. Il faut dire que les volumes englobant sont généralement des pavées, ils utilisent des rectangles, etc. Les différences sont cependant minimales.
===Les hiérarchies de volumes englobants===
Mais on peut faire encore mieux. L'idée est de regrouper plusieurs volumes englobants en un seul. Si une dizaine d'objets sont proches, leurs volumes englobants seront proches. Il est alors utile d'englober leurs volumes englobants dans un super-volume englobant. L'idée est que l'on teste d'abord le super-volume englobant, au lieu de tester la dizaine de volumes englobants de base. S'il n'y a pas d'intersection, alors on a économisé une dizaine de tests. Mais si intersection, il y a, alors on doit vérifier chaque sous-volume englobant de base, jusqu'à tomber sur une intersection. Vu que les intersections sont rares, on y gagne plus qu'on y perd.
Et on peut faire la même chose avec les super-volumes englobants, en les englobant dans des volumes englobants encore plus grands, et ainsi de suite, récursivement. On obtient alors une '''hiérarchie de volumes englobants''', qui part d'un volume englobant qui contient toute la géométrie, hors skybox, qui lui-même regroupe plusieurs volumes englobants, qui eux-mêmes...
[[File:Example of bounding volume hierarchy.svg|centre|vignette|upright=2|Hiérarchie de volumes englobants.]]
Le nombre de tests d'intersection est alors grandement réduit. On passe d'un nombre de tests proportionnel aux nombres d'objets à un nombre proportionnel à son logarithme. Plus la scène contient d'objets, plus l'économie est importante. La seule difficulté est de générer la hiérarchie de volumes englobants à partir d'une scène 3D. Divers algorithmes assez rapides existent pour cela, ils créent des volumes englobants différents. Les volumes englobants les plus utilisés dans les cartes 3D sont les '''''axis-aligned bounding boxes (AABB)'''''.
La hiérarchie est mémorisée en mémoire RAM, dans une structure de données que les programmeurs connaissent sous le nom d'arbre, et précisément un arbre binaire ou du moins d'un arbre similaire (''k-tree''). Traverser cet arbre pour passer d'un objet englobant à un autre plus petit est très simple, mais a un défaut : on saute d'on objet à un autre en mémoire, les deux sont souvent éloignés en mémoire. La traversée de la mémoire est erratique, sautant d'un point à un autre. On n'est donc dans un cas où les caches fonctionnent mal, ou les techniques de préchargement échouent, où la mémoire devient un point bloquant car trop lente.
===La cohérence des rayons===
Les rayons primaires, émis depuis la caméra, sont proches les uns des autres, et vont tous dans le même sens. Mais ce n'est pas le cas pour des rayons secondaires. Les objets d'une scène 3D ont rarement des surfaces planes, mais sont composés d'un tas de triangles qui font un angle entre eux. La conséquence est que deux rayons secondaires émis depuis deux triangles voisins peuvent aller dans des directions très différentes. Ils vont donc intersecter des objets très différents, atterrir sur des sources de lumières différentes, etc. De tels rayons sont dits '''incohérents''', en opposition aux rayons cohérents qui sont des rayons proches qui vont dans la même direction.
Les rayons incohérents sont peu fréquents avec le ''rayctracing'' récursif basique, mais deviennent plus courants avec des techniques avancées comme le ''path tracing'' ou les techniques d'illumination globale. En soi, la présende de rayons incohérents n'est pas un problème et est parfaitement normale. Le problème est que le traitement des rayons incohérent est plus lent que pour les rayons cohérents. Le traitement de deux rayons secondaires voisins demande d'accéder à des données différentes, ce qui donne des accès mémoire très différents et très éloignés. On ne peut pas profiter des mémoires caches ou des optimisations de la hiérarchie mémoire, si on les traite consécutivement. Un autre défaut est qu'une même instance de ''pixels shaders'' va traiter plusieurs rayons en même temps, grâce au SIMD. Mais les branchements n'auront pas les mêmes résultats d'un rayon à l'autre, et cette divergence entrainera des opérations de masquage et de branchement très couteuses.
Pour éviter cela, les GPU modernes permettent de trier les rayons en fonction de leur direction et de leur origine. Ils traitent les rayons non dans l'ordre usuel, mais essayent de regrouper des rayons proches qui vont dans la même direction, et de les traiter ensemble, en parallèle, ou l'un après l'autre. Cela ne change rien au rendu final, qui traite les rayons en parallèle. Ainsi, les données chargées dans le cache par le premier rayon seront celles utilisées pour les rayons suivants, ce qui donne un gain de performance appréciable. De plus, cela évite d'utiliser des branchements dans les ''pixels shaders''. Les méthodes de '''tri de rayons''' sont nombreuses, aussi en faire une liste exhaustive serait assez long, sans compter qu'on ne sait pas quelles sont celles implémentées en hardware, ni commetn elles le sont.
==Le matériel pour accélérer le lancer de rayons==
Le lancer de rayons a toujours besoin de calculer la géométrie, d'appliquer des textures et de faire des calculs d'éclairage. Sachant cela, beaucoup de chercheurs se sont dit qu'il n'était pas nécessaire d'utiliser du matériel spécialisé pour le lancer de rayons, et qu'utiliser les GPU actuels était suffisant. En théorie, il est possible d'utiliser des ''shaders'' pour effectuer du lancer de rayons, mais la technique n'est pas très performante.
Une carte graphique spécialement dédiée au lancer de rayons est donc quasiment identique à une carte graphique normale. Les deux contiennent des unités de texture et des processeurs de ''shaders'', des unités géométriques, un ''input assembler'', et tout ce qui va avec. Seuls les circuits de rasterisation et le z-buffer sont remplacés par des circuits dédiés au lancer de rayon, à savoir des unités de génération des rayons et des unités pour les calculs d'intersection. D'ailleurs, il est aussi possible d'ajouter des circuits de génération/intersection de rayons à une carte graphique existante.
Au niveau matériel, la gestion de la mémoire est un peu plus simple. Le lancer de rayon n'écrit que dans le ''framebuffer'' et n'a pas besoin de z-buffer, ce qui a beaucoup d'avantages. Notamment, les caches sont en lecture seule, leurs circuits sont donc assez simples et performants, les problèmes de cohérence des caches disparaissent. L'absence de z-buffer fait que de nombreuses écritures/lectures dans le ''framebuffer'' sont économisées. Les lectures et écritures de textures sont tout aussi fréquentes qu'avec la rasterisation, et sont même plus faible en principe car de nombreux effets de lumières complexes sont calculés avec le lancer de rayons, alors qu'ils doivent être précalculés dans des textures et lus par les shaders.
===Les circuits spécialisés pour les calculs liés aux rayons===
Toute la subtilité du lancer de rayons est de générer les rayons et de déterminer quels triangles ils intersectent. La seule difficulté est de gérer la transparence, mais aussi et surtout la traversée de la BVH. En soit, générer les rayons et déterminer leurs intersections n'est pas compliqué. Il existe des algorithmes basés sur du calcul vectoriel pour déterminer si intersection il y a et quelles sont ses coordonnées. C'est toute la partie de parcours de la BVH qui est plus compliquée à implémenter : faire du ''pointer chasing'' en hardware n'est pas facile.
Et cela se ressent quand on étudie comment les GPU récents gèrent le lancer de rayons. Ils utilisent des shaders dédiés, qui communiquent avec une '''unité de lancer de rayon''' dédiée à la traversée de la BVH. Le terme anglais est ''Ray-tracing Unit'', ce qui fait que nous utiliseront l'abréviation RTU pour la désigner. Les shaders spécialisés sont des shaders de lancer de rayon, qui s'occupent de générer les rayons, mais aussi de faire tous les calculs une fois qu'une intersection est détectée. Le processus est le suivant :
* En premier lieu, les shaders de lancer de rayon génèrent les rayons lancés.
µ Ensuite, ils laissent la main à l'unité de lancer de rayon. Elle parcours la BVH et effectue les calculs d'intersection. C'est elle qui détermine quels triangles intersectent un rayon.
* A chaque fois que la RTU détecte une intersection, elle envoie son résultat au ''shader'' de lancer de rayon, qui reprend la main et finit le travail.
Il est possible de tester un grand nombre d'intersections de triangles en parallèles, chacun dans une unité de calcul séparée. L'algorithme de lancer de rayons se parallélise donc très bien. En soi, les circuits de détection des intersections sont très simples et se résument à un paquet de circuits de calcul (addition, multiplications, division, autres), connectés les uns aux autres. Il y a assez peu à dire dessus. Mais les autres circuits sont très intéressants à étudier.
====La génération et le tri des rayons primaire/secondaire/d'ombrage====
La génération des rayons n'est pas une étape qui demande beaucoup de puissance de calcul, et elle peut être faite par un processeur de ''shaders'' sans problèmes. Pour du rendu en ''raycasting'', il y a juste à générer les rayons primaires, rien de plus. Et la génération des rayons primaires peut être faite par une unité spécialisée, même si ce n'est pas le cas sur les cartes 3D modernes. La génération des rayons d'ombrage et des rayons secondaires est par contre plus complexe.
Les rayons d'ombrage et secondaires sont générés à partir du résultat des intersections des rayons précédents. Et dans les faits, ce sont les ''shaders'' qui s'occupent de générer les rayons secondaires. Suivant la nature de la surface (opaque, transparente, réfléchissante, mate, autre), ils décident s'il faut ou non émettre un rayon secondaire, et génère ce rayon s'il le faut. Le rayon est alors envoyé aux unités de traversée et d'intersection.
Les cartes graphiques modernes incorporent des circuits de tri pour regrouper les rayons cohérents, ceux qui vont dans la même direction et proviennent de triangles proches. Ce afin d'implémenter les optimisations vues plus haut.
====La traversée des structures d'accélérations et des BVH====
Les cartes graphiques modernes incorporent des circuits pour accélérer les accès mémoire aux BVH. Ces circuits se trouvent vraisemblablement dans les unités de texture, si on en croit quelques brevets déposés par les fabricants de carte graphiques, ce qui est logique vu qu'il s'agit d'un des seuls endroits où la carte graphique gère des accès mémoire une fois la géométrie rendue. Et ces unités effectuent un travail essentiel. Car si le calcul des intersections est une chose facile pour la carte graphique, la gestion des structures d'accélération ne l'est pas du tout. Et ce pour plusieurs raisons.
Déjà, les BVH se marient assez mal avec les mémoires caches et la hiérarchie mémoire. Ce sont des structures de données qui dispersent les données en mémoire, dans le sens où chaque volume englobant est située dans sa propre portion de mémoire et celles-ci ne sont pas collées les unes aux autres en mémoire RAM. A l'inverse, les autres structures de données utilisées par la carte graphique, comme les tampons de sommets ou d'indice, les textures, sont des tableaux, des structures de données compactes qui forment un seul bloc en RAM. Traverser un BVH demande de faire des sauts en mémoire RAM, et ce sont des accès mémoire imprévisibles que l'on ne peut pas optimiser, pour lesquels les caches sont inopérants.
L'autre raison, très liée à la précédente, est que traverser un BVH pour trouver le triangle intersectant demande d'effectuer beaucoup de branchements. On doit tester l'intersection avec un volume englobant, puis décider s'il faut passer au suivant, et si oui lequel, et rebelotte. Et dans du code informatique, cela demande beaucoup de IF...ELSE, de branchements, de tests de conditions, etc. Et les cartes graphiques sont assez mauvaises à ça. Les ''shaders'' peuvent en faire, mais sont très lents pour ces opérations.
====La génération des structures d'accélération et BVH====
La plupart des cartes graphiques ne peuvent pas générer les BVH d'elles-mêmes. Pareil pour les autres structures d'accélération. Elles sont calculées par le processeur, stockées en mémoire RAM, puis copiées dans la mémoire vidéo avant le démarrage du rendu 3D. Cependant, quelques rares cartes spécialement dédiées au lancer de rayons incorporent des circuits pour générer les BVH/AS. Elles lisent le tampon de sommet envoyé par le processeur, puis génèrent les BVH complémentaires. L'unité de génération des structures d'accélération est complétement séparée des autres unités. Un exemple d'architecture de ce type est l'architecture Raycore, dont nous parlerons dans les sections suivantes.
Cette unité peut aussi modifier les BVH à la volée, si jamais la scène 3D change. Par exemple, si un objet change de place, comme un NPC qui se déplace, il faut reconstruire le BVH. Les cartes graphiques récentes évitent de reconstruire le BVH de zéro, mais se contentent de modifier ce qui a changé dans le BVH. Les performances en sont nettement meilleures.
===Les cartes graphiques dédiées au lancer de rayon===
Les premières cartes accélératrices de lancer de rayons sont assez anciennes et datent des années 80-90. Leur évolution a plus ou moins suivi la même évolution que celle des cartes graphiques usuelles, sauf que très peu de cartes pour le lancer de rayons ont été produites. Par même évolution, on veut dire que les cartes graphiques pour le lancer de rayon ont commencé par tester deux solutions évidentes et extrêmes : les cartes basées sur des circuits programmables d'un côté, non programmables de l'autre.
La première carte pour le lancer de rayons était la TigerShark, et elle était tout simplement composée de plusieurs processeurs et de la mémoire sur une carte PCI. Elle ne faisait qu'accélérer le calcul des intersections, rien de plus.
Les autres cartes effectuaient du rendu 3D par voxel, un type de rendu 3D assez spécial que nous n'avons pas abordé jusqu'à présent, dont l'algorithme de lancer de rayons n'était qu'une petite partie du rendu. Elles étaient destinées au marché scientifique, industriel et médical. On peut notamment citer la VolumePro et la VIZARD et II. Les deux étaient des cartes pour bus PCI qui ne faisaient que du ''raycasting'' et n'utilisaient pas de rayons d'ombrage. Le ''raycasting'' était exécuté sur un processeur dédié sur la VIZARD II, sur un circuit fixe implémenté par un FPGA sur la Volume Pro Voici différents papiers académiques qui décrivent l'architecture de ces cartes accélératrices :
* [https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=ccda3712ba0e6575cd08025f3bb920de46201cac The VolumePro Real-Time Ray-Casting System].
* [https://www.researchgate.net/publication/234829060_VIZARD_II_A_reconfigurable_interactive_volume_rendering_system VIZARD II: A reconfigurable interactive volume rendering system]
La puce SaarCOR (Saarbrücken's Coherence Optimized Ray Tracer) et bien plus tard par la carte Raycore, étaient deux cartes réelement dédiées au raycasting pur, sans usage de voxels, et étaient basées sur des FPGA. Elles contenaient uniquement des circuits pour accélérer le lancer de rayon proprement dit, à savoir la génération des rayons, les calculs d'intersection, pas plus. Tout le reste, à savoir le rendu de la géométrie, le placage de textures, les ''shaders'' et autres, étaient effectués par le processeur. Voici des papiers académiques sur leur architecture :
* [https://gamma.cs.unc.edu/SATO/Raycore/raycore.pdf RayCore: A ray-tracing hardware architecture for mobile devices].
Le successeur de la SaarCOR, le Ray Processing Unit (RPU), était une carte hybride : c'était une SaarCOR basée sur des circuits fixes, qui gagna quelques possibilités de programmation. Elle ajoutait des processeurs de ''shaders'' aux circuits fixes spécialisés pour le lancer de rayons. Les autres cartes du genre faisaient pareil, et on peut citer les cartes ART, les cartes CausticOne, Caustic Professional's R2500 et R2100.
Les cartes 3D modernes permettent de faire à la fois de la rasterisation et du lancer de rayons. Pour cela, les GPU récents incorporent des unités pour effectuer des calculs d'intersection, qui sont réalisés dans des circuits spécialisés. Elles sont appelées des RT Cores sur les cartes NVIDIA, mais les cartes AMD et Intel ont leur équivalent, idem chez leurs concurrents de chez Imagination technologies, ainsi que sur certains GPU destinés au marché mobile. Peu de choses sont certaines sur ces unités, mais il semblerait qu'il s'agisse d'unités de textures modifiées.
De ce qu'on en sait, certains GPU utilisent des unités pour calculer les intersections avec les triangles, et d'autres unités séparées pour calculer les intersections avec les volumes englobants. La raison est que, comme dit plus haut, les algorithmes de calcul d'intersection sont différents dans les deux cas. Les algorithmes utilisés ne sont pas connus pour toutes les cartes graphiques. On sait que les GPU Wizard de Imagination technology utilisaient des tests AABB de Plücker. Ils utilisaient 15 circuits de multiplication, 9 additionneurs-soustracteurs, quelques circuits pour tester la présence dans un intervalle, des circuits de normalisation et arrondi. L'algorithme pour leurs GPU d'architecture Photon est disponible ici, pour les curieux : [https://www.highperformancegraphics.org/slides23/2023-06-_HPG_IMG_RayTracing_2.pdf].
{{NavChapitre | book=Les cartes graphiques
| prev=Le multi-GPU
| prevText=Le multi-GPU
}}{{autocat}}
avz3roi66wr7yhlnp6hfspa9llrxxx5
744328
744327
2025-06-08T16:44:33Z
Mewtow
31375
/* Les circuits spécialisés pour les calculs liés aux rayons */
744328
wikitext
text/x-wiki
Les cartes graphiques actuelles utilisent la technique de la rastérisation, qui a été décrite en détail dans le chapitre sur les cartes accélératrices 3D. Mais nous avions dit qu'il existe une seconde technique générale pour le rendu 3D, totalement opposée à la rastérisation, appelée le '''lancer de rayons'''. Cette technique a cependant été peu utilisée dans les jeux vidéo, jusqu'à récemment. La raison est que le lancer de rayons demande beaucoup de puissance de calcul, sans compter que créer des cartes accélératrices pour le lancer de rayons n'est pas simple.
Mais les choses commencent à changer. Quelques jeux vidéos récents intègrent des techniques de lancer rayons, pour compléter un rendu effectué principalement en rastérisation. De plus, les cartes graphiques modernes incorporent quelques circuits pour accélérer le lancer de rayons, même s'ils restent marginaux des compléments au rendu par rastérisation. S'il a existé des cartes accélératrices totalement dédiées au rendu en lancer de rayons, elles sont restées confidentielles. Aussi, nous allons nous concentrer sur les cartes graphiques récentes, et allons peu parler des cartes accélératrices dédiées au lancer de rayons.
==Le lancer de rayons==
Le lancer de rayons et la rastérisation. commencent par générer la géométrie de la scène 3D, en plaçant les objets dans la scène 3D, et en effectuant l'étape de transformation des modèles 3D, et les étapes de transformation suivante. Mais les ressemblances s'arrêtent là. Le lancer de rayons effectue l'étape d'éclairage différemment, sans compter qu'il n'a pas besoin de rastérisation.
===Le ''ray-casting'' : des rayons tirés depuis la caméra===
La forme la plus simple de lancer de rayon s'appelle le '''''ray-casting'''''. Elle émet des lignes droites, des '''rayons''' qui partent de la caméra et qui passent chacun par un pixel de l'écran. Les rayons font alors intersecter les différents objets présents dans la scène 3D, en un point d'intersection. Le moteur du jeu détermine alors quel est le point d'intersection le plus proche, ou plus précisément, le sommet le plus proche de ce point d'intersection. Ce sommet est associé à une coordonnée de textures, ce qui permet d'associer directement un texel au pixel associé au rayon.
[[File:Raytrace trace diagram.png|centre|vignette|upright=2|Raycasting, rayon simple.]]
En somme, l'étape de lancer de rayon et le calcul des intersections remplacent l'étape de rasterisation, mais les étapes de traitement de la géométrie et des textures existent encore. Après tout, il faut bien placer les objets dans la scène 3D/2D, faire diverses transformations, les éclairer. On peut gérer la transparence des textures assez simplement, si on connait la transparence sur chaque point d'intersection d'un rayon, information présente dans les textures.
[[File:Anarch short gameplay.gif|vignette|Exemple de rendu en ray-casting 2D dans un jeu vidéo.]]
En soi, cet algorithme est simple, mais il a déjà été utilisé dans pas mal de jeux vidéos. Mais sous une forme simple, en deux dimensions ! Les premiers jeux IdSoftware, dont Wolfenstein 3D et Catacomb, utilisaient cette méthode de rendu, mais dans un univers en deux dimensions. Cet article explique bien cela : [[Les moteurs de rendu des FPS en 2.5 D\Le moteur de Wolfenstein 3D|Le moteur de rendu de Wolfenstein 3D]]. Au passage, si vous faites des recherches sur le ''raycasting'', vous verrez que le terme est souvent utilisé pour désigner la méthode de rendu de ces vieux FPS, alors que ce n'en est qu'un cas particulier.
[[File:Simple raycasting with fisheye correction.gif|centre|vignette|upright=2|Simple raycasting with fisheye correction]]
===Le ''raytracing'' proprement dit===
Le lancer de rayon proprement dit est une forme améliorée de ''raycasting'' dans la gestion de l'éclairage et des ombres est modifiée. Le lancer de rayon calcule les ombres assez simplement, sans recourir à des algorithmes compliqués. L'idée est qu'un point d'intersection est dans l'ombre si un objet se trouve entre lui et une source de lumière. Pour déterminer cela, il suffit de tirer un trait entre les deux et de vérifier s'il y a un obstacle/objet sur le trajet. Si c'est le cas, le point d'intersection n'est pas éclairé par la source de lumière et est donc dans l'ombre. Si ce n'est pas le cas, il est éclairé avec un algorithme d'éclairage.
Le trait tiré entre la source de lumière et le point d'intersection est en soi facile : c'est rayon, identique aux rayons envoyés depuis la caméra. La différence est que ces rayons servent à calculer les ombres, ils sont utilisés pour une raison différente. Il faut donc faire la différence entre les '''rayons primaires''' qui partent de la caméra et passent par un pixel de l'écran, et les '''rayon d'ombrage''' qui servent pour le calcul des ombres.
[[File:Ray trace diagram.svg|centre|vignette|upright=2|Principe du lancer de rayons.]]
Les calculs d'éclairage utilisés pour éclairer/ombrer les points d'intersection vous sont déjà connus : la luminosité est calculée à partir de l'algorithme d'éclairage de Phong, vu dans le chapitre "L'éclairage d'une scène 3D : shaders et T&L". Pour cela, il faut juste récupérer la normale du sommet associé au point d'intersection et l'intensité de la source de lumière, et de calculer les informations manquantes (l'angle normale-rayons de lumière, autres). Il détermine alors la couleur de chaque point d'intersection à partir de tout un tas d'informations.
===Le ''raytracing'' récursif===
[[File:Glasses 800 edit.png|vignette|Image rendue avec le lancer de rayons récursif.]]
La technique de lancer de rayons précédente ne gère pas les réflexions, les reflets, des miroirs, les effets de spécularité, et quelques autres effets graphiques de ce style. Pourtant, ils peuvent être implémentés facilement en modifiant le ''raycasting'' d'une manière très simple.
Il suffit de relancer des rayons à partir du point d'intersection. La direction de ces '''rayons secondaires''' est calculée en utilisant les lois de la réfraction/réflexion vues en physique. De plus, les rayons secondaires peuvent eux-aussi créer des rayons secondaires quand ils sont reflétés/réfractés, etc. La technique est alors appelée du ''lancer de rayons récursif'', qui est souvent simplement appelée "lancer de rayons".
[[File:Recursive raytracing.svg|centre|vignette|upright=2|Lancer de rayon récursif.]]
===Les avantages et désavantages comparé à la rastérisation===
L'avantage principal du lancer de rayons est son rendu de l'éclairage, qui est plus réaliste. Les ombres se calculent naturellement avec cette méthode de rendu, là où elles demandent des ruses comme des lightmaps, des textures pré-éclairées, divers algorithmes d'éclairage géométriques, etc. Les réflexions et la réfraction sont gérées naturellement par le lancer de rayon récursif, alors qu'elles demandent des ruses de sioux pour obtenir un résultat correct avec la rastérisation.
[[File:ViewFrustum.svg|vignette|upright=1|Volume délimité par la caméra (''view frustum'').]]
Pour ce qui est des performances théoriques, le lancer de rayons se débrouille mieux sur un point : l'élimination des pixels/surfaces cachés. La rastérisation a tendance à calculer inutilement des portions non-rendues de la scène 3D, et doit utiliser des techniques de ''culling'' ou de ''clipping'' pour éviter trop de calculs inutiles. Ces techniques sont très puissantes, mais imparfaites. De nombreux fragments/pixels calculés sont éliminés à la toute fin du pipeline, grâce au z-buffer, après avoir été calculés et texturés. Le lancer de rayons se passe totalement de ces techniques d'élimination des pixels cachés, car elle ne calcule pas les portions invisibles de l'image par construction : pas besoin de ''culling'', de ''clipping'', ni même de z-buffer.
Mais tous ces avantages sont compensés par le fait que le lancer de rayons est plus lent sur un paquet d'autres points. Déjà, les calculs d'intersection sont très lourds, ils demandent beaucoup de calculs et d'opérations arithmétiques, plus que pour l'équivalent en rastérisation. Ensuite, de nombreuses optimisations présentes en rastérisation ne sont pas possibles. Notamment, le lancer de rayon utilise assez mal la mémoire, dans le sens où les accès en mémoire vidéo sont complétement désorganisés, là où le rendu 3D a des accès plus linéaires qui permettent d'utiliser des mémoires caches.
==Les optimisations du lancer de rayons liées aux volumes englobants==
Les calculs d'intersections sont très gourmands en puissance de calcul. Sans optimisation, on doit tester l'intersection de chaque rayon avec chaque triangle. Mais diverses optimisations permettent d'économiser des calculs. Elles consistent à regrouper plusieurs triangles ensemble pour rejeter des paquets de triangles en une fois. Pour cela, la carte graphique utilise des '''structures d'accélération''', qui mémorisent les regroupements de triangles, et parfois les triangles eux-mêmes.
===Les volumes englobants===
[[File:BoundingBox.jpg|vignette|Objet englobant : la statue est englobée dans un pavé.]]
L'idée est d'englober chaque objet par un pavé appelé un ''volume englobant''. Le tout est illustré ci-contre, avec une statue représentée en 3D. La statue est un objet très complexe, contenant plusieurs centaines ou milliers de triangles, ce qui fait que tester l'intersection d'un rayon avec chaque triangle serait très long. Par contre, on peut tester si le rayon intersecte le volume englobant facilement : il suffit de tester les 6 faces du pavé, soit 12 triangles, pas plus. S'il n'y a pas d'intersection, alors on économise plusieurs centaines ou milliers de tests d'intersection. Par contre, s'il y a intersection, on doit vérifier chaque triangle. Vu que les rayons intersectent souvent peu d'objets, le gain est énorme !
L'usage seul de volumes englobant est une optimisation très performante. Au lieu de tester l'intersection avec chaque triangle, on teste l'intersection avec chaque objet, puis l'intersection avec chaque triangle quand on intersecte chaque volume englobant. On divise le nombre de tests par un facteur quasi-constant, mais de très grande valeur.
Il faut noter que les calculs d'intersection sont légèrement différents entre un triangle et un volume englobant. Il faut dire que les volumes englobant sont généralement des pavées, ils utilisent des rectangles, etc. Les différences sont cependant minimales.
===Les hiérarchies de volumes englobants===
Mais on peut faire encore mieux. L'idée est de regrouper plusieurs volumes englobants en un seul. Si une dizaine d'objets sont proches, leurs volumes englobants seront proches. Il est alors utile d'englober leurs volumes englobants dans un super-volume englobant. L'idée est que l'on teste d'abord le super-volume englobant, au lieu de tester la dizaine de volumes englobants de base. S'il n'y a pas d'intersection, alors on a économisé une dizaine de tests. Mais si intersection, il y a, alors on doit vérifier chaque sous-volume englobant de base, jusqu'à tomber sur une intersection. Vu que les intersections sont rares, on y gagne plus qu'on y perd.
Et on peut faire la même chose avec les super-volumes englobants, en les englobant dans des volumes englobants encore plus grands, et ainsi de suite, récursivement. On obtient alors une '''hiérarchie de volumes englobants''', qui part d'un volume englobant qui contient toute la géométrie, hors skybox, qui lui-même regroupe plusieurs volumes englobants, qui eux-mêmes...
[[File:Example of bounding volume hierarchy.svg|centre|vignette|upright=2|Hiérarchie de volumes englobants.]]
Le nombre de tests d'intersection est alors grandement réduit. On passe d'un nombre de tests proportionnel aux nombres d'objets à un nombre proportionnel à son logarithme. Plus la scène contient d'objets, plus l'économie est importante. La seule difficulté est de générer la hiérarchie de volumes englobants à partir d'une scène 3D. Divers algorithmes assez rapides existent pour cela, ils créent des volumes englobants différents. Les volumes englobants les plus utilisés dans les cartes 3D sont les '''''axis-aligned bounding boxes (AABB)'''''.
La hiérarchie est mémorisée en mémoire RAM, dans une structure de données que les programmeurs connaissent sous le nom d'arbre, et précisément un arbre binaire ou du moins d'un arbre similaire (''k-tree''). Traverser cet arbre pour passer d'un objet englobant à un autre plus petit est très simple, mais a un défaut : on saute d'on objet à un autre en mémoire, les deux sont souvent éloignés en mémoire. La traversée de la mémoire est erratique, sautant d'un point à un autre. On n'est donc dans un cas où les caches fonctionnent mal, ou les techniques de préchargement échouent, où la mémoire devient un point bloquant car trop lente.
===La cohérence des rayons===
Les rayons primaires, émis depuis la caméra, sont proches les uns des autres, et vont tous dans le même sens. Mais ce n'est pas le cas pour des rayons secondaires. Les objets d'une scène 3D ont rarement des surfaces planes, mais sont composés d'un tas de triangles qui font un angle entre eux. La conséquence est que deux rayons secondaires émis depuis deux triangles voisins peuvent aller dans des directions très différentes. Ils vont donc intersecter des objets très différents, atterrir sur des sources de lumières différentes, etc. De tels rayons sont dits '''incohérents''', en opposition aux rayons cohérents qui sont des rayons proches qui vont dans la même direction.
Les rayons incohérents sont peu fréquents avec le ''rayctracing'' récursif basique, mais deviennent plus courants avec des techniques avancées comme le ''path tracing'' ou les techniques d'illumination globale. En soi, la présende de rayons incohérents n'est pas un problème et est parfaitement normale. Le problème est que le traitement des rayons incohérent est plus lent que pour les rayons cohérents. Le traitement de deux rayons secondaires voisins demande d'accéder à des données différentes, ce qui donne des accès mémoire très différents et très éloignés. On ne peut pas profiter des mémoires caches ou des optimisations de la hiérarchie mémoire, si on les traite consécutivement. Un autre défaut est qu'une même instance de ''pixels shaders'' va traiter plusieurs rayons en même temps, grâce au SIMD. Mais les branchements n'auront pas les mêmes résultats d'un rayon à l'autre, et cette divergence entrainera des opérations de masquage et de branchement très couteuses.
Pour éviter cela, les GPU modernes permettent de trier les rayons en fonction de leur direction et de leur origine. Ils traitent les rayons non dans l'ordre usuel, mais essayent de regrouper des rayons proches qui vont dans la même direction, et de les traiter ensemble, en parallèle, ou l'un après l'autre. Cela ne change rien au rendu final, qui traite les rayons en parallèle. Ainsi, les données chargées dans le cache par le premier rayon seront celles utilisées pour les rayons suivants, ce qui donne un gain de performance appréciable. De plus, cela évite d'utiliser des branchements dans les ''pixels shaders''. Les méthodes de '''tri de rayons''' sont nombreuses, aussi en faire une liste exhaustive serait assez long, sans compter qu'on ne sait pas quelles sont celles implémentées en hardware, ni commetn elles le sont.
==Le matériel pour accélérer le lancer de rayons==
Le lancer de rayons a toujours besoin de calculer la géométrie, d'appliquer des textures et de faire des calculs d'éclairage. Sachant cela, beaucoup de chercheurs se sont dit qu'il n'était pas nécessaire d'utiliser du matériel spécialisé pour le lancer de rayons, et qu'utiliser les GPU actuels était suffisant. En théorie, il est possible d'utiliser des ''shaders'' pour effectuer du lancer de rayons, mais la technique n'est pas très performante.
Une carte graphique spécialement dédiée au lancer de rayons est donc quasiment identique à une carte graphique normale. Les deux contiennent des unités de texture et des processeurs de ''shaders'', des unités géométriques, un ''input assembler'', et tout ce qui va avec. Seuls les circuits de rasterisation et le z-buffer sont remplacés par des circuits dédiés au lancer de rayon, à savoir des unités de génération des rayons et des unités pour les calculs d'intersection. D'ailleurs, il est aussi possible d'ajouter des circuits de génération/intersection de rayons à une carte graphique existante.
Au niveau matériel, la gestion de la mémoire est un peu plus simple. Le lancer de rayon n'écrit que dans le ''framebuffer'' et n'a pas besoin de z-buffer, ce qui a beaucoup d'avantages. Notamment, les caches sont en lecture seule, leurs circuits sont donc assez simples et performants, les problèmes de cohérence des caches disparaissent. L'absence de z-buffer fait que de nombreuses écritures/lectures dans le ''framebuffer'' sont économisées. Les lectures et écritures de textures sont tout aussi fréquentes qu'avec la rasterisation, et sont même plus faible en principe car de nombreux effets de lumières complexes sont calculés avec le lancer de rayons, alors qu'ils doivent être précalculés dans des textures et lus par les shaders.
===Les circuits spécialisés pour les calculs liés aux rayons===
Toute la subtilité du lancer de rayons est de générer les rayons et de déterminer quels triangles ils intersectent. La seule difficulté est de gérer la transparence, mais aussi et surtout la traversée de la BVH. En soit, générer les rayons et déterminer leurs intersections n'est pas compliqué. Il existe des algorithmes basés sur du calcul vectoriel pour déterminer si intersection il y a et quelles sont ses coordonnées. C'est toute la partie de parcours de la BVH qui est plus compliquée à implémenter : faire du ''pointer chasing'' en hardware n'est pas facile.
Et cela se ressent quand on étudie comment les GPU récents gèrent le lancer de rayons. Ils utilisent des shaders dédiés, qui communiquent avec une '''unité de lancer de rayon''' dédiée à la traversée de la BVH. Le terme anglais est ''Ray-tracing Unit'', ce qui fait que nous utiliseront l'abréviation RTU pour la désigner. Les shaders spécialisés sont des shaders de lancer de rayon, qui s'occupent de générer les rayons, mais aussi de faire tous les calculs une fois qu'une intersection est détectée. Le processus est le suivant :
* En premier lieu, les shaders de lancer de rayon génèrent les rayons lancés.
* Ensuite, ils laissent la main à l'unité de lancer de rayon. Elle parcours la BVH et effectue les calculs d'intersection. C'est elle qui détermine quels triangles intersectent un rayon.
* A chaque fois que la RTU détecte une intersection, elle envoie son résultat au ''shader'' de lancer de rayon, qui reprend la main et finit le travail. Lors de cette étape, il peut générer un nouveau rayon, et le processus recommence.
La génération des rayons a donc lieu dans les processeur de ''shaders'', avec cependant une petite subtilité quant aux rayons secondaires. La génération des rayons primaires est triviale, mais la génération des rayons d'ombrage et des rayons secondaires est par contre plus complexe. Les rayons d'ombrage et secondaires sont générés à partir du résultat des intersections des rayons précédents. Et dans les faits, ce sont les ''shaders'' qui s'occupent de générer les rayons secondaires. Suivant la nature de la surface (opaque, transparente, réfléchissante, mate, autre), ils décident s'il faut ou non émettre un rayon secondaire, et génère ce rayon s'il le faut. Le rayon est alors envoyé aux unités de traversée et d'intersection.
Les cartes graphiques modernes incorporent des circuits de tri pour regrouper les rayons cohérents, ceux qui vont dans la même direction et proviennent de triangles proches. Ce afin d'implémenter les optimisations vues plus haut.
====La traversée des structures d'accélérations et des BVH====
L'intérieur de la RTU contient de quoi séquencer les accès mémoire nécessaires pour parcourir la BVH. Mais elle contient aussi beaucoup d'unités de calcul pour effectuer les calculs d'intersections. Il est possible de tester un grand nombre d'intersections de triangles en parallèles, chacun dans une unité de calcul séparée. L'algorithme de lancer de rayons se parallélise donc très bien et la RTU en profite. En soi, les circuits de détection des intersections sont très simples et se résument à un paquet de circuits de calcul (addition, multiplications, division, autres), connectés les uns aux autres. Il y a assez peu à dire dessus. Mais les autres circuits sont très intéressants à étudier.
Les cartes graphiques modernes incorporent des circuits pour accélérer les accès mémoire aux BVH. Ces circuits se trouvent vraisemblablement dans les unités de texture, si on en croit quelques brevets déposés par les fabricants de carte graphiques, ce qui est logique vu qu'il s'agit d'un des seuls endroits où la carte graphique gère des accès mémoire une fois la géométrie rendue. Et ces unités effectuent un travail essentiel. Car si le calcul des intersections est une chose facile pour la carte graphique, la gestion des structures d'accélération ne l'est pas du tout. Et ce pour plusieurs raisons.
Déjà, les BVH se marient assez mal avec les mémoires caches et la hiérarchie mémoire. Ce sont des structures de données qui dispersent les données en mémoire, dans le sens où chaque volume englobant est située dans sa propre portion de mémoire et celles-ci ne sont pas collées les unes aux autres en mémoire RAM. A l'inverse, les autres structures de données utilisées par la carte graphique, comme les tampons de sommets ou d'indice, les textures, sont des tableaux, des structures de données compactes qui forment un seul bloc en RAM. Traverser un BVH demande de faire des sauts en mémoire RAM, et ce sont des accès mémoire imprévisibles que l'on ne peut pas optimiser, pour lesquels les caches sont inopérants.
L'autre raison, très liée à la précédente, est que traverser un BVH pour trouver le triangle intersectant demande d'effectuer beaucoup de branchements. On doit tester l'intersection avec un volume englobant, puis décider s'il faut passer au suivant, et si oui lequel, et rebelotte. Et dans du code informatique, cela demande beaucoup de IF...ELSE, de branchements, de tests de conditions, etc. Et les cartes graphiques sont assez mauvaises à ça. Les ''shaders'' peuvent en faire, mais sont très lents pour ces opérations.
====La génération des structures d'accélération et BVH====
La plupart des cartes graphiques ne peuvent pas générer les BVH d'elles-mêmes. Pareil pour les autres structures d'accélération. Elles sont calculées par le processeur, stockées en mémoire RAM, puis copiées dans la mémoire vidéo avant le démarrage du rendu 3D. Cependant, quelques rares cartes spécialement dédiées au lancer de rayons incorporent des circuits pour générer les BVH/AS. Elles lisent le tampon de sommet envoyé par le processeur, puis génèrent les BVH complémentaires. L'unité de génération des structures d'accélération est complétement séparée des autres unités. Un exemple d'architecture de ce type est l'architecture Raycore, dont nous parlerons dans les sections suivantes.
Cette unité peut aussi modifier les BVH à la volée, si jamais la scène 3D change. Par exemple, si un objet change de place, comme un NPC qui se déplace, il faut reconstruire le BVH. Les cartes graphiques récentes évitent de reconstruire le BVH de zéro, mais se contentent de modifier ce qui a changé dans le BVH. Les performances en sont nettement meilleures.
===Les cartes graphiques dédiées au lancer de rayon===
Les premières cartes accélératrices de lancer de rayons sont assez anciennes et datent des années 80-90. Leur évolution a plus ou moins suivi la même évolution que celle des cartes graphiques usuelles, sauf que très peu de cartes pour le lancer de rayons ont été produites. Par même évolution, on veut dire que les cartes graphiques pour le lancer de rayon ont commencé par tester deux solutions évidentes et extrêmes : les cartes basées sur des circuits programmables d'un côté, non programmables de l'autre.
La première carte pour le lancer de rayons était la TigerShark, et elle était tout simplement composée de plusieurs processeurs et de la mémoire sur une carte PCI. Elle ne faisait qu'accélérer le calcul des intersections, rien de plus.
Les autres cartes effectuaient du rendu 3D par voxel, un type de rendu 3D assez spécial que nous n'avons pas abordé jusqu'à présent, dont l'algorithme de lancer de rayons n'était qu'une petite partie du rendu. Elles étaient destinées au marché scientifique, industriel et médical. On peut notamment citer la VolumePro et la VIZARD et II. Les deux étaient des cartes pour bus PCI qui ne faisaient que du ''raycasting'' et n'utilisaient pas de rayons d'ombrage. Le ''raycasting'' était exécuté sur un processeur dédié sur la VIZARD II, sur un circuit fixe implémenté par un FPGA sur la Volume Pro Voici différents papiers académiques qui décrivent l'architecture de ces cartes accélératrices :
* [https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=ccda3712ba0e6575cd08025f3bb920de46201cac The VolumePro Real-Time Ray-Casting System].
* [https://www.researchgate.net/publication/234829060_VIZARD_II_A_reconfigurable_interactive_volume_rendering_system VIZARD II: A reconfigurable interactive volume rendering system]
La puce SaarCOR (Saarbrücken's Coherence Optimized Ray Tracer) et bien plus tard par la carte Raycore, étaient deux cartes réelement dédiées au raycasting pur, sans usage de voxels, et étaient basées sur des FPGA. Elles contenaient uniquement des circuits pour accélérer le lancer de rayon proprement dit, à savoir la génération des rayons, les calculs d'intersection, pas plus. Tout le reste, à savoir le rendu de la géométrie, le placage de textures, les ''shaders'' et autres, étaient effectués par le processeur. Voici des papiers académiques sur leur architecture :
* [https://gamma.cs.unc.edu/SATO/Raycore/raycore.pdf RayCore: A ray-tracing hardware architecture for mobile devices].
Le successeur de la SaarCOR, le Ray Processing Unit (RPU), était une carte hybride : c'était une SaarCOR basée sur des circuits fixes, qui gagna quelques possibilités de programmation. Elle ajoutait des processeurs de ''shaders'' aux circuits fixes spécialisés pour le lancer de rayons. Les autres cartes du genre faisaient pareil, et on peut citer les cartes ART, les cartes CausticOne, Caustic Professional's R2500 et R2100.
Les cartes 3D modernes permettent de faire à la fois de la rasterisation et du lancer de rayons. Pour cela, les GPU récents incorporent des unités pour effectuer des calculs d'intersection, qui sont réalisés dans des circuits spécialisés. Elles sont appelées des RT Cores sur les cartes NVIDIA, mais les cartes AMD et Intel ont leur équivalent, idem chez leurs concurrents de chez Imagination technologies, ainsi que sur certains GPU destinés au marché mobile. Peu de choses sont certaines sur ces unités, mais il semblerait qu'il s'agisse d'unités de textures modifiées.
De ce qu'on en sait, certains GPU utilisent des unités pour calculer les intersections avec les triangles, et d'autres unités séparées pour calculer les intersections avec les volumes englobants. La raison est que, comme dit plus haut, les algorithmes de calcul d'intersection sont différents dans les deux cas. Les algorithmes utilisés ne sont pas connus pour toutes les cartes graphiques. On sait que les GPU Wizard de Imagination technology utilisaient des tests AABB de Plücker. Ils utilisaient 15 circuits de multiplication, 9 additionneurs-soustracteurs, quelques circuits pour tester la présence dans un intervalle, des circuits de normalisation et arrondi. L'algorithme pour leurs GPU d'architecture Photon est disponible ici, pour les curieux : [https://www.highperformancegraphics.org/slides23/2023-06-_HPG_IMG_RayTracing_2.pdf].
{{NavChapitre | book=Les cartes graphiques
| prev=Le multi-GPU
| prevText=Le multi-GPU
}}{{autocat}}
eim8in5x1ayoqit3gzz5oa7dwsv6gov
744329
744328
2025-06-08T16:52:03Z
Mewtow
31375
/* Les circuits spécialisés pour les calculs liés aux rayons */
744329
wikitext
text/x-wiki
Les cartes graphiques actuelles utilisent la technique de la rastérisation, qui a été décrite en détail dans le chapitre sur les cartes accélératrices 3D. Mais nous avions dit qu'il existe une seconde technique générale pour le rendu 3D, totalement opposée à la rastérisation, appelée le '''lancer de rayons'''. Cette technique a cependant été peu utilisée dans les jeux vidéo, jusqu'à récemment. La raison est que le lancer de rayons demande beaucoup de puissance de calcul, sans compter que créer des cartes accélératrices pour le lancer de rayons n'est pas simple.
Mais les choses commencent à changer. Quelques jeux vidéos récents intègrent des techniques de lancer rayons, pour compléter un rendu effectué principalement en rastérisation. De plus, les cartes graphiques modernes incorporent quelques circuits pour accélérer le lancer de rayons, même s'ils restent marginaux des compléments au rendu par rastérisation. S'il a existé des cartes accélératrices totalement dédiées au rendu en lancer de rayons, elles sont restées confidentielles. Aussi, nous allons nous concentrer sur les cartes graphiques récentes, et allons peu parler des cartes accélératrices dédiées au lancer de rayons.
==Le lancer de rayons==
Le lancer de rayons et la rastérisation. commencent par générer la géométrie de la scène 3D, en plaçant les objets dans la scène 3D, et en effectuant l'étape de transformation des modèles 3D, et les étapes de transformation suivante. Mais les ressemblances s'arrêtent là. Le lancer de rayons effectue l'étape d'éclairage différemment, sans compter qu'il n'a pas besoin de rastérisation.
===Le ''ray-casting'' : des rayons tirés depuis la caméra===
La forme la plus simple de lancer de rayon s'appelle le '''''ray-casting'''''. Elle émet des lignes droites, des '''rayons''' qui partent de la caméra et qui passent chacun par un pixel de l'écran. Les rayons font alors intersecter les différents objets présents dans la scène 3D, en un point d'intersection. Le moteur du jeu détermine alors quel est le point d'intersection le plus proche, ou plus précisément, le sommet le plus proche de ce point d'intersection. Ce sommet est associé à une coordonnée de textures, ce qui permet d'associer directement un texel au pixel associé au rayon.
[[File:Raytrace trace diagram.png|centre|vignette|upright=2|Raycasting, rayon simple.]]
En somme, l'étape de lancer de rayon et le calcul des intersections remplacent l'étape de rasterisation, mais les étapes de traitement de la géométrie et des textures existent encore. Après tout, il faut bien placer les objets dans la scène 3D/2D, faire diverses transformations, les éclairer. On peut gérer la transparence des textures assez simplement, si on connait la transparence sur chaque point d'intersection d'un rayon, information présente dans les textures.
[[File:Anarch short gameplay.gif|vignette|Exemple de rendu en ray-casting 2D dans un jeu vidéo.]]
En soi, cet algorithme est simple, mais il a déjà été utilisé dans pas mal de jeux vidéos. Mais sous une forme simple, en deux dimensions ! Les premiers jeux IdSoftware, dont Wolfenstein 3D et Catacomb, utilisaient cette méthode de rendu, mais dans un univers en deux dimensions. Cet article explique bien cela : [[Les moteurs de rendu des FPS en 2.5 D\Le moteur de Wolfenstein 3D|Le moteur de rendu de Wolfenstein 3D]]. Au passage, si vous faites des recherches sur le ''raycasting'', vous verrez que le terme est souvent utilisé pour désigner la méthode de rendu de ces vieux FPS, alors que ce n'en est qu'un cas particulier.
[[File:Simple raycasting with fisheye correction.gif|centre|vignette|upright=2|Simple raycasting with fisheye correction]]
===Le ''raytracing'' proprement dit===
Le lancer de rayon proprement dit est une forme améliorée de ''raycasting'' dans la gestion de l'éclairage et des ombres est modifiée. Le lancer de rayon calcule les ombres assez simplement, sans recourir à des algorithmes compliqués. L'idée est qu'un point d'intersection est dans l'ombre si un objet se trouve entre lui et une source de lumière. Pour déterminer cela, il suffit de tirer un trait entre les deux et de vérifier s'il y a un obstacle/objet sur le trajet. Si c'est le cas, le point d'intersection n'est pas éclairé par la source de lumière et est donc dans l'ombre. Si ce n'est pas le cas, il est éclairé avec un algorithme d'éclairage.
Le trait tiré entre la source de lumière et le point d'intersection est en soi facile : c'est rayon, identique aux rayons envoyés depuis la caméra. La différence est que ces rayons servent à calculer les ombres, ils sont utilisés pour une raison différente. Il faut donc faire la différence entre les '''rayons primaires''' qui partent de la caméra et passent par un pixel de l'écran, et les '''rayon d'ombrage''' qui servent pour le calcul des ombres.
[[File:Ray trace diagram.svg|centre|vignette|upright=2|Principe du lancer de rayons.]]
Les calculs d'éclairage utilisés pour éclairer/ombrer les points d'intersection vous sont déjà connus : la luminosité est calculée à partir de l'algorithme d'éclairage de Phong, vu dans le chapitre "L'éclairage d'une scène 3D : shaders et T&L". Pour cela, il faut juste récupérer la normale du sommet associé au point d'intersection et l'intensité de la source de lumière, et de calculer les informations manquantes (l'angle normale-rayons de lumière, autres). Il détermine alors la couleur de chaque point d'intersection à partir de tout un tas d'informations.
===Le ''raytracing'' récursif===
[[File:Glasses 800 edit.png|vignette|Image rendue avec le lancer de rayons récursif.]]
La technique de lancer de rayons précédente ne gère pas les réflexions, les reflets, des miroirs, les effets de spécularité, et quelques autres effets graphiques de ce style. Pourtant, ils peuvent être implémentés facilement en modifiant le ''raycasting'' d'une manière très simple.
Il suffit de relancer des rayons à partir du point d'intersection. La direction de ces '''rayons secondaires''' est calculée en utilisant les lois de la réfraction/réflexion vues en physique. De plus, les rayons secondaires peuvent eux-aussi créer des rayons secondaires quand ils sont reflétés/réfractés, etc. La technique est alors appelée du ''lancer de rayons récursif'', qui est souvent simplement appelée "lancer de rayons".
[[File:Recursive raytracing.svg|centre|vignette|upright=2|Lancer de rayon récursif.]]
===Les avantages et désavantages comparé à la rastérisation===
L'avantage principal du lancer de rayons est son rendu de l'éclairage, qui est plus réaliste. Les ombres se calculent naturellement avec cette méthode de rendu, là où elles demandent des ruses comme des lightmaps, des textures pré-éclairées, divers algorithmes d'éclairage géométriques, etc. Les réflexions et la réfraction sont gérées naturellement par le lancer de rayon récursif, alors qu'elles demandent des ruses de sioux pour obtenir un résultat correct avec la rastérisation.
[[File:ViewFrustum.svg|vignette|upright=1|Volume délimité par la caméra (''view frustum'').]]
Pour ce qui est des performances théoriques, le lancer de rayons se débrouille mieux sur un point : l'élimination des pixels/surfaces cachés. La rastérisation a tendance à calculer inutilement des portions non-rendues de la scène 3D, et doit utiliser des techniques de ''culling'' ou de ''clipping'' pour éviter trop de calculs inutiles. Ces techniques sont très puissantes, mais imparfaites. De nombreux fragments/pixels calculés sont éliminés à la toute fin du pipeline, grâce au z-buffer, après avoir été calculés et texturés. Le lancer de rayons se passe totalement de ces techniques d'élimination des pixels cachés, car elle ne calcule pas les portions invisibles de l'image par construction : pas besoin de ''culling'', de ''clipping'', ni même de z-buffer.
Mais tous ces avantages sont compensés par le fait que le lancer de rayons est plus lent sur un paquet d'autres points. Déjà, les calculs d'intersection sont très lourds, ils demandent beaucoup de calculs et d'opérations arithmétiques, plus que pour l'équivalent en rastérisation. Ensuite, de nombreuses optimisations présentes en rastérisation ne sont pas possibles. Notamment, le lancer de rayon utilise assez mal la mémoire, dans le sens où les accès en mémoire vidéo sont complétement désorganisés, là où le rendu 3D a des accès plus linéaires qui permettent d'utiliser des mémoires caches.
==Les optimisations du lancer de rayons liées aux volumes englobants==
Les calculs d'intersections sont très gourmands en puissance de calcul. Sans optimisation, on doit tester l'intersection de chaque rayon avec chaque triangle. Mais diverses optimisations permettent d'économiser des calculs. Elles consistent à regrouper plusieurs triangles ensemble pour rejeter des paquets de triangles en une fois. Pour cela, la carte graphique utilise des '''structures d'accélération''', qui mémorisent les regroupements de triangles, et parfois les triangles eux-mêmes.
===Les volumes englobants===
[[File:BoundingBox.jpg|vignette|Objet englobant : la statue est englobée dans un pavé.]]
L'idée est d'englober chaque objet par un pavé appelé un ''volume englobant''. Le tout est illustré ci-contre, avec une statue représentée en 3D. La statue est un objet très complexe, contenant plusieurs centaines ou milliers de triangles, ce qui fait que tester l'intersection d'un rayon avec chaque triangle serait très long. Par contre, on peut tester si le rayon intersecte le volume englobant facilement : il suffit de tester les 6 faces du pavé, soit 12 triangles, pas plus. S'il n'y a pas d'intersection, alors on économise plusieurs centaines ou milliers de tests d'intersection. Par contre, s'il y a intersection, on doit vérifier chaque triangle. Vu que les rayons intersectent souvent peu d'objets, le gain est énorme !
L'usage seul de volumes englobant est une optimisation très performante. Au lieu de tester l'intersection avec chaque triangle, on teste l'intersection avec chaque objet, puis l'intersection avec chaque triangle quand on intersecte chaque volume englobant. On divise le nombre de tests par un facteur quasi-constant, mais de très grande valeur.
Il faut noter que les calculs d'intersection sont légèrement différents entre un triangle et un volume englobant. Il faut dire que les volumes englobant sont généralement des pavées, ils utilisent des rectangles, etc. Les différences sont cependant minimales.
===Les hiérarchies de volumes englobants===
Mais on peut faire encore mieux. L'idée est de regrouper plusieurs volumes englobants en un seul. Si une dizaine d'objets sont proches, leurs volumes englobants seront proches. Il est alors utile d'englober leurs volumes englobants dans un super-volume englobant. L'idée est que l'on teste d'abord le super-volume englobant, au lieu de tester la dizaine de volumes englobants de base. S'il n'y a pas d'intersection, alors on a économisé une dizaine de tests. Mais si intersection, il y a, alors on doit vérifier chaque sous-volume englobant de base, jusqu'à tomber sur une intersection. Vu que les intersections sont rares, on y gagne plus qu'on y perd.
Et on peut faire la même chose avec les super-volumes englobants, en les englobant dans des volumes englobants encore plus grands, et ainsi de suite, récursivement. On obtient alors une '''hiérarchie de volumes englobants''', qui part d'un volume englobant qui contient toute la géométrie, hors skybox, qui lui-même regroupe plusieurs volumes englobants, qui eux-mêmes...
[[File:Example of bounding volume hierarchy.svg|centre|vignette|upright=2|Hiérarchie de volumes englobants.]]
Le nombre de tests d'intersection est alors grandement réduit. On passe d'un nombre de tests proportionnel aux nombres d'objets à un nombre proportionnel à son logarithme. Plus la scène contient d'objets, plus l'économie est importante. La seule difficulté est de générer la hiérarchie de volumes englobants à partir d'une scène 3D. Divers algorithmes assez rapides existent pour cela, ils créent des volumes englobants différents. Les volumes englobants les plus utilisés dans les cartes 3D sont les '''''axis-aligned bounding boxes (AABB)'''''.
La hiérarchie est mémorisée en mémoire RAM, dans une structure de données que les programmeurs connaissent sous le nom d'arbre, et précisément un arbre binaire ou du moins d'un arbre similaire (''k-tree''). Traverser cet arbre pour passer d'un objet englobant à un autre plus petit est très simple, mais a un défaut : on saute d'on objet à un autre en mémoire, les deux sont souvent éloignés en mémoire. La traversée de la mémoire est erratique, sautant d'un point à un autre. On n'est donc dans un cas où les caches fonctionnent mal, ou les techniques de préchargement échouent, où la mémoire devient un point bloquant car trop lente.
===La cohérence des rayons===
Les rayons primaires, émis depuis la caméra, sont proches les uns des autres, et vont tous dans le même sens. Mais ce n'est pas le cas pour des rayons secondaires. Les objets d'une scène 3D ont rarement des surfaces planes, mais sont composés d'un tas de triangles qui font un angle entre eux. La conséquence est que deux rayons secondaires émis depuis deux triangles voisins peuvent aller dans des directions très différentes. Ils vont donc intersecter des objets très différents, atterrir sur des sources de lumières différentes, etc. De tels rayons sont dits '''incohérents''', en opposition aux rayons cohérents qui sont des rayons proches qui vont dans la même direction.
Les rayons incohérents sont peu fréquents avec le ''rayctracing'' récursif basique, mais deviennent plus courants avec des techniques avancées comme le ''path tracing'' ou les techniques d'illumination globale. En soi, la présende de rayons incohérents n'est pas un problème et est parfaitement normale. Le problème est que le traitement des rayons incohérent est plus lent que pour les rayons cohérents. Le traitement de deux rayons secondaires voisins demande d'accéder à des données différentes, ce qui donne des accès mémoire très différents et très éloignés. On ne peut pas profiter des mémoires caches ou des optimisations de la hiérarchie mémoire, si on les traite consécutivement. Un autre défaut est qu'une même instance de ''pixels shaders'' va traiter plusieurs rayons en même temps, grâce au SIMD. Mais les branchements n'auront pas les mêmes résultats d'un rayon à l'autre, et cette divergence entrainera des opérations de masquage et de branchement très couteuses.
Pour éviter cela, les GPU modernes permettent de trier les rayons en fonction de leur direction et de leur origine. Ils traitent les rayons non dans l'ordre usuel, mais essayent de regrouper des rayons proches qui vont dans la même direction, et de les traiter ensemble, en parallèle, ou l'un après l'autre. Cela ne change rien au rendu final, qui traite les rayons en parallèle. Ainsi, les données chargées dans le cache par le premier rayon seront celles utilisées pour les rayons suivants, ce qui donne un gain de performance appréciable. De plus, cela évite d'utiliser des branchements dans les ''pixels shaders''. Les méthodes de '''tri de rayons''' sont nombreuses, aussi en faire une liste exhaustive serait assez long, sans compter qu'on ne sait pas quelles sont celles implémentées en hardware, ni commetn elles le sont.
==Le matériel pour accélérer le lancer de rayons==
Le lancer de rayons a toujours besoin de calculer la géométrie, d'appliquer des textures et de faire des calculs d'éclairage. Sachant cela, beaucoup de chercheurs se sont dit qu'il n'était pas nécessaire d'utiliser du matériel spécialisé pour le lancer de rayons, et qu'utiliser les GPU actuels était suffisant. En théorie, il est possible d'utiliser des ''shaders'' pour effectuer du lancer de rayons, mais la technique n'est pas très performante.
Une carte graphique spécialement dédiée au lancer de rayons est donc quasiment identique à une carte graphique normale. Les deux contiennent des unités de texture et des processeurs de ''shaders'', des unités géométriques, un ''input assembler'', et tout ce qui va avec. Seuls les circuits de rasterisation et le z-buffer sont remplacés par des circuits dédiés au lancer de rayon, à savoir des unités de génération des rayons et des unités pour les calculs d'intersection. D'ailleurs, il est aussi possible d'ajouter des circuits de génération/intersection de rayons à une carte graphique existante.
Au niveau matériel, la gestion de la mémoire est un peu plus simple. Le lancer de rayon n'écrit que dans le ''framebuffer'' et n'a pas besoin de z-buffer, ce qui a beaucoup d'avantages. Notamment, les caches sont en lecture seule, leurs circuits sont donc assez simples et performants, les problèmes de cohérence des caches disparaissent. L'absence de z-buffer fait que de nombreuses écritures/lectures dans le ''framebuffer'' sont économisées. Les lectures et écritures de textures sont tout aussi fréquentes qu'avec la rasterisation, et sont même plus faible en principe car de nombreux effets de lumières complexes sont calculés avec le lancer de rayons, alors qu'ils doivent être précalculés dans des textures et lus par les shaders.
===Les circuits spécialisés pour les calculs liés aux rayons===
Toute la subtilité du lancer de rayons est de générer les rayons et de déterminer quels triangles ils intersectent. La seule difficulté est de gérer la transparence, mais aussi et surtout la traversée de la BVH. En soit, générer les rayons et déterminer leurs intersections n'est pas compliqué. Il existe des algorithmes basés sur du calcul vectoriel pour déterminer si intersection il y a et quelles sont ses coordonnées. C'est toute la partie de parcours de la BVH qui est plus compliquée à implémenter : faire du ''pointer chasing'' en hardware n'est pas facile.
Et cela se ressent quand on étudie comment les GPU récents gèrent le lancer de rayons. Ils utilisent des shaders dédiés, qui communiquent avec une '''unité de lancer de rayon''' dédiée à la traversée de la BVH. Le terme anglais est ''Ray-tracing Unit'', ce qui fait que nous utiliseront l'abréviation RTU pour la désigner. Les shaders spécialisés sont des shaders de lancer de rayon, qui s'occupent de générer les rayons, mais aussi de faire tous les calculs une fois qu'une intersection est détectée. Le processus est le suivant :
* En premier lieu, les shaders de lancer de rayon génèrent les rayons lancés.
* Ensuite, ils laissent la main à l'unité de lancer de rayon. Elle parcours la BVH et effectue les calculs d'intersection. C'est elle qui détermine quels triangles intersectent un rayon.
* A chaque fois que la RTU détecte une intersection, elle envoie son résultat au ''shader'' de lancer de rayon, qui reprend la main et finit le travail. Lors de cette étape, il peut générer un nouveau rayon, et le processus recommence.
La génération des rayons a donc lieu dans les processeur de ''shaders'', avec cependant une petite subtilité quant aux rayons secondaires. La génération des rayons primaires est triviale, mais la génération des rayons d'ombrage et des rayons secondaires est par contre plus complexe. Les rayons d'ombrage et secondaires sont générés à partir du résultat des intersections des rayons précédents. Et dans les faits, ce sont les ''shaders'' qui s'occupent de générer les rayons secondaires. Suivant la nature de la surface (opaque, transparente, réfléchissante, mate, autre), ils décident s'il faut ou non émettre un rayon secondaire, et génère ce rayon s'il le faut. Le rayon est alors envoyé aux unités de traversée et d'intersection.
====La traversée des structures d'accélérations et des BVH====
Lorsqu'un processeur de shader fait appel à la RTU, il lui envoie un rayon encodé d'une manière ou d'une autre, potentiellement différente d'un GPU à l'autre. Toujours est-il que les informations sur ce rayon sont mémorisée dans des registres à l'intérieur de la RTU. Ce n'est que quand le rayon quitte la RTU que ces registres sont réinitialisé pour laisser la palce à un autre rayon.
La RTU contient aussi beaucoup d'unités de calcul pour effectuer les calculs d'intersections. Il est possible de tester un grand nombre d'intersections de triangles en parallèles, chacun dans une unité de calcul séparée. L'algorithme de lancer de rayons se parallélise donc très bien et la RTU en profite. En soi, les circuits de détection des intersections sont très simples et se résument à un paquet de circuits de calcul (addition, multiplications, division, autres), connectés les uns aux autres. Il y a assez peu à dire dessus. Mais les autres circuits sont très intéressants à étudier.
L'intérieur de la RTU contient de quoi séquencer les accès mémoire nécessaires pour parcourir la BVH. Les circuits pour ce faire se trouvent vraisemblablement dans les unités de texture, si on en croit quelques brevets déposés par les fabricants de carte graphiques, ce qui est logique vu qu'il s'agit d'un des seuls endroits où la carte graphique gère des accès mémoire une fois la géométrie rendue. Et ces unités effectuent un travail essentiel. Car si le calcul des intersections est une chose facile pour la carte graphique, la gestion des structures d'accélération ne l'est pas du tout. Et ce pour plusieurs raisons.
Déjà, les BVH se marient assez mal avec les mémoires caches et la hiérarchie mémoire. Ce sont des structures de données qui dispersent les données en mémoire, dans le sens où chaque volume englobant est située dans sa propre portion de mémoire et celles-ci ne sont pas collées les unes aux autres en mémoire RAM. A l'inverse, les autres structures de données utilisées par la carte graphique, comme les tampons de sommets ou d'indice, les textures, sont des tableaux, des structures de données compactes qui forment un seul bloc en RAM. Traverser un BVH demande de faire des sauts en mémoire RAM, et ce sont des accès mémoire imprévisibles que l'on ne peut pas optimiser, pour lesquels les caches sont inopérants.
L'autre raison, très liée à la précédente, est que traverser un BVH pour trouver le triangle intersectant demande d'effectuer beaucoup de branchements. On doit tester l'intersection avec un volume englobant, puis décider s'il faut passer au suivant, et si oui lequel, et rebelotte. Et dans du code informatique, cela demande beaucoup de IF...ELSE, de branchements, de tests de conditions, etc. Et les cartes graphiques sont assez mauvaises à ça. Les ''shaders'' peuvent en faire, mais sont très lents pour ces opérations.
Les cartes graphiques modernes incorporent des circuits de tri pour regrouper les rayons cohérents, ceux qui vont dans la même direction et proviennent de triangles proches. Ce afin d'implémenter les optimisations vues plus haut.
====La génération des structures d'accélération et BVH====
La plupart des cartes graphiques ne peuvent pas générer les BVH d'elles-mêmes. Pareil pour les autres structures d'accélération. Elles sont calculées par le processeur, stockées en mémoire RAM, puis copiées dans la mémoire vidéo avant le démarrage du rendu 3D. Cependant, quelques rares cartes spécialement dédiées au lancer de rayons incorporent des circuits pour générer les BVH/AS. Elles lisent le tampon de sommet envoyé par le processeur, puis génèrent les BVH complémentaires. L'unité de génération des structures d'accélération est complétement séparée des autres unités. Un exemple d'architecture de ce type est l'architecture Raycore, dont nous parlerons dans les sections suivantes.
Cette unité peut aussi modifier les BVH à la volée, si jamais la scène 3D change. Par exemple, si un objet change de place, comme un NPC qui se déplace, il faut reconstruire le BVH. Les cartes graphiques récentes évitent de reconstruire le BVH de zéro, mais se contentent de modifier ce qui a changé dans le BVH. Les performances en sont nettement meilleures.
===Les cartes graphiques dédiées au lancer de rayon===
Les premières cartes accélératrices de lancer de rayons sont assez anciennes et datent des années 80-90. Leur évolution a plus ou moins suivi la même évolution que celle des cartes graphiques usuelles, sauf que très peu de cartes pour le lancer de rayons ont été produites. Par même évolution, on veut dire que les cartes graphiques pour le lancer de rayon ont commencé par tester deux solutions évidentes et extrêmes : les cartes basées sur des circuits programmables d'un côté, non programmables de l'autre.
La première carte pour le lancer de rayons était la TigerShark, et elle était tout simplement composée de plusieurs processeurs et de la mémoire sur une carte PCI. Elle ne faisait qu'accélérer le calcul des intersections, rien de plus.
Les autres cartes effectuaient du rendu 3D par voxel, un type de rendu 3D assez spécial que nous n'avons pas abordé jusqu'à présent, dont l'algorithme de lancer de rayons n'était qu'une petite partie du rendu. Elles étaient destinées au marché scientifique, industriel et médical. On peut notamment citer la VolumePro et la VIZARD et II. Les deux étaient des cartes pour bus PCI qui ne faisaient que du ''raycasting'' et n'utilisaient pas de rayons d'ombrage. Le ''raycasting'' était exécuté sur un processeur dédié sur la VIZARD II, sur un circuit fixe implémenté par un FPGA sur la Volume Pro Voici différents papiers académiques qui décrivent l'architecture de ces cartes accélératrices :
* [https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=ccda3712ba0e6575cd08025f3bb920de46201cac The VolumePro Real-Time Ray-Casting System].
* [https://www.researchgate.net/publication/234829060_VIZARD_II_A_reconfigurable_interactive_volume_rendering_system VIZARD II: A reconfigurable interactive volume rendering system]
La puce SaarCOR (Saarbrücken's Coherence Optimized Ray Tracer) et bien plus tard par la carte Raycore, étaient deux cartes réelement dédiées au raycasting pur, sans usage de voxels, et étaient basées sur des FPGA. Elles contenaient uniquement des circuits pour accélérer le lancer de rayon proprement dit, à savoir la génération des rayons, les calculs d'intersection, pas plus. Tout le reste, à savoir le rendu de la géométrie, le placage de textures, les ''shaders'' et autres, étaient effectués par le processeur. Voici des papiers académiques sur leur architecture :
* [https://gamma.cs.unc.edu/SATO/Raycore/raycore.pdf RayCore: A ray-tracing hardware architecture for mobile devices].
Le successeur de la SaarCOR, le Ray Processing Unit (RPU), était une carte hybride : c'était une SaarCOR basée sur des circuits fixes, qui gagna quelques possibilités de programmation. Elle ajoutait des processeurs de ''shaders'' aux circuits fixes spécialisés pour le lancer de rayons. Les autres cartes du genre faisaient pareil, et on peut citer les cartes ART, les cartes CausticOne, Caustic Professional's R2500 et R2100.
Les cartes 3D modernes permettent de faire à la fois de la rasterisation et du lancer de rayons. Pour cela, les GPU récents incorporent des unités pour effectuer des calculs d'intersection, qui sont réalisés dans des circuits spécialisés. Elles sont appelées des RT Cores sur les cartes NVIDIA, mais les cartes AMD et Intel ont leur équivalent, idem chez leurs concurrents de chez Imagination technologies, ainsi que sur certains GPU destinés au marché mobile. Peu de choses sont certaines sur ces unités, mais il semblerait qu'il s'agisse d'unités de textures modifiées.
De ce qu'on en sait, certains GPU utilisent des unités pour calculer les intersections avec les triangles, et d'autres unités séparées pour calculer les intersections avec les volumes englobants. La raison est que, comme dit plus haut, les algorithmes de calcul d'intersection sont différents dans les deux cas. Les algorithmes utilisés ne sont pas connus pour toutes les cartes graphiques. On sait que les GPU Wizard de Imagination technology utilisaient des tests AABB de Plücker. Ils utilisaient 15 circuits de multiplication, 9 additionneurs-soustracteurs, quelques circuits pour tester la présence dans un intervalle, des circuits de normalisation et arrondi. L'algorithme pour leurs GPU d'architecture Photon est disponible ici, pour les curieux : [https://www.highperformancegraphics.org/slides23/2023-06-_HPG_IMG_RayTracing_2.pdf].
{{NavChapitre | book=Les cartes graphiques
| prev=Le multi-GPU
| prevText=Le multi-GPU
}}{{autocat}}
komi4bp8n9mktd2h2bu4prgsl5ve8jq
744330
744329
2025-06-08T16:58:29Z
Mewtow
31375
/* La traversée des structures d'accélérations et des BVH */
744330
wikitext
text/x-wiki
Les cartes graphiques actuelles utilisent la technique de la rastérisation, qui a été décrite en détail dans le chapitre sur les cartes accélératrices 3D. Mais nous avions dit qu'il existe une seconde technique générale pour le rendu 3D, totalement opposée à la rastérisation, appelée le '''lancer de rayons'''. Cette technique a cependant été peu utilisée dans les jeux vidéo, jusqu'à récemment. La raison est que le lancer de rayons demande beaucoup de puissance de calcul, sans compter que créer des cartes accélératrices pour le lancer de rayons n'est pas simple.
Mais les choses commencent à changer. Quelques jeux vidéos récents intègrent des techniques de lancer rayons, pour compléter un rendu effectué principalement en rastérisation. De plus, les cartes graphiques modernes incorporent quelques circuits pour accélérer le lancer de rayons, même s'ils restent marginaux des compléments au rendu par rastérisation. S'il a existé des cartes accélératrices totalement dédiées au rendu en lancer de rayons, elles sont restées confidentielles. Aussi, nous allons nous concentrer sur les cartes graphiques récentes, et allons peu parler des cartes accélératrices dédiées au lancer de rayons.
==Le lancer de rayons==
Le lancer de rayons et la rastérisation. commencent par générer la géométrie de la scène 3D, en plaçant les objets dans la scène 3D, et en effectuant l'étape de transformation des modèles 3D, et les étapes de transformation suivante. Mais les ressemblances s'arrêtent là. Le lancer de rayons effectue l'étape d'éclairage différemment, sans compter qu'il n'a pas besoin de rastérisation.
===Le ''ray-casting'' : des rayons tirés depuis la caméra===
La forme la plus simple de lancer de rayon s'appelle le '''''ray-casting'''''. Elle émet des lignes droites, des '''rayons''' qui partent de la caméra et qui passent chacun par un pixel de l'écran. Les rayons font alors intersecter les différents objets présents dans la scène 3D, en un point d'intersection. Le moteur du jeu détermine alors quel est le point d'intersection le plus proche, ou plus précisément, le sommet le plus proche de ce point d'intersection. Ce sommet est associé à une coordonnée de textures, ce qui permet d'associer directement un texel au pixel associé au rayon.
[[File:Raytrace trace diagram.png|centre|vignette|upright=2|Raycasting, rayon simple.]]
En somme, l'étape de lancer de rayon et le calcul des intersections remplacent l'étape de rasterisation, mais les étapes de traitement de la géométrie et des textures existent encore. Après tout, il faut bien placer les objets dans la scène 3D/2D, faire diverses transformations, les éclairer. On peut gérer la transparence des textures assez simplement, si on connait la transparence sur chaque point d'intersection d'un rayon, information présente dans les textures.
[[File:Anarch short gameplay.gif|vignette|Exemple de rendu en ray-casting 2D dans un jeu vidéo.]]
En soi, cet algorithme est simple, mais il a déjà été utilisé dans pas mal de jeux vidéos. Mais sous une forme simple, en deux dimensions ! Les premiers jeux IdSoftware, dont Wolfenstein 3D et Catacomb, utilisaient cette méthode de rendu, mais dans un univers en deux dimensions. Cet article explique bien cela : [[Les moteurs de rendu des FPS en 2.5 D\Le moteur de Wolfenstein 3D|Le moteur de rendu de Wolfenstein 3D]]. Au passage, si vous faites des recherches sur le ''raycasting'', vous verrez que le terme est souvent utilisé pour désigner la méthode de rendu de ces vieux FPS, alors que ce n'en est qu'un cas particulier.
[[File:Simple raycasting with fisheye correction.gif|centre|vignette|upright=2|Simple raycasting with fisheye correction]]
===Le ''raytracing'' proprement dit===
Le lancer de rayon proprement dit est une forme améliorée de ''raycasting'' dans la gestion de l'éclairage et des ombres est modifiée. Le lancer de rayon calcule les ombres assez simplement, sans recourir à des algorithmes compliqués. L'idée est qu'un point d'intersection est dans l'ombre si un objet se trouve entre lui et une source de lumière. Pour déterminer cela, il suffit de tirer un trait entre les deux et de vérifier s'il y a un obstacle/objet sur le trajet. Si c'est le cas, le point d'intersection n'est pas éclairé par la source de lumière et est donc dans l'ombre. Si ce n'est pas le cas, il est éclairé avec un algorithme d'éclairage.
Le trait tiré entre la source de lumière et le point d'intersection est en soi facile : c'est rayon, identique aux rayons envoyés depuis la caméra. La différence est que ces rayons servent à calculer les ombres, ils sont utilisés pour une raison différente. Il faut donc faire la différence entre les '''rayons primaires''' qui partent de la caméra et passent par un pixel de l'écran, et les '''rayon d'ombrage''' qui servent pour le calcul des ombres.
[[File:Ray trace diagram.svg|centre|vignette|upright=2|Principe du lancer de rayons.]]
Les calculs d'éclairage utilisés pour éclairer/ombrer les points d'intersection vous sont déjà connus : la luminosité est calculée à partir de l'algorithme d'éclairage de Phong, vu dans le chapitre "L'éclairage d'une scène 3D : shaders et T&L". Pour cela, il faut juste récupérer la normale du sommet associé au point d'intersection et l'intensité de la source de lumière, et de calculer les informations manquantes (l'angle normale-rayons de lumière, autres). Il détermine alors la couleur de chaque point d'intersection à partir de tout un tas d'informations.
===Le ''raytracing'' récursif===
[[File:Glasses 800 edit.png|vignette|Image rendue avec le lancer de rayons récursif.]]
La technique de lancer de rayons précédente ne gère pas les réflexions, les reflets, des miroirs, les effets de spécularité, et quelques autres effets graphiques de ce style. Pourtant, ils peuvent être implémentés facilement en modifiant le ''raycasting'' d'une manière très simple.
Il suffit de relancer des rayons à partir du point d'intersection. La direction de ces '''rayons secondaires''' est calculée en utilisant les lois de la réfraction/réflexion vues en physique. De plus, les rayons secondaires peuvent eux-aussi créer des rayons secondaires quand ils sont reflétés/réfractés, etc. La technique est alors appelée du ''lancer de rayons récursif'', qui est souvent simplement appelée "lancer de rayons".
[[File:Recursive raytracing.svg|centre|vignette|upright=2|Lancer de rayon récursif.]]
===Les avantages et désavantages comparé à la rastérisation===
L'avantage principal du lancer de rayons est son rendu de l'éclairage, qui est plus réaliste. Les ombres se calculent naturellement avec cette méthode de rendu, là où elles demandent des ruses comme des lightmaps, des textures pré-éclairées, divers algorithmes d'éclairage géométriques, etc. Les réflexions et la réfraction sont gérées naturellement par le lancer de rayon récursif, alors qu'elles demandent des ruses de sioux pour obtenir un résultat correct avec la rastérisation.
[[File:ViewFrustum.svg|vignette|upright=1|Volume délimité par la caméra (''view frustum'').]]
Pour ce qui est des performances théoriques, le lancer de rayons se débrouille mieux sur un point : l'élimination des pixels/surfaces cachés. La rastérisation a tendance à calculer inutilement des portions non-rendues de la scène 3D, et doit utiliser des techniques de ''culling'' ou de ''clipping'' pour éviter trop de calculs inutiles. Ces techniques sont très puissantes, mais imparfaites. De nombreux fragments/pixels calculés sont éliminés à la toute fin du pipeline, grâce au z-buffer, après avoir été calculés et texturés. Le lancer de rayons se passe totalement de ces techniques d'élimination des pixels cachés, car elle ne calcule pas les portions invisibles de l'image par construction : pas besoin de ''culling'', de ''clipping'', ni même de z-buffer.
Mais tous ces avantages sont compensés par le fait que le lancer de rayons est plus lent sur un paquet d'autres points. Déjà, les calculs d'intersection sont très lourds, ils demandent beaucoup de calculs et d'opérations arithmétiques, plus que pour l'équivalent en rastérisation. Ensuite, de nombreuses optimisations présentes en rastérisation ne sont pas possibles. Notamment, le lancer de rayon utilise assez mal la mémoire, dans le sens où les accès en mémoire vidéo sont complétement désorganisés, là où le rendu 3D a des accès plus linéaires qui permettent d'utiliser des mémoires caches.
==Les optimisations du lancer de rayons liées aux volumes englobants==
Les calculs d'intersections sont très gourmands en puissance de calcul. Sans optimisation, on doit tester l'intersection de chaque rayon avec chaque triangle. Mais diverses optimisations permettent d'économiser des calculs. Elles consistent à regrouper plusieurs triangles ensemble pour rejeter des paquets de triangles en une fois. Pour cela, la carte graphique utilise des '''structures d'accélération''', qui mémorisent les regroupements de triangles, et parfois les triangles eux-mêmes.
===Les volumes englobants===
[[File:BoundingBox.jpg|vignette|Objet englobant : la statue est englobée dans un pavé.]]
L'idée est d'englober chaque objet par un pavé appelé un ''volume englobant''. Le tout est illustré ci-contre, avec une statue représentée en 3D. La statue est un objet très complexe, contenant plusieurs centaines ou milliers de triangles, ce qui fait que tester l'intersection d'un rayon avec chaque triangle serait très long. Par contre, on peut tester si le rayon intersecte le volume englobant facilement : il suffit de tester les 6 faces du pavé, soit 12 triangles, pas plus. S'il n'y a pas d'intersection, alors on économise plusieurs centaines ou milliers de tests d'intersection. Par contre, s'il y a intersection, on doit vérifier chaque triangle. Vu que les rayons intersectent souvent peu d'objets, le gain est énorme !
L'usage seul de volumes englobant est une optimisation très performante. Au lieu de tester l'intersection avec chaque triangle, on teste l'intersection avec chaque objet, puis l'intersection avec chaque triangle quand on intersecte chaque volume englobant. On divise le nombre de tests par un facteur quasi-constant, mais de très grande valeur.
Il faut noter que les calculs d'intersection sont légèrement différents entre un triangle et un volume englobant. Il faut dire que les volumes englobant sont généralement des pavées, ils utilisent des rectangles, etc. Les différences sont cependant minimales.
===Les hiérarchies de volumes englobants===
Mais on peut faire encore mieux. L'idée est de regrouper plusieurs volumes englobants en un seul. Si une dizaine d'objets sont proches, leurs volumes englobants seront proches. Il est alors utile d'englober leurs volumes englobants dans un super-volume englobant. L'idée est que l'on teste d'abord le super-volume englobant, au lieu de tester la dizaine de volumes englobants de base. S'il n'y a pas d'intersection, alors on a économisé une dizaine de tests. Mais si intersection, il y a, alors on doit vérifier chaque sous-volume englobant de base, jusqu'à tomber sur une intersection. Vu que les intersections sont rares, on y gagne plus qu'on y perd.
Et on peut faire la même chose avec les super-volumes englobants, en les englobant dans des volumes englobants encore plus grands, et ainsi de suite, récursivement. On obtient alors une '''hiérarchie de volumes englobants''', qui part d'un volume englobant qui contient toute la géométrie, hors skybox, qui lui-même regroupe plusieurs volumes englobants, qui eux-mêmes...
[[File:Example of bounding volume hierarchy.svg|centre|vignette|upright=2|Hiérarchie de volumes englobants.]]
Le nombre de tests d'intersection est alors grandement réduit. On passe d'un nombre de tests proportionnel aux nombres d'objets à un nombre proportionnel à son logarithme. Plus la scène contient d'objets, plus l'économie est importante. La seule difficulté est de générer la hiérarchie de volumes englobants à partir d'une scène 3D. Divers algorithmes assez rapides existent pour cela, ils créent des volumes englobants différents. Les volumes englobants les plus utilisés dans les cartes 3D sont les '''''axis-aligned bounding boxes (AABB)'''''.
La hiérarchie est mémorisée en mémoire RAM, dans une structure de données que les programmeurs connaissent sous le nom d'arbre, et précisément un arbre binaire ou du moins d'un arbre similaire (''k-tree''). Traverser cet arbre pour passer d'un objet englobant à un autre plus petit est très simple, mais a un défaut : on saute d'on objet à un autre en mémoire, les deux sont souvent éloignés en mémoire. La traversée de la mémoire est erratique, sautant d'un point à un autre. On n'est donc dans un cas où les caches fonctionnent mal, ou les techniques de préchargement échouent, où la mémoire devient un point bloquant car trop lente.
===La cohérence des rayons===
Les rayons primaires, émis depuis la caméra, sont proches les uns des autres, et vont tous dans le même sens. Mais ce n'est pas le cas pour des rayons secondaires. Les objets d'une scène 3D ont rarement des surfaces planes, mais sont composés d'un tas de triangles qui font un angle entre eux. La conséquence est que deux rayons secondaires émis depuis deux triangles voisins peuvent aller dans des directions très différentes. Ils vont donc intersecter des objets très différents, atterrir sur des sources de lumières différentes, etc. De tels rayons sont dits '''incohérents''', en opposition aux rayons cohérents qui sont des rayons proches qui vont dans la même direction.
Les rayons incohérents sont peu fréquents avec le ''rayctracing'' récursif basique, mais deviennent plus courants avec des techniques avancées comme le ''path tracing'' ou les techniques d'illumination globale. En soi, la présende de rayons incohérents n'est pas un problème et est parfaitement normale. Le problème est que le traitement des rayons incohérent est plus lent que pour les rayons cohérents. Le traitement de deux rayons secondaires voisins demande d'accéder à des données différentes, ce qui donne des accès mémoire très différents et très éloignés. On ne peut pas profiter des mémoires caches ou des optimisations de la hiérarchie mémoire, si on les traite consécutivement. Un autre défaut est qu'une même instance de ''pixels shaders'' va traiter plusieurs rayons en même temps, grâce au SIMD. Mais les branchements n'auront pas les mêmes résultats d'un rayon à l'autre, et cette divergence entrainera des opérations de masquage et de branchement très couteuses.
Pour éviter cela, les GPU modernes permettent de trier les rayons en fonction de leur direction et de leur origine. Ils traitent les rayons non dans l'ordre usuel, mais essayent de regrouper des rayons proches qui vont dans la même direction, et de les traiter ensemble, en parallèle, ou l'un après l'autre. Cela ne change rien au rendu final, qui traite les rayons en parallèle. Ainsi, les données chargées dans le cache par le premier rayon seront celles utilisées pour les rayons suivants, ce qui donne un gain de performance appréciable. De plus, cela évite d'utiliser des branchements dans les ''pixels shaders''. Les méthodes de '''tri de rayons''' sont nombreuses, aussi en faire une liste exhaustive serait assez long, sans compter qu'on ne sait pas quelles sont celles implémentées en hardware, ni commetn elles le sont.
==Le matériel pour accélérer le lancer de rayons==
Le lancer de rayons a toujours besoin de calculer la géométrie, d'appliquer des textures et de faire des calculs d'éclairage. Sachant cela, beaucoup de chercheurs se sont dit qu'il n'était pas nécessaire d'utiliser du matériel spécialisé pour le lancer de rayons, et qu'utiliser les GPU actuels était suffisant. En théorie, il est possible d'utiliser des ''shaders'' pour effectuer du lancer de rayons, mais la technique n'est pas très performante.
Une carte graphique spécialement dédiée au lancer de rayons est donc quasiment identique à une carte graphique normale. Les deux contiennent des unités de texture et des processeurs de ''shaders'', des unités géométriques, un ''input assembler'', et tout ce qui va avec. Seuls les circuits de rasterisation et le z-buffer sont remplacés par des circuits dédiés au lancer de rayon, à savoir des unités de génération des rayons et des unités pour les calculs d'intersection. D'ailleurs, il est aussi possible d'ajouter des circuits de génération/intersection de rayons à une carte graphique existante.
Au niveau matériel, la gestion de la mémoire est un peu plus simple. Le lancer de rayon n'écrit que dans le ''framebuffer'' et n'a pas besoin de z-buffer, ce qui a beaucoup d'avantages. Notamment, les caches sont en lecture seule, leurs circuits sont donc assez simples et performants, les problèmes de cohérence des caches disparaissent. L'absence de z-buffer fait que de nombreuses écritures/lectures dans le ''framebuffer'' sont économisées. Les lectures et écritures de textures sont tout aussi fréquentes qu'avec la rasterisation, et sont même plus faible en principe car de nombreux effets de lumières complexes sont calculés avec le lancer de rayons, alors qu'ils doivent être précalculés dans des textures et lus par les shaders.
===Les circuits spécialisés pour les calculs liés aux rayons===
Toute la subtilité du lancer de rayons est de générer les rayons et de déterminer quels triangles ils intersectent. La seule difficulté est de gérer la transparence, mais aussi et surtout la traversée de la BVH. En soit, générer les rayons et déterminer leurs intersections n'est pas compliqué. Il existe des algorithmes basés sur du calcul vectoriel pour déterminer si intersection il y a et quelles sont ses coordonnées. C'est toute la partie de parcours de la BVH qui est plus compliquée à implémenter : faire du ''pointer chasing'' en hardware n'est pas facile.
Et cela se ressent quand on étudie comment les GPU récents gèrent le lancer de rayons. Ils utilisent des shaders dédiés, qui communiquent avec une '''unité de lancer de rayon''' dédiée à la traversée de la BVH. Le terme anglais est ''Ray-tracing Unit'', ce qui fait que nous utiliseront l'abréviation RTU pour la désigner. Les shaders spécialisés sont des shaders de lancer de rayon, qui s'occupent de générer les rayons, mais aussi de faire tous les calculs une fois qu'une intersection est détectée. Le processus est le suivant :
* En premier lieu, les shaders de lancer de rayon génèrent les rayons lancés.
* Ensuite, ils laissent la main à l'unité de lancer de rayon. Elle parcours la BVH et effectue les calculs d'intersection. C'est elle qui détermine quels triangles intersectent un rayon.
* A chaque fois que la RTU détecte une intersection, elle envoie son résultat au ''shader'' de lancer de rayon, qui reprend la main et finit le travail. Lors de cette étape, il peut générer un nouveau rayon, et le processus recommence.
La génération des rayons a donc lieu dans les processeur de ''shaders'', avec cependant une petite subtilité quant aux rayons secondaires. La génération des rayons primaires est triviale, mais la génération des rayons d'ombrage et des rayons secondaires est par contre plus complexe. Les rayons d'ombrage et secondaires sont générés à partir du résultat des intersections des rayons précédents. Et dans les faits, ce sont les ''shaders'' qui s'occupent de générer les rayons secondaires. Suivant la nature de la surface (opaque, transparente, réfléchissante, mate, autre), ils décident s'il faut ou non émettre un rayon secondaire, et génère ce rayon s'il le faut. Le rayon est alors envoyé aux unités de traversée et d'intersection.
====La traversée des structures d'accélérations et des BVH====
Lorsqu'un processeur de shader fait appel à la RTU, il lui envoie un rayon encodé d'une manière ou d'une autre, potentiellement différente d'un GPU à l'autre. Toujours est-il que les informations sur ce rayon sont mémorisée dans des registres à l'intérieur de la RTU. Ce n'est que quand le rayon quitte la RTU que ces registres sont réinitialisé pour laisser la palce à un autre rayon.
La RTU contient aussi beaucoup d'unités de calcul pour effectuer les calculs d'intersections. Il est possible de tester un grand nombre d'intersections de triangles en parallèles, chacun dans une unité de calcul séparée. L'algorithme de lancer de rayons se parallélise donc très bien et la RTU en profite. En soi, les circuits de détection des intersections sont très simples et se résument à un paquet de circuits de calcul (addition, multiplications, division, autres), connectés les uns aux autres. Il y a assez peu à dire dessus. Mais les autres circuits sont très intéressants à étudier.
L'intérieur de la RTU contient de quoi séquencer les accès mémoire nécessaires pour parcourir la BVH. Et le problème est que les BVH se marient assez mal avec la hiérarchie mémoire des GPU et CPU modernes. Ce sont des structures de données qui dispersent les données en mémoire, là où les GPU préfèrent des structures de données qui forment un seul bloc en RAM. Traverser un BVH demande de faire des sauts en mémoire RAM, et ce sont des accès mémoire imprévisibles que l'on ne peut pas optimiser. Pour limiter la casse, les RTU intègrent des caches pour mémoriser des portions de la BVH, au cas où celles-ci seraient retraversées plusieurs fois de suite par des rayons consécutifs. Mais ceux-ci ont un impact plus léger sur les performances.
L'autre raison, très liée à la précédente, est que traverser un BVH pour trouver le triangle intersectant demande d'effectuer beaucoup de branchements. On doit tester l'intersection avec un volume englobant, puis décider s'il faut passer au suivant, et si oui lequel, et rebelotte. Et dans du code informatique, cela demande beaucoup de IF...ELSE, de branchements, de tests de conditions, etc. Et les cartes graphiques sont assez mauvaises à ça. Les ''shaders'' peuvent en faire, mais sont très lents pour ces opérations. Pour diminuer l’impact sur les performances, les cartes graphiques modernes incorporent des circuits de tri pour regrouper les rayons cohérents, ceux qui vont dans la même direction et proviennent de triangles proches. Ce afin d'implémenter les optimisations vues plus haut.
====La génération des structures d'accélération et BVH====
La plupart des cartes graphiques ne peuvent pas générer les BVH d'elles-mêmes. Pareil pour les autres structures d'accélération. Elles sont calculées par le processeur, stockées en mémoire RAM, puis copiées dans la mémoire vidéo avant le démarrage du rendu 3D. Cependant, quelques rares cartes spécialement dédiées au lancer de rayons incorporent des circuits pour générer les BVH/AS. Elles lisent le tampon de sommet envoyé par le processeur, puis génèrent les BVH complémentaires. L'unité de génération des structures d'accélération est complétement séparée des autres unités. Un exemple d'architecture de ce type est l'architecture Raycore, dont nous parlerons dans les sections suivantes.
Cette unité peut aussi modifier les BVH à la volée, si jamais la scène 3D change. Par exemple, si un objet change de place, comme un NPC qui se déplace, il faut reconstruire le BVH. Les cartes graphiques récentes évitent de reconstruire le BVH de zéro, mais se contentent de modifier ce qui a changé dans le BVH. Les performances en sont nettement meilleures.
===Les cartes graphiques dédiées au lancer de rayon===
Les premières cartes accélératrices de lancer de rayons sont assez anciennes et datent des années 80-90. Leur évolution a plus ou moins suivi la même évolution que celle des cartes graphiques usuelles, sauf que très peu de cartes pour le lancer de rayons ont été produites. Par même évolution, on veut dire que les cartes graphiques pour le lancer de rayon ont commencé par tester deux solutions évidentes et extrêmes : les cartes basées sur des circuits programmables d'un côté, non programmables de l'autre.
La première carte pour le lancer de rayons était la TigerShark, et elle était tout simplement composée de plusieurs processeurs et de la mémoire sur une carte PCI. Elle ne faisait qu'accélérer le calcul des intersections, rien de plus.
Les autres cartes effectuaient du rendu 3D par voxel, un type de rendu 3D assez spécial que nous n'avons pas abordé jusqu'à présent, dont l'algorithme de lancer de rayons n'était qu'une petite partie du rendu. Elles étaient destinées au marché scientifique, industriel et médical. On peut notamment citer la VolumePro et la VIZARD et II. Les deux étaient des cartes pour bus PCI qui ne faisaient que du ''raycasting'' et n'utilisaient pas de rayons d'ombrage. Le ''raycasting'' était exécuté sur un processeur dédié sur la VIZARD II, sur un circuit fixe implémenté par un FPGA sur la Volume Pro Voici différents papiers académiques qui décrivent l'architecture de ces cartes accélératrices :
* [https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=ccda3712ba0e6575cd08025f3bb920de46201cac The VolumePro Real-Time Ray-Casting System].
* [https://www.researchgate.net/publication/234829060_VIZARD_II_A_reconfigurable_interactive_volume_rendering_system VIZARD II: A reconfigurable interactive volume rendering system]
La puce SaarCOR (Saarbrücken's Coherence Optimized Ray Tracer) et bien plus tard par la carte Raycore, étaient deux cartes réelement dédiées au raycasting pur, sans usage de voxels, et étaient basées sur des FPGA. Elles contenaient uniquement des circuits pour accélérer le lancer de rayon proprement dit, à savoir la génération des rayons, les calculs d'intersection, pas plus. Tout le reste, à savoir le rendu de la géométrie, le placage de textures, les ''shaders'' et autres, étaient effectués par le processeur. Voici des papiers académiques sur leur architecture :
* [https://gamma.cs.unc.edu/SATO/Raycore/raycore.pdf RayCore: A ray-tracing hardware architecture for mobile devices].
Le successeur de la SaarCOR, le Ray Processing Unit (RPU), était une carte hybride : c'était une SaarCOR basée sur des circuits fixes, qui gagna quelques possibilités de programmation. Elle ajoutait des processeurs de ''shaders'' aux circuits fixes spécialisés pour le lancer de rayons. Les autres cartes du genre faisaient pareil, et on peut citer les cartes ART, les cartes CausticOne, Caustic Professional's R2500 et R2100.
Les cartes 3D modernes permettent de faire à la fois de la rasterisation et du lancer de rayons. Pour cela, les GPU récents incorporent des unités pour effectuer des calculs d'intersection, qui sont réalisés dans des circuits spécialisés. Elles sont appelées des RT Cores sur les cartes NVIDIA, mais les cartes AMD et Intel ont leur équivalent, idem chez leurs concurrents de chez Imagination technologies, ainsi que sur certains GPU destinés au marché mobile. Peu de choses sont certaines sur ces unités, mais il semblerait qu'il s'agisse d'unités de textures modifiées.
De ce qu'on en sait, certains GPU utilisent des unités pour calculer les intersections avec les triangles, et d'autres unités séparées pour calculer les intersections avec les volumes englobants. La raison est que, comme dit plus haut, les algorithmes de calcul d'intersection sont différents dans les deux cas. Les algorithmes utilisés ne sont pas connus pour toutes les cartes graphiques. On sait que les GPU Wizard de Imagination technology utilisaient des tests AABB de Plücker. Ils utilisaient 15 circuits de multiplication, 9 additionneurs-soustracteurs, quelques circuits pour tester la présence dans un intervalle, des circuits de normalisation et arrondi. L'algorithme pour leurs GPU d'architecture Photon est disponible ici, pour les curieux : [https://www.highperformancegraphics.org/slides23/2023-06-_HPG_IMG_RayTracing_2.pdf].
{{NavChapitre | book=Les cartes graphiques
| prev=Le multi-GPU
| prevText=Le multi-GPU
}}{{autocat}}
fb0ytjezbn9ldnf64kpgjzwamdgbujp
744331
744330
2025-06-08T17:02:22Z
Mewtow
31375
/* La traversée des structures d'accélérations et des BVH */
744331
wikitext
text/x-wiki
Les cartes graphiques actuelles utilisent la technique de la rastérisation, qui a été décrite en détail dans le chapitre sur les cartes accélératrices 3D. Mais nous avions dit qu'il existe une seconde technique générale pour le rendu 3D, totalement opposée à la rastérisation, appelée le '''lancer de rayons'''. Cette technique a cependant été peu utilisée dans les jeux vidéo, jusqu'à récemment. La raison est que le lancer de rayons demande beaucoup de puissance de calcul, sans compter que créer des cartes accélératrices pour le lancer de rayons n'est pas simple.
Mais les choses commencent à changer. Quelques jeux vidéos récents intègrent des techniques de lancer rayons, pour compléter un rendu effectué principalement en rastérisation. De plus, les cartes graphiques modernes incorporent quelques circuits pour accélérer le lancer de rayons, même s'ils restent marginaux des compléments au rendu par rastérisation. S'il a existé des cartes accélératrices totalement dédiées au rendu en lancer de rayons, elles sont restées confidentielles. Aussi, nous allons nous concentrer sur les cartes graphiques récentes, et allons peu parler des cartes accélératrices dédiées au lancer de rayons.
==Le lancer de rayons==
Le lancer de rayons et la rastérisation. commencent par générer la géométrie de la scène 3D, en plaçant les objets dans la scène 3D, et en effectuant l'étape de transformation des modèles 3D, et les étapes de transformation suivante. Mais les ressemblances s'arrêtent là. Le lancer de rayons effectue l'étape d'éclairage différemment, sans compter qu'il n'a pas besoin de rastérisation.
===Le ''ray-casting'' : des rayons tirés depuis la caméra===
La forme la plus simple de lancer de rayon s'appelle le '''''ray-casting'''''. Elle émet des lignes droites, des '''rayons''' qui partent de la caméra et qui passent chacun par un pixel de l'écran. Les rayons font alors intersecter les différents objets présents dans la scène 3D, en un point d'intersection. Le moteur du jeu détermine alors quel est le point d'intersection le plus proche, ou plus précisément, le sommet le plus proche de ce point d'intersection. Ce sommet est associé à une coordonnée de textures, ce qui permet d'associer directement un texel au pixel associé au rayon.
[[File:Raytrace trace diagram.png|centre|vignette|upright=2|Raycasting, rayon simple.]]
En somme, l'étape de lancer de rayon et le calcul des intersections remplacent l'étape de rasterisation, mais les étapes de traitement de la géométrie et des textures existent encore. Après tout, il faut bien placer les objets dans la scène 3D/2D, faire diverses transformations, les éclairer. On peut gérer la transparence des textures assez simplement, si on connait la transparence sur chaque point d'intersection d'un rayon, information présente dans les textures.
[[File:Anarch short gameplay.gif|vignette|Exemple de rendu en ray-casting 2D dans un jeu vidéo.]]
En soi, cet algorithme est simple, mais il a déjà été utilisé dans pas mal de jeux vidéos. Mais sous une forme simple, en deux dimensions ! Les premiers jeux IdSoftware, dont Wolfenstein 3D et Catacomb, utilisaient cette méthode de rendu, mais dans un univers en deux dimensions. Cet article explique bien cela : [[Les moteurs de rendu des FPS en 2.5 D\Le moteur de Wolfenstein 3D|Le moteur de rendu de Wolfenstein 3D]]. Au passage, si vous faites des recherches sur le ''raycasting'', vous verrez que le terme est souvent utilisé pour désigner la méthode de rendu de ces vieux FPS, alors que ce n'en est qu'un cas particulier.
[[File:Simple raycasting with fisheye correction.gif|centre|vignette|upright=2|Simple raycasting with fisheye correction]]
===Le ''raytracing'' proprement dit===
Le lancer de rayon proprement dit est une forme améliorée de ''raycasting'' dans la gestion de l'éclairage et des ombres est modifiée. Le lancer de rayon calcule les ombres assez simplement, sans recourir à des algorithmes compliqués. L'idée est qu'un point d'intersection est dans l'ombre si un objet se trouve entre lui et une source de lumière. Pour déterminer cela, il suffit de tirer un trait entre les deux et de vérifier s'il y a un obstacle/objet sur le trajet. Si c'est le cas, le point d'intersection n'est pas éclairé par la source de lumière et est donc dans l'ombre. Si ce n'est pas le cas, il est éclairé avec un algorithme d'éclairage.
Le trait tiré entre la source de lumière et le point d'intersection est en soi facile : c'est rayon, identique aux rayons envoyés depuis la caméra. La différence est que ces rayons servent à calculer les ombres, ils sont utilisés pour une raison différente. Il faut donc faire la différence entre les '''rayons primaires''' qui partent de la caméra et passent par un pixel de l'écran, et les '''rayon d'ombrage''' qui servent pour le calcul des ombres.
[[File:Ray trace diagram.svg|centre|vignette|upright=2|Principe du lancer de rayons.]]
Les calculs d'éclairage utilisés pour éclairer/ombrer les points d'intersection vous sont déjà connus : la luminosité est calculée à partir de l'algorithme d'éclairage de Phong, vu dans le chapitre "L'éclairage d'une scène 3D : shaders et T&L". Pour cela, il faut juste récupérer la normale du sommet associé au point d'intersection et l'intensité de la source de lumière, et de calculer les informations manquantes (l'angle normale-rayons de lumière, autres). Il détermine alors la couleur de chaque point d'intersection à partir de tout un tas d'informations.
===Le ''raytracing'' récursif===
[[File:Glasses 800 edit.png|vignette|Image rendue avec le lancer de rayons récursif.]]
La technique de lancer de rayons précédente ne gère pas les réflexions, les reflets, des miroirs, les effets de spécularité, et quelques autres effets graphiques de ce style. Pourtant, ils peuvent être implémentés facilement en modifiant le ''raycasting'' d'une manière très simple.
Il suffit de relancer des rayons à partir du point d'intersection. La direction de ces '''rayons secondaires''' est calculée en utilisant les lois de la réfraction/réflexion vues en physique. De plus, les rayons secondaires peuvent eux-aussi créer des rayons secondaires quand ils sont reflétés/réfractés, etc. La technique est alors appelée du ''lancer de rayons récursif'', qui est souvent simplement appelée "lancer de rayons".
[[File:Recursive raytracing.svg|centre|vignette|upright=2|Lancer de rayon récursif.]]
===Les avantages et désavantages comparé à la rastérisation===
L'avantage principal du lancer de rayons est son rendu de l'éclairage, qui est plus réaliste. Les ombres se calculent naturellement avec cette méthode de rendu, là où elles demandent des ruses comme des lightmaps, des textures pré-éclairées, divers algorithmes d'éclairage géométriques, etc. Les réflexions et la réfraction sont gérées naturellement par le lancer de rayon récursif, alors qu'elles demandent des ruses de sioux pour obtenir un résultat correct avec la rastérisation.
[[File:ViewFrustum.svg|vignette|upright=1|Volume délimité par la caméra (''view frustum'').]]
Pour ce qui est des performances théoriques, le lancer de rayons se débrouille mieux sur un point : l'élimination des pixels/surfaces cachés. La rastérisation a tendance à calculer inutilement des portions non-rendues de la scène 3D, et doit utiliser des techniques de ''culling'' ou de ''clipping'' pour éviter trop de calculs inutiles. Ces techniques sont très puissantes, mais imparfaites. De nombreux fragments/pixels calculés sont éliminés à la toute fin du pipeline, grâce au z-buffer, après avoir été calculés et texturés. Le lancer de rayons se passe totalement de ces techniques d'élimination des pixels cachés, car elle ne calcule pas les portions invisibles de l'image par construction : pas besoin de ''culling'', de ''clipping'', ni même de z-buffer.
Mais tous ces avantages sont compensés par le fait que le lancer de rayons est plus lent sur un paquet d'autres points. Déjà, les calculs d'intersection sont très lourds, ils demandent beaucoup de calculs et d'opérations arithmétiques, plus que pour l'équivalent en rastérisation. Ensuite, de nombreuses optimisations présentes en rastérisation ne sont pas possibles. Notamment, le lancer de rayon utilise assez mal la mémoire, dans le sens où les accès en mémoire vidéo sont complétement désorganisés, là où le rendu 3D a des accès plus linéaires qui permettent d'utiliser des mémoires caches.
==Les optimisations du lancer de rayons liées aux volumes englobants==
Les calculs d'intersections sont très gourmands en puissance de calcul. Sans optimisation, on doit tester l'intersection de chaque rayon avec chaque triangle. Mais diverses optimisations permettent d'économiser des calculs. Elles consistent à regrouper plusieurs triangles ensemble pour rejeter des paquets de triangles en une fois. Pour cela, la carte graphique utilise des '''structures d'accélération''', qui mémorisent les regroupements de triangles, et parfois les triangles eux-mêmes.
===Les volumes englobants===
[[File:BoundingBox.jpg|vignette|Objet englobant : la statue est englobée dans un pavé.]]
L'idée est d'englober chaque objet par un pavé appelé un ''volume englobant''. Le tout est illustré ci-contre, avec une statue représentée en 3D. La statue est un objet très complexe, contenant plusieurs centaines ou milliers de triangles, ce qui fait que tester l'intersection d'un rayon avec chaque triangle serait très long. Par contre, on peut tester si le rayon intersecte le volume englobant facilement : il suffit de tester les 6 faces du pavé, soit 12 triangles, pas plus. S'il n'y a pas d'intersection, alors on économise plusieurs centaines ou milliers de tests d'intersection. Par contre, s'il y a intersection, on doit vérifier chaque triangle. Vu que les rayons intersectent souvent peu d'objets, le gain est énorme !
L'usage seul de volumes englobant est une optimisation très performante. Au lieu de tester l'intersection avec chaque triangle, on teste l'intersection avec chaque objet, puis l'intersection avec chaque triangle quand on intersecte chaque volume englobant. On divise le nombre de tests par un facteur quasi-constant, mais de très grande valeur.
Il faut noter que les calculs d'intersection sont légèrement différents entre un triangle et un volume englobant. Il faut dire que les volumes englobant sont généralement des pavées, ils utilisent des rectangles, etc. Les différences sont cependant minimales.
===Les hiérarchies de volumes englobants===
Mais on peut faire encore mieux. L'idée est de regrouper plusieurs volumes englobants en un seul. Si une dizaine d'objets sont proches, leurs volumes englobants seront proches. Il est alors utile d'englober leurs volumes englobants dans un super-volume englobant. L'idée est que l'on teste d'abord le super-volume englobant, au lieu de tester la dizaine de volumes englobants de base. S'il n'y a pas d'intersection, alors on a économisé une dizaine de tests. Mais si intersection, il y a, alors on doit vérifier chaque sous-volume englobant de base, jusqu'à tomber sur une intersection. Vu que les intersections sont rares, on y gagne plus qu'on y perd.
Et on peut faire la même chose avec les super-volumes englobants, en les englobant dans des volumes englobants encore plus grands, et ainsi de suite, récursivement. On obtient alors une '''hiérarchie de volumes englobants''', qui part d'un volume englobant qui contient toute la géométrie, hors skybox, qui lui-même regroupe plusieurs volumes englobants, qui eux-mêmes...
[[File:Example of bounding volume hierarchy.svg|centre|vignette|upright=2|Hiérarchie de volumes englobants.]]
Le nombre de tests d'intersection est alors grandement réduit. On passe d'un nombre de tests proportionnel aux nombres d'objets à un nombre proportionnel à son logarithme. Plus la scène contient d'objets, plus l'économie est importante. La seule difficulté est de générer la hiérarchie de volumes englobants à partir d'une scène 3D. Divers algorithmes assez rapides existent pour cela, ils créent des volumes englobants différents. Les volumes englobants les plus utilisés dans les cartes 3D sont les '''''axis-aligned bounding boxes (AABB)'''''.
La hiérarchie est mémorisée en mémoire RAM, dans une structure de données que les programmeurs connaissent sous le nom d'arbre, et précisément un arbre binaire ou du moins d'un arbre similaire (''k-tree''). Traverser cet arbre pour passer d'un objet englobant à un autre plus petit est très simple, mais a un défaut : on saute d'on objet à un autre en mémoire, les deux sont souvent éloignés en mémoire. La traversée de la mémoire est erratique, sautant d'un point à un autre. On n'est donc dans un cas où les caches fonctionnent mal, ou les techniques de préchargement échouent, où la mémoire devient un point bloquant car trop lente.
===La cohérence des rayons===
Les rayons primaires, émis depuis la caméra, sont proches les uns des autres, et vont tous dans le même sens. Mais ce n'est pas le cas pour des rayons secondaires. Les objets d'une scène 3D ont rarement des surfaces planes, mais sont composés d'un tas de triangles qui font un angle entre eux. La conséquence est que deux rayons secondaires émis depuis deux triangles voisins peuvent aller dans des directions très différentes. Ils vont donc intersecter des objets très différents, atterrir sur des sources de lumières différentes, etc. De tels rayons sont dits '''incohérents''', en opposition aux rayons cohérents qui sont des rayons proches qui vont dans la même direction.
Les rayons incohérents sont peu fréquents avec le ''rayctracing'' récursif basique, mais deviennent plus courants avec des techniques avancées comme le ''path tracing'' ou les techniques d'illumination globale. En soi, la présende de rayons incohérents n'est pas un problème et est parfaitement normale. Le problème est que le traitement des rayons incohérent est plus lent que pour les rayons cohérents. Le traitement de deux rayons secondaires voisins demande d'accéder à des données différentes, ce qui donne des accès mémoire très différents et très éloignés. On ne peut pas profiter des mémoires caches ou des optimisations de la hiérarchie mémoire, si on les traite consécutivement. Un autre défaut est qu'une même instance de ''pixels shaders'' va traiter plusieurs rayons en même temps, grâce au SIMD. Mais les branchements n'auront pas les mêmes résultats d'un rayon à l'autre, et cette divergence entrainera des opérations de masquage et de branchement très couteuses.
Pour éviter cela, les GPU modernes permettent de trier les rayons en fonction de leur direction et de leur origine. Ils traitent les rayons non dans l'ordre usuel, mais essayent de regrouper des rayons proches qui vont dans la même direction, et de les traiter ensemble, en parallèle, ou l'un après l'autre. Cela ne change rien au rendu final, qui traite les rayons en parallèle. Ainsi, les données chargées dans le cache par le premier rayon seront celles utilisées pour les rayons suivants, ce qui donne un gain de performance appréciable. De plus, cela évite d'utiliser des branchements dans les ''pixels shaders''. Les méthodes de '''tri de rayons''' sont nombreuses, aussi en faire une liste exhaustive serait assez long, sans compter qu'on ne sait pas quelles sont celles implémentées en hardware, ni commetn elles le sont.
==Le matériel pour accélérer le lancer de rayons==
Le lancer de rayons a toujours besoin de calculer la géométrie, d'appliquer des textures et de faire des calculs d'éclairage. Sachant cela, beaucoup de chercheurs se sont dit qu'il n'était pas nécessaire d'utiliser du matériel spécialisé pour le lancer de rayons, et qu'utiliser les GPU actuels était suffisant. En théorie, il est possible d'utiliser des ''shaders'' pour effectuer du lancer de rayons, mais la technique n'est pas très performante.
Une carte graphique spécialement dédiée au lancer de rayons est donc quasiment identique à une carte graphique normale. Les deux contiennent des unités de texture et des processeurs de ''shaders'', des unités géométriques, un ''input assembler'', et tout ce qui va avec. Seuls les circuits de rasterisation et le z-buffer sont remplacés par des circuits dédiés au lancer de rayon, à savoir des unités de génération des rayons et des unités pour les calculs d'intersection. D'ailleurs, il est aussi possible d'ajouter des circuits de génération/intersection de rayons à une carte graphique existante.
Au niveau matériel, la gestion de la mémoire est un peu plus simple. Le lancer de rayon n'écrit que dans le ''framebuffer'' et n'a pas besoin de z-buffer, ce qui a beaucoup d'avantages. Notamment, les caches sont en lecture seule, leurs circuits sont donc assez simples et performants, les problèmes de cohérence des caches disparaissent. L'absence de z-buffer fait que de nombreuses écritures/lectures dans le ''framebuffer'' sont économisées. Les lectures et écritures de textures sont tout aussi fréquentes qu'avec la rasterisation, et sont même plus faible en principe car de nombreux effets de lumières complexes sont calculés avec le lancer de rayons, alors qu'ils doivent être précalculés dans des textures et lus par les shaders.
===Les circuits spécialisés pour les calculs liés aux rayons===
Toute la subtilité du lancer de rayons est de générer les rayons et de déterminer quels triangles ils intersectent. La seule difficulté est de gérer la transparence, mais aussi et surtout la traversée de la BVH. En soit, générer les rayons et déterminer leurs intersections n'est pas compliqué. Il existe des algorithmes basés sur du calcul vectoriel pour déterminer si intersection il y a et quelles sont ses coordonnées. C'est toute la partie de parcours de la BVH qui est plus compliquée à implémenter : faire du ''pointer chasing'' en hardware n'est pas facile.
Et cela se ressent quand on étudie comment les GPU récents gèrent le lancer de rayons. Ils utilisent des shaders dédiés, qui communiquent avec une '''unité de lancer de rayon''' dédiée à la traversée de la BVH. Le terme anglais est ''Ray-tracing Unit'', ce qui fait que nous utiliseront l'abréviation RTU pour la désigner. Les shaders spécialisés sont des shaders de lancer de rayon, qui s'occupent de générer les rayons, mais aussi de faire tous les calculs une fois qu'une intersection est détectée. Le processus est le suivant :
* En premier lieu, les shaders de lancer de rayon génèrent les rayons lancés.
* Ensuite, ils laissent la main à l'unité de lancer de rayon. Elle parcours la BVH et effectue les calculs d'intersection. C'est elle qui détermine quels triangles intersectent un rayon.
* A chaque fois que la RTU détecte une intersection, elle envoie son résultat au ''shader'' de lancer de rayon, qui reprend la main et finit le travail. Lors de cette étape, il peut générer un nouveau rayon, et le processus recommence.
La génération des rayons a donc lieu dans les processeur de ''shaders'', avec cependant une petite subtilité quant aux rayons secondaires. La génération des rayons primaires est triviale, mais la génération des rayons d'ombrage et des rayons secondaires est par contre plus complexe. Les rayons d'ombrage et secondaires sont générés à partir du résultat des intersections des rayons précédents. Et dans les faits, ce sont les ''shaders'' qui s'occupent de générer les rayons secondaires. Suivant la nature de la surface (opaque, transparente, réfléchissante, mate, autre), ils décident s'il faut ou non émettre un rayon secondaire, et génère ce rayon s'il le faut. Le rayon est alors envoyé aux unités de traversée et d'intersection.
====La traversée des structures d'accélérations et des BVH====
Lorsqu'un processeur de shader fait appel à la RTU, il lui envoie un rayon encodé d'une manière ou d'une autre, potentiellement différente d'un GPU à l'autre. Toujours est-il que les informations sur ce rayon sont mémorisée dans des registres à l'intérieur de la RTU. Ce n'est que quand le rayon quitte la RTU que ces registres sont réinitialisé pour laisser la palce à un autre rayon.
La RTU contient beaucoup d'unités de calcul pour effectuer les calculs d'intersections. Il est possible de tester un grand nombre d'intersections de triangles en parallèles, chacun dans une unité de calcul séparée. L'algorithme de lancer de rayons se parallélise donc très bien et la RTU en profite. En soi, les circuits de détection des intersections sont très simples et se résument à un paquet de circuits de calcul (addition, multiplications, division, autres), connectés les uns aux autres. Il y a assez peu à dire dessus. Mais les autres circuits sont très intéressants à étudier.
Il y a deux types d'intersections à calculer : les intersections avec les volumes englobants, les intersections avec les triangles. Volumes englobants et triangles ne sont pas encodés de la même manière en mémoire vidéo, ce qui fait que les calculs à faire ne sont pas exactement les mêmes. Et c'est normal : il y a une différence entre un pavé pour le volume englobant et trois sommets/vecteurs pour un triangle. La RTU des GPU Intel, et vraisemblablement celle des autres GPU, utilise des circuits de calcul différents pour les deux. Elle incorpore plus de circuits pour les intersections avec les volumes englobants, que de circuits pour les intersections avec un triangle. Il faut dire que lors de la traversée d'une BVH, il y a une intersection avec un triangle par rayon, mais plusieurs pour les volumes englobants.
L'intérieur de la RTU contient de quoi séquencer les accès mémoire nécessaires pour parcourir la BVH. Et le problème est que les BVH se marient assez mal avec la hiérarchie mémoire des GPU et CPU modernes. Ce sont des structures de données qui dispersent les données en mémoire, là où les GPU préfèrent des structures de données qui forment un seul bloc en RAM. Traverser un BVH demande de faire des sauts en mémoire RAM, et ce sont des accès mémoire imprévisibles que l'on ne peut pas optimiser. Pour limiter la casse, les RTU intègrent des caches pour mémoriser des portions de la BVH, au cas où celles-ci seraient retraversées plusieurs fois de suite par des rayons consécutifs. Mais ceux-ci ont un impact plus léger sur les performances.
L'autre raison, très liée à la précédente, est que traverser un BVH pour trouver le triangle intersectant demande d'effectuer beaucoup de branchements. On doit tester l'intersection avec un volume englobant, puis décider s'il faut passer au suivant, et si oui lequel, et rebelotte. Et dans du code informatique, cela demande beaucoup de IF...ELSE, de branchements, de tests de conditions, etc. Et les cartes graphiques sont assez mauvaises à ça. Les ''shaders'' peuvent en faire, mais sont très lents pour ces opérations. Pour diminuer l’impact sur les performances, les cartes graphiques modernes incorporent des circuits de tri pour regrouper les rayons cohérents, ceux qui vont dans la même direction et proviennent de triangles proches. Ce afin d'implémenter les optimisations vues plus haut.
====La génération des structures d'accélération et BVH====
La plupart des cartes graphiques ne peuvent pas générer les BVH d'elles-mêmes. Pareil pour les autres structures d'accélération. Elles sont calculées par le processeur, stockées en mémoire RAM, puis copiées dans la mémoire vidéo avant le démarrage du rendu 3D. Cependant, quelques rares cartes spécialement dédiées au lancer de rayons incorporent des circuits pour générer les BVH/AS. Elles lisent le tampon de sommet envoyé par le processeur, puis génèrent les BVH complémentaires. L'unité de génération des structures d'accélération est complétement séparée des autres unités. Un exemple d'architecture de ce type est l'architecture Raycore, dont nous parlerons dans les sections suivantes.
Cette unité peut aussi modifier les BVH à la volée, si jamais la scène 3D change. Par exemple, si un objet change de place, comme un NPC qui se déplace, il faut reconstruire le BVH. Les cartes graphiques récentes évitent de reconstruire le BVH de zéro, mais se contentent de modifier ce qui a changé dans le BVH. Les performances en sont nettement meilleures.
===Les cartes graphiques dédiées au lancer de rayon===
Les premières cartes accélératrices de lancer de rayons sont assez anciennes et datent des années 80-90. Leur évolution a plus ou moins suivi la même évolution que celle des cartes graphiques usuelles, sauf que très peu de cartes pour le lancer de rayons ont été produites. Par même évolution, on veut dire que les cartes graphiques pour le lancer de rayon ont commencé par tester deux solutions évidentes et extrêmes : les cartes basées sur des circuits programmables d'un côté, non programmables de l'autre.
La première carte pour le lancer de rayons était la TigerShark, et elle était tout simplement composée de plusieurs processeurs et de la mémoire sur une carte PCI. Elle ne faisait qu'accélérer le calcul des intersections, rien de plus.
Les autres cartes effectuaient du rendu 3D par voxel, un type de rendu 3D assez spécial que nous n'avons pas abordé jusqu'à présent, dont l'algorithme de lancer de rayons n'était qu'une petite partie du rendu. Elles étaient destinées au marché scientifique, industriel et médical. On peut notamment citer la VolumePro et la VIZARD et II. Les deux étaient des cartes pour bus PCI qui ne faisaient que du ''raycasting'' et n'utilisaient pas de rayons d'ombrage. Le ''raycasting'' était exécuté sur un processeur dédié sur la VIZARD II, sur un circuit fixe implémenté par un FPGA sur la Volume Pro Voici différents papiers académiques qui décrivent l'architecture de ces cartes accélératrices :
* [https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=ccda3712ba0e6575cd08025f3bb920de46201cac The VolumePro Real-Time Ray-Casting System].
* [https://www.researchgate.net/publication/234829060_VIZARD_II_A_reconfigurable_interactive_volume_rendering_system VIZARD II: A reconfigurable interactive volume rendering system]
La puce SaarCOR (Saarbrücken's Coherence Optimized Ray Tracer) et bien plus tard par la carte Raycore, étaient deux cartes réelement dédiées au raycasting pur, sans usage de voxels, et étaient basées sur des FPGA. Elles contenaient uniquement des circuits pour accélérer le lancer de rayon proprement dit, à savoir la génération des rayons, les calculs d'intersection, pas plus. Tout le reste, à savoir le rendu de la géométrie, le placage de textures, les ''shaders'' et autres, étaient effectués par le processeur. Voici des papiers académiques sur leur architecture :
* [https://gamma.cs.unc.edu/SATO/Raycore/raycore.pdf RayCore: A ray-tracing hardware architecture for mobile devices].
Le successeur de la SaarCOR, le Ray Processing Unit (RPU), était une carte hybride : c'était une SaarCOR basée sur des circuits fixes, qui gagna quelques possibilités de programmation. Elle ajoutait des processeurs de ''shaders'' aux circuits fixes spécialisés pour le lancer de rayons. Les autres cartes du genre faisaient pareil, et on peut citer les cartes ART, les cartes CausticOne, Caustic Professional's R2500 et R2100.
Les cartes 3D modernes permettent de faire à la fois de la rasterisation et du lancer de rayons. Pour cela, les GPU récents incorporent des unités pour effectuer des calculs d'intersection, qui sont réalisés dans des circuits spécialisés. Elles sont appelées des RT Cores sur les cartes NVIDIA, mais les cartes AMD et Intel ont leur équivalent, idem chez leurs concurrents de chez Imagination technologies, ainsi que sur certains GPU destinés au marché mobile. Peu de choses sont certaines sur ces unités, mais il semblerait qu'il s'agisse d'unités de textures modifiées.
De ce qu'on en sait, certains GPU utilisent des unités pour calculer les intersections avec les triangles, et d'autres unités séparées pour calculer les intersections avec les volumes englobants. La raison est que, comme dit plus haut, les algorithmes de calcul d'intersection sont différents dans les deux cas. Les algorithmes utilisés ne sont pas connus pour toutes les cartes graphiques. On sait que les GPU Wizard de Imagination technology utilisaient des tests AABB de Plücker. Ils utilisaient 15 circuits de multiplication, 9 additionneurs-soustracteurs, quelques circuits pour tester la présence dans un intervalle, des circuits de normalisation et arrondi. L'algorithme pour leurs GPU d'architecture Photon est disponible ici, pour les curieux : [https://www.highperformancegraphics.org/slides23/2023-06-_HPG_IMG_RayTracing_2.pdf].
{{NavChapitre | book=Les cartes graphiques
| prev=Le multi-GPU
| prevText=Le multi-GPU
}}{{autocat}}
im79fw02ru55a3qwj46xip6pf5ir9wq
744332
744331
2025-06-08T17:07:18Z
Mewtow
31375
/* Les circuits spécialisés pour les calculs liés aux rayons */
744332
wikitext
text/x-wiki
Les cartes graphiques actuelles utilisent la technique de la rastérisation, qui a été décrite en détail dans le chapitre sur les cartes accélératrices 3D. Mais nous avions dit qu'il existe une seconde technique générale pour le rendu 3D, totalement opposée à la rastérisation, appelée le '''lancer de rayons'''. Cette technique a cependant été peu utilisée dans les jeux vidéo, jusqu'à récemment. La raison est que le lancer de rayons demande beaucoup de puissance de calcul, sans compter que créer des cartes accélératrices pour le lancer de rayons n'est pas simple.
Mais les choses commencent à changer. Quelques jeux vidéos récents intègrent des techniques de lancer rayons, pour compléter un rendu effectué principalement en rastérisation. De plus, les cartes graphiques modernes incorporent quelques circuits pour accélérer le lancer de rayons, même s'ils restent marginaux des compléments au rendu par rastérisation. S'il a existé des cartes accélératrices totalement dédiées au rendu en lancer de rayons, elles sont restées confidentielles. Aussi, nous allons nous concentrer sur les cartes graphiques récentes, et allons peu parler des cartes accélératrices dédiées au lancer de rayons.
==Le lancer de rayons==
Le lancer de rayons et la rastérisation. commencent par générer la géométrie de la scène 3D, en plaçant les objets dans la scène 3D, et en effectuant l'étape de transformation des modèles 3D, et les étapes de transformation suivante. Mais les ressemblances s'arrêtent là. Le lancer de rayons effectue l'étape d'éclairage différemment, sans compter qu'il n'a pas besoin de rastérisation.
===Le ''ray-casting'' : des rayons tirés depuis la caméra===
La forme la plus simple de lancer de rayon s'appelle le '''''ray-casting'''''. Elle émet des lignes droites, des '''rayons''' qui partent de la caméra et qui passent chacun par un pixel de l'écran. Les rayons font alors intersecter les différents objets présents dans la scène 3D, en un point d'intersection. Le moteur du jeu détermine alors quel est le point d'intersection le plus proche, ou plus précisément, le sommet le plus proche de ce point d'intersection. Ce sommet est associé à une coordonnée de textures, ce qui permet d'associer directement un texel au pixel associé au rayon.
[[File:Raytrace trace diagram.png|centre|vignette|upright=2|Raycasting, rayon simple.]]
En somme, l'étape de lancer de rayon et le calcul des intersections remplacent l'étape de rasterisation, mais les étapes de traitement de la géométrie et des textures existent encore. Après tout, il faut bien placer les objets dans la scène 3D/2D, faire diverses transformations, les éclairer. On peut gérer la transparence des textures assez simplement, si on connait la transparence sur chaque point d'intersection d'un rayon, information présente dans les textures.
[[File:Anarch short gameplay.gif|vignette|Exemple de rendu en ray-casting 2D dans un jeu vidéo.]]
En soi, cet algorithme est simple, mais il a déjà été utilisé dans pas mal de jeux vidéos. Mais sous une forme simple, en deux dimensions ! Les premiers jeux IdSoftware, dont Wolfenstein 3D et Catacomb, utilisaient cette méthode de rendu, mais dans un univers en deux dimensions. Cet article explique bien cela : [[Les moteurs de rendu des FPS en 2.5 D\Le moteur de Wolfenstein 3D|Le moteur de rendu de Wolfenstein 3D]]. Au passage, si vous faites des recherches sur le ''raycasting'', vous verrez que le terme est souvent utilisé pour désigner la méthode de rendu de ces vieux FPS, alors que ce n'en est qu'un cas particulier.
[[File:Simple raycasting with fisheye correction.gif|centre|vignette|upright=2|Simple raycasting with fisheye correction]]
===Le ''raytracing'' proprement dit===
Le lancer de rayon proprement dit est une forme améliorée de ''raycasting'' dans la gestion de l'éclairage et des ombres est modifiée. Le lancer de rayon calcule les ombres assez simplement, sans recourir à des algorithmes compliqués. L'idée est qu'un point d'intersection est dans l'ombre si un objet se trouve entre lui et une source de lumière. Pour déterminer cela, il suffit de tirer un trait entre les deux et de vérifier s'il y a un obstacle/objet sur le trajet. Si c'est le cas, le point d'intersection n'est pas éclairé par la source de lumière et est donc dans l'ombre. Si ce n'est pas le cas, il est éclairé avec un algorithme d'éclairage.
Le trait tiré entre la source de lumière et le point d'intersection est en soi facile : c'est rayon, identique aux rayons envoyés depuis la caméra. La différence est que ces rayons servent à calculer les ombres, ils sont utilisés pour une raison différente. Il faut donc faire la différence entre les '''rayons primaires''' qui partent de la caméra et passent par un pixel de l'écran, et les '''rayon d'ombrage''' qui servent pour le calcul des ombres.
[[File:Ray trace diagram.svg|centre|vignette|upright=2|Principe du lancer de rayons.]]
Les calculs d'éclairage utilisés pour éclairer/ombrer les points d'intersection vous sont déjà connus : la luminosité est calculée à partir de l'algorithme d'éclairage de Phong, vu dans le chapitre "L'éclairage d'une scène 3D : shaders et T&L". Pour cela, il faut juste récupérer la normale du sommet associé au point d'intersection et l'intensité de la source de lumière, et de calculer les informations manquantes (l'angle normale-rayons de lumière, autres). Il détermine alors la couleur de chaque point d'intersection à partir de tout un tas d'informations.
===Le ''raytracing'' récursif===
[[File:Glasses 800 edit.png|vignette|Image rendue avec le lancer de rayons récursif.]]
La technique de lancer de rayons précédente ne gère pas les réflexions, les reflets, des miroirs, les effets de spécularité, et quelques autres effets graphiques de ce style. Pourtant, ils peuvent être implémentés facilement en modifiant le ''raycasting'' d'une manière très simple.
Il suffit de relancer des rayons à partir du point d'intersection. La direction de ces '''rayons secondaires''' est calculée en utilisant les lois de la réfraction/réflexion vues en physique. De plus, les rayons secondaires peuvent eux-aussi créer des rayons secondaires quand ils sont reflétés/réfractés, etc. La technique est alors appelée du ''lancer de rayons récursif'', qui est souvent simplement appelée "lancer de rayons".
[[File:Recursive raytracing.svg|centre|vignette|upright=2|Lancer de rayon récursif.]]
===Les avantages et désavantages comparé à la rastérisation===
L'avantage principal du lancer de rayons est son rendu de l'éclairage, qui est plus réaliste. Les ombres se calculent naturellement avec cette méthode de rendu, là où elles demandent des ruses comme des lightmaps, des textures pré-éclairées, divers algorithmes d'éclairage géométriques, etc. Les réflexions et la réfraction sont gérées naturellement par le lancer de rayon récursif, alors qu'elles demandent des ruses de sioux pour obtenir un résultat correct avec la rastérisation.
[[File:ViewFrustum.svg|vignette|upright=1|Volume délimité par la caméra (''view frustum'').]]
Pour ce qui est des performances théoriques, le lancer de rayons se débrouille mieux sur un point : l'élimination des pixels/surfaces cachés. La rastérisation a tendance à calculer inutilement des portions non-rendues de la scène 3D, et doit utiliser des techniques de ''culling'' ou de ''clipping'' pour éviter trop de calculs inutiles. Ces techniques sont très puissantes, mais imparfaites. De nombreux fragments/pixels calculés sont éliminés à la toute fin du pipeline, grâce au z-buffer, après avoir été calculés et texturés. Le lancer de rayons se passe totalement de ces techniques d'élimination des pixels cachés, car elle ne calcule pas les portions invisibles de l'image par construction : pas besoin de ''culling'', de ''clipping'', ni même de z-buffer.
Mais tous ces avantages sont compensés par le fait que le lancer de rayons est plus lent sur un paquet d'autres points. Déjà, les calculs d'intersection sont très lourds, ils demandent beaucoup de calculs et d'opérations arithmétiques, plus que pour l'équivalent en rastérisation. Ensuite, de nombreuses optimisations présentes en rastérisation ne sont pas possibles. Notamment, le lancer de rayon utilise assez mal la mémoire, dans le sens où les accès en mémoire vidéo sont complétement désorganisés, là où le rendu 3D a des accès plus linéaires qui permettent d'utiliser des mémoires caches.
==Les optimisations du lancer de rayons liées aux volumes englobants==
Les calculs d'intersections sont très gourmands en puissance de calcul. Sans optimisation, on doit tester l'intersection de chaque rayon avec chaque triangle. Mais diverses optimisations permettent d'économiser des calculs. Elles consistent à regrouper plusieurs triangles ensemble pour rejeter des paquets de triangles en une fois. Pour cela, la carte graphique utilise des '''structures d'accélération''', qui mémorisent les regroupements de triangles, et parfois les triangles eux-mêmes.
===Les volumes englobants===
[[File:BoundingBox.jpg|vignette|Objet englobant : la statue est englobée dans un pavé.]]
L'idée est d'englober chaque objet par un pavé appelé un ''volume englobant''. Le tout est illustré ci-contre, avec une statue représentée en 3D. La statue est un objet très complexe, contenant plusieurs centaines ou milliers de triangles, ce qui fait que tester l'intersection d'un rayon avec chaque triangle serait très long. Par contre, on peut tester si le rayon intersecte le volume englobant facilement : il suffit de tester les 6 faces du pavé, soit 12 triangles, pas plus. S'il n'y a pas d'intersection, alors on économise plusieurs centaines ou milliers de tests d'intersection. Par contre, s'il y a intersection, on doit vérifier chaque triangle. Vu que les rayons intersectent souvent peu d'objets, le gain est énorme !
L'usage seul de volumes englobant est une optimisation très performante. Au lieu de tester l'intersection avec chaque triangle, on teste l'intersection avec chaque objet, puis l'intersection avec chaque triangle quand on intersecte chaque volume englobant. On divise le nombre de tests par un facteur quasi-constant, mais de très grande valeur.
Il faut noter que les calculs d'intersection sont légèrement différents entre un triangle et un volume englobant. Il faut dire que les volumes englobant sont généralement des pavées, ils utilisent des rectangles, etc. Les différences sont cependant minimales.
===Les hiérarchies de volumes englobants===
Mais on peut faire encore mieux. L'idée est de regrouper plusieurs volumes englobants en un seul. Si une dizaine d'objets sont proches, leurs volumes englobants seront proches. Il est alors utile d'englober leurs volumes englobants dans un super-volume englobant. L'idée est que l'on teste d'abord le super-volume englobant, au lieu de tester la dizaine de volumes englobants de base. S'il n'y a pas d'intersection, alors on a économisé une dizaine de tests. Mais si intersection, il y a, alors on doit vérifier chaque sous-volume englobant de base, jusqu'à tomber sur une intersection. Vu que les intersections sont rares, on y gagne plus qu'on y perd.
Et on peut faire la même chose avec les super-volumes englobants, en les englobant dans des volumes englobants encore plus grands, et ainsi de suite, récursivement. On obtient alors une '''hiérarchie de volumes englobants''', qui part d'un volume englobant qui contient toute la géométrie, hors skybox, qui lui-même regroupe plusieurs volumes englobants, qui eux-mêmes...
[[File:Example of bounding volume hierarchy.svg|centre|vignette|upright=2|Hiérarchie de volumes englobants.]]
Le nombre de tests d'intersection est alors grandement réduit. On passe d'un nombre de tests proportionnel aux nombres d'objets à un nombre proportionnel à son logarithme. Plus la scène contient d'objets, plus l'économie est importante. La seule difficulté est de générer la hiérarchie de volumes englobants à partir d'une scène 3D. Divers algorithmes assez rapides existent pour cela, ils créent des volumes englobants différents. Les volumes englobants les plus utilisés dans les cartes 3D sont les '''''axis-aligned bounding boxes (AABB)'''''.
La hiérarchie est mémorisée en mémoire RAM, dans une structure de données que les programmeurs connaissent sous le nom d'arbre, et précisément un arbre binaire ou du moins d'un arbre similaire (''k-tree''). Traverser cet arbre pour passer d'un objet englobant à un autre plus petit est très simple, mais a un défaut : on saute d'on objet à un autre en mémoire, les deux sont souvent éloignés en mémoire. La traversée de la mémoire est erratique, sautant d'un point à un autre. On n'est donc dans un cas où les caches fonctionnent mal, ou les techniques de préchargement échouent, où la mémoire devient un point bloquant car trop lente.
===La cohérence des rayons===
Les rayons primaires, émis depuis la caméra, sont proches les uns des autres, et vont tous dans le même sens. Mais ce n'est pas le cas pour des rayons secondaires. Les objets d'une scène 3D ont rarement des surfaces planes, mais sont composés d'un tas de triangles qui font un angle entre eux. La conséquence est que deux rayons secondaires émis depuis deux triangles voisins peuvent aller dans des directions très différentes. Ils vont donc intersecter des objets très différents, atterrir sur des sources de lumières différentes, etc. De tels rayons sont dits '''incohérents''', en opposition aux rayons cohérents qui sont des rayons proches qui vont dans la même direction.
Les rayons incohérents sont peu fréquents avec le ''rayctracing'' récursif basique, mais deviennent plus courants avec des techniques avancées comme le ''path tracing'' ou les techniques d'illumination globale. En soi, la présende de rayons incohérents n'est pas un problème et est parfaitement normale. Le problème est que le traitement des rayons incohérent est plus lent que pour les rayons cohérents. Le traitement de deux rayons secondaires voisins demande d'accéder à des données différentes, ce qui donne des accès mémoire très différents et très éloignés. On ne peut pas profiter des mémoires caches ou des optimisations de la hiérarchie mémoire, si on les traite consécutivement. Un autre défaut est qu'une même instance de ''pixels shaders'' va traiter plusieurs rayons en même temps, grâce au SIMD. Mais les branchements n'auront pas les mêmes résultats d'un rayon à l'autre, et cette divergence entrainera des opérations de masquage et de branchement très couteuses.
Pour éviter cela, les GPU modernes permettent de trier les rayons en fonction de leur direction et de leur origine. Ils traitent les rayons non dans l'ordre usuel, mais essayent de regrouper des rayons proches qui vont dans la même direction, et de les traiter ensemble, en parallèle, ou l'un après l'autre. Cela ne change rien au rendu final, qui traite les rayons en parallèle. Ainsi, les données chargées dans le cache par le premier rayon seront celles utilisées pour les rayons suivants, ce qui donne un gain de performance appréciable. De plus, cela évite d'utiliser des branchements dans les ''pixels shaders''. Les méthodes de '''tri de rayons''' sont nombreuses, aussi en faire une liste exhaustive serait assez long, sans compter qu'on ne sait pas quelles sont celles implémentées en hardware, ni commetn elles le sont.
==Le matériel pour accélérer le lancer de rayons==
Le lancer de rayons a toujours besoin de calculer la géométrie, d'appliquer des textures et de faire des calculs d'éclairage. Sachant cela, beaucoup de chercheurs se sont dit qu'il n'était pas nécessaire d'utiliser du matériel spécialisé pour le lancer de rayons, et qu'utiliser les GPU actuels était suffisant. En théorie, il est possible d'utiliser des ''shaders'' pour effectuer du lancer de rayons, mais la technique n'est pas très performante.
Une carte graphique spécialement dédiée au lancer de rayons est donc quasiment identique à une carte graphique normale. Les deux contiennent des unités de texture et des processeurs de ''shaders'', des unités géométriques, un ''input assembler'', et tout ce qui va avec. Seuls les circuits de rasterisation et le z-buffer sont remplacés par des circuits dédiés au lancer de rayon, à savoir des unités de génération des rayons et des unités pour les calculs d'intersection. D'ailleurs, il est aussi possible d'ajouter des circuits de génération/intersection de rayons à une carte graphique existante.
Au niveau matériel, la gestion de la mémoire est un peu plus simple. Le lancer de rayon n'écrit que dans le ''framebuffer'' et n'a pas besoin de z-buffer, ce qui a beaucoup d'avantages. Notamment, les caches sont en lecture seule, leurs circuits sont donc assez simples et performants, les problèmes de cohérence des caches disparaissent. L'absence de z-buffer fait que de nombreuses écritures/lectures dans le ''framebuffer'' sont économisées. Les lectures et écritures de textures sont tout aussi fréquentes qu'avec la rasterisation, et sont même plus faible en principe car de nombreux effets de lumières complexes sont calculés avec le lancer de rayons, alors qu'ils doivent être précalculés dans des textures et lus par les shaders.
===Les circuits spécialisés pour les calculs liés aux rayons===
Toute la subtilité du lancer de rayons est de générer les rayons et de déterminer quels triangles ils intersectent. La seule difficulté est de gérer la transparence, mais aussi et surtout la traversée de la BVH. En soit, générer les rayons et déterminer leurs intersections n'est pas compliqué. Il existe des algorithmes basés sur du calcul vectoriel pour déterminer si intersection il y a et quelles sont ses coordonnées. C'est toute la partie de parcours de la BVH qui est plus compliquée à implémenter : faire du ''pointer chasing'' en hardware n'est pas facile.
Et cela se ressent quand on étudie comment les GPU récents gèrent le lancer de rayons. Ils utilisent des shaders dédiés, qui communiquent avec une '''unité de lancer de rayon''' dédiée à la traversée de la BVH. Le terme anglais est ''Ray-tracing Unit'', ce qui fait que nous utiliseront l'abréviation RTU pour la désigner. Les shaders spécialisés sont des '''shaders de lancer de rayon''' et il y en a deux types.
* Les '''''shaders'' de génération de rayon''' s'occupent de générer les rayons
* Les '''''shaders'' de ''Hit/miss''''' s'occupent de faire tous les calculs une fois qu'une intersection est détectée.
Le processus de rendu en lancer de rayon sur ces GPU est le suivant. Pour commencer, les shaders de génération de rayon génèrent les rayons lancés. Ils laissent la main à l'unité de lancer de rayon, qui parcours la BVH et effectue les calculs d'intersection. Si la RTU détecte une intersection, elle envoie son résultat au processeur de ''shader'', qui lance alors l'exécution d'un ''shader'' de ''Hit/miss'' qui finit le travail. Lors de cette étape, il peut générer un nouveau rayon, et le processus recommence.
La génération des rayons a donc lieu dans les processeur de ''shaders'', par les ''shader'' de ''Hit/miss'', avec cependant une petite subtilité quant aux rayons secondaires. Les rayons d'ombrage et secondaires sont générés à partir du résultat des intersections des rayons précédents, donc dans le ''shader'' de ''Hit/miss''. Suivant la nature de la surface (opaque, transparente, réfléchissante, mate, autre), ils décident s'il faut ou non émettre un rayon secondaire, génèrent ce rayon s'il le faut, et l'envoie à la RTU.
====La traversée des structures d'accélérations et des BVH====
Lorsqu'un processeur de shader fait appel à la RTU, il lui envoie un rayon encodé d'une manière ou d'une autre, potentiellement différente d'un GPU à l'autre. Toujours est-il que les informations sur ce rayon sont mémorisée dans des registres à l'intérieur de la RTU. Ce n'est que quand le rayon quitte la RTU que ces registres sont réinitialisé pour laisser la palce à un autre rayon.
La RTU contient beaucoup d'unités de calcul pour effectuer les calculs d'intersections. Il est possible de tester un grand nombre d'intersections de triangles en parallèles, chacun dans une unité de calcul séparée. L'algorithme de lancer de rayons se parallélise donc très bien et la RTU en profite. En soi, les circuits de détection des intersections sont très simples et se résument à un paquet de circuits de calcul (addition, multiplications, division, autres), connectés les uns aux autres. Il y a assez peu à dire dessus. Mais les autres circuits sont très intéressants à étudier.
Il y a deux types d'intersections à calculer : les intersections avec les volumes englobants, les intersections avec les triangles. Volumes englobants et triangles ne sont pas encodés de la même manière en mémoire vidéo, ce qui fait que les calculs à faire ne sont pas exactement les mêmes. Et c'est normal : il y a une différence entre un pavé pour le volume englobant et trois sommets/vecteurs pour un triangle. La RTU des GPU Intel, et vraisemblablement celle des autres GPU, utilise des circuits de calcul différents pour les deux. Elle incorpore plus de circuits pour les intersections avec les volumes englobants, que de circuits pour les intersections avec un triangle. Il faut dire que lors de la traversée d'une BVH, il y a une intersection avec un triangle par rayon, mais plusieurs pour les volumes englobants.
L'intérieur de la RTU contient de quoi séquencer les accès mémoire nécessaires pour parcourir la BVH. Et le problème est que les BVH se marient assez mal avec la hiérarchie mémoire des GPU et CPU modernes. Ce sont des structures de données qui dispersent les données en mémoire, là où les GPU préfèrent des structures de données qui forment un seul bloc en RAM. Traverser un BVH demande de faire des sauts en mémoire RAM, et ce sont des accès mémoire imprévisibles que l'on ne peut pas optimiser. Pour limiter la casse, les RTU intègrent des caches pour mémoriser des portions de la BVH, au cas où celles-ci seraient retraversées plusieurs fois de suite par des rayons consécutifs. Mais ceux-ci ont un impact plus léger sur les performances.
L'autre raison, très liée à la précédente, est que traverser un BVH pour trouver le triangle intersectant demande d'effectuer beaucoup de branchements. On doit tester l'intersection avec un volume englobant, puis décider s'il faut passer au suivant, et si oui lequel, et rebelotte. Et dans du code informatique, cela demande beaucoup de IF...ELSE, de branchements, de tests de conditions, etc. Et les cartes graphiques sont assez mauvaises à ça. Les ''shaders'' peuvent en faire, mais sont très lents pour ces opérations. Pour diminuer l’impact sur les performances, les cartes graphiques modernes incorporent des circuits de tri pour regrouper les rayons cohérents, ceux qui vont dans la même direction et proviennent de triangles proches. Ce afin d'implémenter les optimisations vues plus haut.
====La génération des structures d'accélération et BVH====
La plupart des cartes graphiques ne peuvent pas générer les BVH d'elles-mêmes. Pareil pour les autres structures d'accélération. Elles sont calculées par le processeur, stockées en mémoire RAM, puis copiées dans la mémoire vidéo avant le démarrage du rendu 3D. Cependant, quelques rares cartes spécialement dédiées au lancer de rayons incorporent des circuits pour générer les BVH/AS. Elles lisent le tampon de sommet envoyé par le processeur, puis génèrent les BVH complémentaires. L'unité de génération des structures d'accélération est complétement séparée des autres unités. Un exemple d'architecture de ce type est l'architecture Raycore, dont nous parlerons dans les sections suivantes.
Cette unité peut aussi modifier les BVH à la volée, si jamais la scène 3D change. Par exemple, si un objet change de place, comme un NPC qui se déplace, il faut reconstruire le BVH. Les cartes graphiques récentes évitent de reconstruire le BVH de zéro, mais se contentent de modifier ce qui a changé dans le BVH. Les performances en sont nettement meilleures.
===Les cartes graphiques dédiées au lancer de rayon===
Les premières cartes accélératrices de lancer de rayons sont assez anciennes et datent des années 80-90. Leur évolution a plus ou moins suivi la même évolution que celle des cartes graphiques usuelles, sauf que très peu de cartes pour le lancer de rayons ont été produites. Par même évolution, on veut dire que les cartes graphiques pour le lancer de rayon ont commencé par tester deux solutions évidentes et extrêmes : les cartes basées sur des circuits programmables d'un côté, non programmables de l'autre.
La première carte pour le lancer de rayons était la TigerShark, et elle était tout simplement composée de plusieurs processeurs et de la mémoire sur une carte PCI. Elle ne faisait qu'accélérer le calcul des intersections, rien de plus.
Les autres cartes effectuaient du rendu 3D par voxel, un type de rendu 3D assez spécial que nous n'avons pas abordé jusqu'à présent, dont l'algorithme de lancer de rayons n'était qu'une petite partie du rendu. Elles étaient destinées au marché scientifique, industriel et médical. On peut notamment citer la VolumePro et la VIZARD et II. Les deux étaient des cartes pour bus PCI qui ne faisaient que du ''raycasting'' et n'utilisaient pas de rayons d'ombrage. Le ''raycasting'' était exécuté sur un processeur dédié sur la VIZARD II, sur un circuit fixe implémenté par un FPGA sur la Volume Pro Voici différents papiers académiques qui décrivent l'architecture de ces cartes accélératrices :
* [https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=ccda3712ba0e6575cd08025f3bb920de46201cac The VolumePro Real-Time Ray-Casting System].
* [https://www.researchgate.net/publication/234829060_VIZARD_II_A_reconfigurable_interactive_volume_rendering_system VIZARD II: A reconfigurable interactive volume rendering system]
La puce SaarCOR (Saarbrücken's Coherence Optimized Ray Tracer) et bien plus tard par la carte Raycore, étaient deux cartes réelement dédiées au raycasting pur, sans usage de voxels, et étaient basées sur des FPGA. Elles contenaient uniquement des circuits pour accélérer le lancer de rayon proprement dit, à savoir la génération des rayons, les calculs d'intersection, pas plus. Tout le reste, à savoir le rendu de la géométrie, le placage de textures, les ''shaders'' et autres, étaient effectués par le processeur. Voici des papiers académiques sur leur architecture :
* [https://gamma.cs.unc.edu/SATO/Raycore/raycore.pdf RayCore: A ray-tracing hardware architecture for mobile devices].
Le successeur de la SaarCOR, le Ray Processing Unit (RPU), était une carte hybride : c'était une SaarCOR basée sur des circuits fixes, qui gagna quelques possibilités de programmation. Elle ajoutait des processeurs de ''shaders'' aux circuits fixes spécialisés pour le lancer de rayons. Les autres cartes du genre faisaient pareil, et on peut citer les cartes ART, les cartes CausticOne, Caustic Professional's R2500 et R2100.
Les cartes 3D modernes permettent de faire à la fois de la rasterisation et du lancer de rayons. Pour cela, les GPU récents incorporent des unités pour effectuer des calculs d'intersection, qui sont réalisés dans des circuits spécialisés. Elles sont appelées des RT Cores sur les cartes NVIDIA, mais les cartes AMD et Intel ont leur équivalent, idem chez leurs concurrents de chez Imagination technologies, ainsi que sur certains GPU destinés au marché mobile. Peu de choses sont certaines sur ces unités, mais il semblerait qu'il s'agisse d'unités de textures modifiées.
De ce qu'on en sait, certains GPU utilisent des unités pour calculer les intersections avec les triangles, et d'autres unités séparées pour calculer les intersections avec les volumes englobants. La raison est que, comme dit plus haut, les algorithmes de calcul d'intersection sont différents dans les deux cas. Les algorithmes utilisés ne sont pas connus pour toutes les cartes graphiques. On sait que les GPU Wizard de Imagination technology utilisaient des tests AABB de Plücker. Ils utilisaient 15 circuits de multiplication, 9 additionneurs-soustracteurs, quelques circuits pour tester la présence dans un intervalle, des circuits de normalisation et arrondi. L'algorithme pour leurs GPU d'architecture Photon est disponible ici, pour les curieux : [https://www.highperformancegraphics.org/slides23/2023-06-_HPG_IMG_RayTracing_2.pdf].
{{NavChapitre | book=Les cartes graphiques
| prev=Le multi-GPU
| prevText=Le multi-GPU
}}{{autocat}}
h0ebpsnp3fvxysx5vmmlgvgkwgkmj6e
744333
744332
2025-06-08T17:11:49Z
Mewtow
31375
/* La traversée des structures d'accélérations et des BVH */
744333
wikitext
text/x-wiki
Les cartes graphiques actuelles utilisent la technique de la rastérisation, qui a été décrite en détail dans le chapitre sur les cartes accélératrices 3D. Mais nous avions dit qu'il existe une seconde technique générale pour le rendu 3D, totalement opposée à la rastérisation, appelée le '''lancer de rayons'''. Cette technique a cependant été peu utilisée dans les jeux vidéo, jusqu'à récemment. La raison est que le lancer de rayons demande beaucoup de puissance de calcul, sans compter que créer des cartes accélératrices pour le lancer de rayons n'est pas simple.
Mais les choses commencent à changer. Quelques jeux vidéos récents intègrent des techniques de lancer rayons, pour compléter un rendu effectué principalement en rastérisation. De plus, les cartes graphiques modernes incorporent quelques circuits pour accélérer le lancer de rayons, même s'ils restent marginaux des compléments au rendu par rastérisation. S'il a existé des cartes accélératrices totalement dédiées au rendu en lancer de rayons, elles sont restées confidentielles. Aussi, nous allons nous concentrer sur les cartes graphiques récentes, et allons peu parler des cartes accélératrices dédiées au lancer de rayons.
==Le lancer de rayons==
Le lancer de rayons et la rastérisation. commencent par générer la géométrie de la scène 3D, en plaçant les objets dans la scène 3D, et en effectuant l'étape de transformation des modèles 3D, et les étapes de transformation suivante. Mais les ressemblances s'arrêtent là. Le lancer de rayons effectue l'étape d'éclairage différemment, sans compter qu'il n'a pas besoin de rastérisation.
===Le ''ray-casting'' : des rayons tirés depuis la caméra===
La forme la plus simple de lancer de rayon s'appelle le '''''ray-casting'''''. Elle émet des lignes droites, des '''rayons''' qui partent de la caméra et qui passent chacun par un pixel de l'écran. Les rayons font alors intersecter les différents objets présents dans la scène 3D, en un point d'intersection. Le moteur du jeu détermine alors quel est le point d'intersection le plus proche, ou plus précisément, le sommet le plus proche de ce point d'intersection. Ce sommet est associé à une coordonnée de textures, ce qui permet d'associer directement un texel au pixel associé au rayon.
[[File:Raytrace trace diagram.png|centre|vignette|upright=2|Raycasting, rayon simple.]]
En somme, l'étape de lancer de rayon et le calcul des intersections remplacent l'étape de rasterisation, mais les étapes de traitement de la géométrie et des textures existent encore. Après tout, il faut bien placer les objets dans la scène 3D/2D, faire diverses transformations, les éclairer. On peut gérer la transparence des textures assez simplement, si on connait la transparence sur chaque point d'intersection d'un rayon, information présente dans les textures.
[[File:Anarch short gameplay.gif|vignette|Exemple de rendu en ray-casting 2D dans un jeu vidéo.]]
En soi, cet algorithme est simple, mais il a déjà été utilisé dans pas mal de jeux vidéos. Mais sous une forme simple, en deux dimensions ! Les premiers jeux IdSoftware, dont Wolfenstein 3D et Catacomb, utilisaient cette méthode de rendu, mais dans un univers en deux dimensions. Cet article explique bien cela : [[Les moteurs de rendu des FPS en 2.5 D\Le moteur de Wolfenstein 3D|Le moteur de rendu de Wolfenstein 3D]]. Au passage, si vous faites des recherches sur le ''raycasting'', vous verrez que le terme est souvent utilisé pour désigner la méthode de rendu de ces vieux FPS, alors que ce n'en est qu'un cas particulier.
[[File:Simple raycasting with fisheye correction.gif|centre|vignette|upright=2|Simple raycasting with fisheye correction]]
===Le ''raytracing'' proprement dit===
Le lancer de rayon proprement dit est une forme améliorée de ''raycasting'' dans la gestion de l'éclairage et des ombres est modifiée. Le lancer de rayon calcule les ombres assez simplement, sans recourir à des algorithmes compliqués. L'idée est qu'un point d'intersection est dans l'ombre si un objet se trouve entre lui et une source de lumière. Pour déterminer cela, il suffit de tirer un trait entre les deux et de vérifier s'il y a un obstacle/objet sur le trajet. Si c'est le cas, le point d'intersection n'est pas éclairé par la source de lumière et est donc dans l'ombre. Si ce n'est pas le cas, il est éclairé avec un algorithme d'éclairage.
Le trait tiré entre la source de lumière et le point d'intersection est en soi facile : c'est rayon, identique aux rayons envoyés depuis la caméra. La différence est que ces rayons servent à calculer les ombres, ils sont utilisés pour une raison différente. Il faut donc faire la différence entre les '''rayons primaires''' qui partent de la caméra et passent par un pixel de l'écran, et les '''rayon d'ombrage''' qui servent pour le calcul des ombres.
[[File:Ray trace diagram.svg|centre|vignette|upright=2|Principe du lancer de rayons.]]
Les calculs d'éclairage utilisés pour éclairer/ombrer les points d'intersection vous sont déjà connus : la luminosité est calculée à partir de l'algorithme d'éclairage de Phong, vu dans le chapitre "L'éclairage d'une scène 3D : shaders et T&L". Pour cela, il faut juste récupérer la normale du sommet associé au point d'intersection et l'intensité de la source de lumière, et de calculer les informations manquantes (l'angle normale-rayons de lumière, autres). Il détermine alors la couleur de chaque point d'intersection à partir de tout un tas d'informations.
===Le ''raytracing'' récursif===
[[File:Glasses 800 edit.png|vignette|Image rendue avec le lancer de rayons récursif.]]
La technique de lancer de rayons précédente ne gère pas les réflexions, les reflets, des miroirs, les effets de spécularité, et quelques autres effets graphiques de ce style. Pourtant, ils peuvent être implémentés facilement en modifiant le ''raycasting'' d'une manière très simple.
Il suffit de relancer des rayons à partir du point d'intersection. La direction de ces '''rayons secondaires''' est calculée en utilisant les lois de la réfraction/réflexion vues en physique. De plus, les rayons secondaires peuvent eux-aussi créer des rayons secondaires quand ils sont reflétés/réfractés, etc. La technique est alors appelée du ''lancer de rayons récursif'', qui est souvent simplement appelée "lancer de rayons".
[[File:Recursive raytracing.svg|centre|vignette|upright=2|Lancer de rayon récursif.]]
===Les avantages et désavantages comparé à la rastérisation===
L'avantage principal du lancer de rayons est son rendu de l'éclairage, qui est plus réaliste. Les ombres se calculent naturellement avec cette méthode de rendu, là où elles demandent des ruses comme des lightmaps, des textures pré-éclairées, divers algorithmes d'éclairage géométriques, etc. Les réflexions et la réfraction sont gérées naturellement par le lancer de rayon récursif, alors qu'elles demandent des ruses de sioux pour obtenir un résultat correct avec la rastérisation.
[[File:ViewFrustum.svg|vignette|upright=1|Volume délimité par la caméra (''view frustum'').]]
Pour ce qui est des performances théoriques, le lancer de rayons se débrouille mieux sur un point : l'élimination des pixels/surfaces cachés. La rastérisation a tendance à calculer inutilement des portions non-rendues de la scène 3D, et doit utiliser des techniques de ''culling'' ou de ''clipping'' pour éviter trop de calculs inutiles. Ces techniques sont très puissantes, mais imparfaites. De nombreux fragments/pixels calculés sont éliminés à la toute fin du pipeline, grâce au z-buffer, après avoir été calculés et texturés. Le lancer de rayons se passe totalement de ces techniques d'élimination des pixels cachés, car elle ne calcule pas les portions invisibles de l'image par construction : pas besoin de ''culling'', de ''clipping'', ni même de z-buffer.
Mais tous ces avantages sont compensés par le fait que le lancer de rayons est plus lent sur un paquet d'autres points. Déjà, les calculs d'intersection sont très lourds, ils demandent beaucoup de calculs et d'opérations arithmétiques, plus que pour l'équivalent en rastérisation. Ensuite, de nombreuses optimisations présentes en rastérisation ne sont pas possibles. Notamment, le lancer de rayon utilise assez mal la mémoire, dans le sens où les accès en mémoire vidéo sont complétement désorganisés, là où le rendu 3D a des accès plus linéaires qui permettent d'utiliser des mémoires caches.
==Les optimisations du lancer de rayons liées aux volumes englobants==
Les calculs d'intersections sont très gourmands en puissance de calcul. Sans optimisation, on doit tester l'intersection de chaque rayon avec chaque triangle. Mais diverses optimisations permettent d'économiser des calculs. Elles consistent à regrouper plusieurs triangles ensemble pour rejeter des paquets de triangles en une fois. Pour cela, la carte graphique utilise des '''structures d'accélération''', qui mémorisent les regroupements de triangles, et parfois les triangles eux-mêmes.
===Les volumes englobants===
[[File:BoundingBox.jpg|vignette|Objet englobant : la statue est englobée dans un pavé.]]
L'idée est d'englober chaque objet par un pavé appelé un ''volume englobant''. Le tout est illustré ci-contre, avec une statue représentée en 3D. La statue est un objet très complexe, contenant plusieurs centaines ou milliers de triangles, ce qui fait que tester l'intersection d'un rayon avec chaque triangle serait très long. Par contre, on peut tester si le rayon intersecte le volume englobant facilement : il suffit de tester les 6 faces du pavé, soit 12 triangles, pas plus. S'il n'y a pas d'intersection, alors on économise plusieurs centaines ou milliers de tests d'intersection. Par contre, s'il y a intersection, on doit vérifier chaque triangle. Vu que les rayons intersectent souvent peu d'objets, le gain est énorme !
L'usage seul de volumes englobant est une optimisation très performante. Au lieu de tester l'intersection avec chaque triangle, on teste l'intersection avec chaque objet, puis l'intersection avec chaque triangle quand on intersecte chaque volume englobant. On divise le nombre de tests par un facteur quasi-constant, mais de très grande valeur.
Il faut noter que les calculs d'intersection sont légèrement différents entre un triangle et un volume englobant. Il faut dire que les volumes englobant sont généralement des pavées, ils utilisent des rectangles, etc. Les différences sont cependant minimales.
===Les hiérarchies de volumes englobants===
Mais on peut faire encore mieux. L'idée est de regrouper plusieurs volumes englobants en un seul. Si une dizaine d'objets sont proches, leurs volumes englobants seront proches. Il est alors utile d'englober leurs volumes englobants dans un super-volume englobant. L'idée est que l'on teste d'abord le super-volume englobant, au lieu de tester la dizaine de volumes englobants de base. S'il n'y a pas d'intersection, alors on a économisé une dizaine de tests. Mais si intersection, il y a, alors on doit vérifier chaque sous-volume englobant de base, jusqu'à tomber sur une intersection. Vu que les intersections sont rares, on y gagne plus qu'on y perd.
Et on peut faire la même chose avec les super-volumes englobants, en les englobant dans des volumes englobants encore plus grands, et ainsi de suite, récursivement. On obtient alors une '''hiérarchie de volumes englobants''', qui part d'un volume englobant qui contient toute la géométrie, hors skybox, qui lui-même regroupe plusieurs volumes englobants, qui eux-mêmes...
[[File:Example of bounding volume hierarchy.svg|centre|vignette|upright=2|Hiérarchie de volumes englobants.]]
Le nombre de tests d'intersection est alors grandement réduit. On passe d'un nombre de tests proportionnel aux nombres d'objets à un nombre proportionnel à son logarithme. Plus la scène contient d'objets, plus l'économie est importante. La seule difficulté est de générer la hiérarchie de volumes englobants à partir d'une scène 3D. Divers algorithmes assez rapides existent pour cela, ils créent des volumes englobants différents. Les volumes englobants les plus utilisés dans les cartes 3D sont les '''''axis-aligned bounding boxes (AABB)'''''.
La hiérarchie est mémorisée en mémoire RAM, dans une structure de données que les programmeurs connaissent sous le nom d'arbre, et précisément un arbre binaire ou du moins d'un arbre similaire (''k-tree''). Traverser cet arbre pour passer d'un objet englobant à un autre plus petit est très simple, mais a un défaut : on saute d'on objet à un autre en mémoire, les deux sont souvent éloignés en mémoire. La traversée de la mémoire est erratique, sautant d'un point à un autre. On n'est donc dans un cas où les caches fonctionnent mal, ou les techniques de préchargement échouent, où la mémoire devient un point bloquant car trop lente.
===La cohérence des rayons===
Les rayons primaires, émis depuis la caméra, sont proches les uns des autres, et vont tous dans le même sens. Mais ce n'est pas le cas pour des rayons secondaires. Les objets d'une scène 3D ont rarement des surfaces planes, mais sont composés d'un tas de triangles qui font un angle entre eux. La conséquence est que deux rayons secondaires émis depuis deux triangles voisins peuvent aller dans des directions très différentes. Ils vont donc intersecter des objets très différents, atterrir sur des sources de lumières différentes, etc. De tels rayons sont dits '''incohérents''', en opposition aux rayons cohérents qui sont des rayons proches qui vont dans la même direction.
Les rayons incohérents sont peu fréquents avec le ''rayctracing'' récursif basique, mais deviennent plus courants avec des techniques avancées comme le ''path tracing'' ou les techniques d'illumination globale. En soi, la présende de rayons incohérents n'est pas un problème et est parfaitement normale. Le problème est que le traitement des rayons incohérent est plus lent que pour les rayons cohérents. Le traitement de deux rayons secondaires voisins demande d'accéder à des données différentes, ce qui donne des accès mémoire très différents et très éloignés. On ne peut pas profiter des mémoires caches ou des optimisations de la hiérarchie mémoire, si on les traite consécutivement. Un autre défaut est qu'une même instance de ''pixels shaders'' va traiter plusieurs rayons en même temps, grâce au SIMD. Mais les branchements n'auront pas les mêmes résultats d'un rayon à l'autre, et cette divergence entrainera des opérations de masquage et de branchement très couteuses.
Pour éviter cela, les GPU modernes permettent de trier les rayons en fonction de leur direction et de leur origine. Ils traitent les rayons non dans l'ordre usuel, mais essayent de regrouper des rayons proches qui vont dans la même direction, et de les traiter ensemble, en parallèle, ou l'un après l'autre. Cela ne change rien au rendu final, qui traite les rayons en parallèle. Ainsi, les données chargées dans le cache par le premier rayon seront celles utilisées pour les rayons suivants, ce qui donne un gain de performance appréciable. De plus, cela évite d'utiliser des branchements dans les ''pixels shaders''. Les méthodes de '''tri de rayons''' sont nombreuses, aussi en faire une liste exhaustive serait assez long, sans compter qu'on ne sait pas quelles sont celles implémentées en hardware, ni commetn elles le sont.
==Le matériel pour accélérer le lancer de rayons==
Le lancer de rayons a toujours besoin de calculer la géométrie, d'appliquer des textures et de faire des calculs d'éclairage. Sachant cela, beaucoup de chercheurs se sont dit qu'il n'était pas nécessaire d'utiliser du matériel spécialisé pour le lancer de rayons, et qu'utiliser les GPU actuels était suffisant. En théorie, il est possible d'utiliser des ''shaders'' pour effectuer du lancer de rayons, mais la technique n'est pas très performante.
Une carte graphique spécialement dédiée au lancer de rayons est donc quasiment identique à une carte graphique normale. Les deux contiennent des unités de texture et des processeurs de ''shaders'', des unités géométriques, un ''input assembler'', et tout ce qui va avec. Seuls les circuits de rasterisation et le z-buffer sont remplacés par des circuits dédiés au lancer de rayon, à savoir des unités de génération des rayons et des unités pour les calculs d'intersection. D'ailleurs, il est aussi possible d'ajouter des circuits de génération/intersection de rayons à une carte graphique existante.
Au niveau matériel, la gestion de la mémoire est un peu plus simple. Le lancer de rayon n'écrit que dans le ''framebuffer'' et n'a pas besoin de z-buffer, ce qui a beaucoup d'avantages. Notamment, les caches sont en lecture seule, leurs circuits sont donc assez simples et performants, les problèmes de cohérence des caches disparaissent. L'absence de z-buffer fait que de nombreuses écritures/lectures dans le ''framebuffer'' sont économisées. Les lectures et écritures de textures sont tout aussi fréquentes qu'avec la rasterisation, et sont même plus faible en principe car de nombreux effets de lumières complexes sont calculés avec le lancer de rayons, alors qu'ils doivent être précalculés dans des textures et lus par les shaders.
===Les circuits spécialisés pour les calculs liés aux rayons===
Toute la subtilité du lancer de rayons est de générer les rayons et de déterminer quels triangles ils intersectent. La seule difficulté est de gérer la transparence, mais aussi et surtout la traversée de la BVH. En soit, générer les rayons et déterminer leurs intersections n'est pas compliqué. Il existe des algorithmes basés sur du calcul vectoriel pour déterminer si intersection il y a et quelles sont ses coordonnées. C'est toute la partie de parcours de la BVH qui est plus compliquée à implémenter : faire du ''pointer chasing'' en hardware n'est pas facile.
Et cela se ressent quand on étudie comment les GPU récents gèrent le lancer de rayons. Ils utilisent des shaders dédiés, qui communiquent avec une '''unité de lancer de rayon''' dédiée à la traversée de la BVH. Le terme anglais est ''Ray-tracing Unit'', ce qui fait que nous utiliseront l'abréviation RTU pour la désigner. Les shaders spécialisés sont des '''shaders de lancer de rayon''' et il y en a deux types.
* Les '''''shaders'' de génération de rayon''' s'occupent de générer les rayons
* Les '''''shaders'' de ''Hit/miss''''' s'occupent de faire tous les calculs une fois qu'une intersection est détectée.
Le processus de rendu en lancer de rayon sur ces GPU est le suivant. Pour commencer, les shaders de génération de rayon génèrent les rayons lancés. Ils laissent la main à l'unité de lancer de rayon, qui parcours la BVH et effectue les calculs d'intersection. Si la RTU détecte une intersection, elle envoie son résultat au processeur de ''shader'', qui lance alors l'exécution d'un ''shader'' de ''Hit/miss'' qui finit le travail. Lors de cette étape, il peut générer un nouveau rayon, et le processus recommence.
La génération des rayons a donc lieu dans les processeur de ''shaders'', par les ''shader'' de ''Hit/miss'', avec cependant une petite subtilité quant aux rayons secondaires. Les rayons d'ombrage et secondaires sont générés à partir du résultat des intersections des rayons précédents, donc dans le ''shader'' de ''Hit/miss''. Suivant la nature de la surface (opaque, transparente, réfléchissante, mate, autre), ils décident s'il faut ou non émettre un rayon secondaire, génèrent ce rayon s'il le faut, et l'envoie à la RTU.
===La RTU : la traversée des structures d'accélérations et des BVH===
Lorsqu'un processeur de shader fait appel à la RTU, il lui envoie un rayon encodé d'une manière ou d'une autre, potentiellement différente d'un GPU à l'autre. Toujours est-il que les informations sur ce rayon sont mémorisée dans des registres à l'intérieur de la RTU. Ce n'est que quand le rayon quitte la RTU que ces registres sont réinitialisé pour laisser la palce à un autre rayon.
La RTU contient beaucoup d'unités de calcul pour effectuer les calculs d'intersections. Il est possible de tester un grand nombre d'intersections de triangles en parallèles, chacun dans une unité de calcul séparée. L'algorithme de lancer de rayons se parallélise donc très bien et la RTU en profite. En soi, les circuits de détection des intersections sont très simples et se résument à un paquet de circuits de calcul (addition, multiplications, division, autres), connectés les uns aux autres. Il y a assez peu à dire dessus. Mais les autres circuits sont très intéressants à étudier.
Il y a deux types d'intersections à calculer : les intersections avec les volumes englobants, les intersections avec les triangles. Volumes englobants et triangles ne sont pas encodés de la même manière en mémoire vidéo, ce qui fait que les calculs à faire ne sont pas exactement les mêmes. Et c'est normal : il y a une différence entre un pavé pour le volume englobant et trois sommets/vecteurs pour un triangle. La RTU des GPU Intel, et vraisemblablement celle des autres GPU, utilise des circuits de calcul différents pour les deux. Elle incorpore plus de circuits pour les intersections avec les volumes englobants, que de circuits pour les intersections avec un triangle. Il faut dire que lors de la traversée d'une BVH, il y a une intersection avec un triangle par rayon, mais plusieurs pour les volumes englobants.
L'intérieur de la RTU contient de quoi séquencer les accès mémoire nécessaires pour parcourir la BVH. Et le problème est que les BVH se marient assez mal avec la hiérarchie mémoire des GPU et CPU modernes. Ce sont des structures de données qui dispersent les données en mémoire, là où les GPU préfèrent des structures de données qui forment un seul bloc en RAM. Traverser un BVH demande de faire des sauts en mémoire RAM, et ce sont des accès mémoire imprévisibles que l'on ne peut pas optimiser.
Pour limiter la casse, les RTU intègrent des '''caches de BVH''', qui mémorisent des portions de la BVH au cas où celles-ci seraient retraversées plusieurs fois de suite par des rayons consécutifs. Mais ceux-ci ont un impact plus léger sur les performances. La taille de ce cache est de l'ordre du kilo-octet ou plus. Pour donner des exemples, les GPU Intel d'architecture Battlemage ont un cache de BVH de 16 Kilo-octets, soit le double comparé aux GPU antérieurs. Le cache de BVH est très fortement lié à la RTU et n'est pas accesible par l'unité de texture, les processeurs de ''sahder'' ou autres.
L'autre raison, très liée à la précédente, est que traverser un BVH pour trouver le triangle intersectant demande d'effectuer beaucoup de branchements. On doit tester l'intersection avec un volume englobant, puis décider s'il faut passer au suivant, et si oui lequel, et rebelotte. Et dans du code informatique, cela demande beaucoup de IF...ELSE, de branchements, de tests de conditions, etc. Et les cartes graphiques sont assez mauvaises à ça. Les ''shaders'' peuvent en faire, mais sont très lents pour ces opérations. Pour diminuer l’impact sur les performances, les cartes graphiques modernes incorporent des circuits de tri pour regrouper les rayons cohérents, ceux qui vont dans la même direction et proviennent de triangles proches. Ce afin d'implémenter les optimisations vues plus haut.
====La génération des structures d'accélération et BVH====
La plupart des cartes graphiques ne peuvent pas générer les BVH d'elles-mêmes. Pareil pour les autres structures d'accélération. Elles sont calculées par le processeur, stockées en mémoire RAM, puis copiées dans la mémoire vidéo avant le démarrage du rendu 3D. Cependant, quelques rares cartes spécialement dédiées au lancer de rayons incorporent des circuits pour générer les BVH/AS. Elles lisent le tampon de sommet envoyé par le processeur, puis génèrent les BVH complémentaires. L'unité de génération des structures d'accélération est complétement séparée des autres unités. Un exemple d'architecture de ce type est l'architecture Raycore, dont nous parlerons dans les sections suivantes.
Cette unité peut aussi modifier les BVH à la volée, si jamais la scène 3D change. Par exemple, si un objet change de place, comme un NPC qui se déplace, il faut reconstruire le BVH. Les cartes graphiques récentes évitent de reconstruire le BVH de zéro, mais se contentent de modifier ce qui a changé dans le BVH. Les performances en sont nettement meilleures.
===Les cartes graphiques dédiées au lancer de rayon===
Les premières cartes accélératrices de lancer de rayons sont assez anciennes et datent des années 80-90. Leur évolution a plus ou moins suivi la même évolution que celle des cartes graphiques usuelles, sauf que très peu de cartes pour le lancer de rayons ont été produites. Par même évolution, on veut dire que les cartes graphiques pour le lancer de rayon ont commencé par tester deux solutions évidentes et extrêmes : les cartes basées sur des circuits programmables d'un côté, non programmables de l'autre.
La première carte pour le lancer de rayons était la TigerShark, et elle était tout simplement composée de plusieurs processeurs et de la mémoire sur une carte PCI. Elle ne faisait qu'accélérer le calcul des intersections, rien de plus.
Les autres cartes effectuaient du rendu 3D par voxel, un type de rendu 3D assez spécial que nous n'avons pas abordé jusqu'à présent, dont l'algorithme de lancer de rayons n'était qu'une petite partie du rendu. Elles étaient destinées au marché scientifique, industriel et médical. On peut notamment citer la VolumePro et la VIZARD et II. Les deux étaient des cartes pour bus PCI qui ne faisaient que du ''raycasting'' et n'utilisaient pas de rayons d'ombrage. Le ''raycasting'' était exécuté sur un processeur dédié sur la VIZARD II, sur un circuit fixe implémenté par un FPGA sur la Volume Pro Voici différents papiers académiques qui décrivent l'architecture de ces cartes accélératrices :
* [https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=ccda3712ba0e6575cd08025f3bb920de46201cac The VolumePro Real-Time Ray-Casting System].
* [https://www.researchgate.net/publication/234829060_VIZARD_II_A_reconfigurable_interactive_volume_rendering_system VIZARD II: A reconfigurable interactive volume rendering system]
La puce SaarCOR (Saarbrücken's Coherence Optimized Ray Tracer) et bien plus tard par la carte Raycore, étaient deux cartes réelement dédiées au raycasting pur, sans usage de voxels, et étaient basées sur des FPGA. Elles contenaient uniquement des circuits pour accélérer le lancer de rayon proprement dit, à savoir la génération des rayons, les calculs d'intersection, pas plus. Tout le reste, à savoir le rendu de la géométrie, le placage de textures, les ''shaders'' et autres, étaient effectués par le processeur. Voici des papiers académiques sur leur architecture :
* [https://gamma.cs.unc.edu/SATO/Raycore/raycore.pdf RayCore: A ray-tracing hardware architecture for mobile devices].
Le successeur de la SaarCOR, le Ray Processing Unit (RPU), était une carte hybride : c'était une SaarCOR basée sur des circuits fixes, qui gagna quelques possibilités de programmation. Elle ajoutait des processeurs de ''shaders'' aux circuits fixes spécialisés pour le lancer de rayons. Les autres cartes du genre faisaient pareil, et on peut citer les cartes ART, les cartes CausticOne, Caustic Professional's R2500 et R2100.
Les cartes 3D modernes permettent de faire à la fois de la rasterisation et du lancer de rayons. Pour cela, les GPU récents incorporent des unités pour effectuer des calculs d'intersection, qui sont réalisés dans des circuits spécialisés. Elles sont appelées des RT Cores sur les cartes NVIDIA, mais les cartes AMD et Intel ont leur équivalent, idem chez leurs concurrents de chez Imagination technologies, ainsi que sur certains GPU destinés au marché mobile. Peu de choses sont certaines sur ces unités, mais il semblerait qu'il s'agisse d'unités de textures modifiées.
De ce qu'on en sait, certains GPU utilisent des unités pour calculer les intersections avec les triangles, et d'autres unités séparées pour calculer les intersections avec les volumes englobants. La raison est que, comme dit plus haut, les algorithmes de calcul d'intersection sont différents dans les deux cas. Les algorithmes utilisés ne sont pas connus pour toutes les cartes graphiques. On sait que les GPU Wizard de Imagination technology utilisaient des tests AABB de Plücker. Ils utilisaient 15 circuits de multiplication, 9 additionneurs-soustracteurs, quelques circuits pour tester la présence dans un intervalle, des circuits de normalisation et arrondi. L'algorithme pour leurs GPU d'architecture Photon est disponible ici, pour les curieux : [https://www.highperformancegraphics.org/slides23/2023-06-_HPG_IMG_RayTracing_2.pdf].
{{NavChapitre | book=Les cartes graphiques
| prev=Le multi-GPU
| prevText=Le multi-GPU
}}{{autocat}}
43nptanof8xqwav5q0sektt0vd7hj5n
Fonctionnement d'un ordinateur/L'accélération matérielle de la virtualisation
0
82429
744305
744297
2025-06-08T13:11:36Z
Mewtow
31375
/* Les machines virtuelles */
744305
wikitext
text/x-wiki
La virtualisation est l'ensemble des techniques qui permettent de faire tourner plusieurs systèmes d'exploitation en même temps. Le terme est polysémique, mais c'est la définition que nous allons utiliser pour ce qui nous intéresse. La virtualisation demande d'utiliser un logiciel dit '''hyperviseur''', qui permet de faire tourner plusieurs OS en même temps. Les hyperviseurs sont en quelque sorte situés sous le système d'exploitation et on peut les voir comme une sorte de sous-système d'exploitation, de système d'exploitation pour les systèmes d'exploitation.
[[File:Diagramme ArchiHyperviseur.png|centre|vignette|upright=2|Différence entre système d'exploitation et hyperviseur.]]
Pour faire tourner plusieurs OS en même temps, l'hyperviseur recourt à de nombreux stratagèmes. Il doit partager le processeur, la RAM et les entrées-sorties entre plusieurs OS. Les trois demandent des techniques différentes. Le partage de la RAM demande concrètement des modifications au niveau de la mémoire virtuelle. Le partage du processeur est assez simple : les OS s'exécutent à tour de rôle sur le processeur, chacun pendant un temps défini, fixe. Une fois leur temps d'exécution passé, ils laissent la main à l'OS suivant. C'est l’hyperviseur qui s'occupe de tout cela, grâce à une interruption commandée à un ''timer''. Ce système de partage est une forme de '''multiplexage'''.
La gestion des entrées-sorties demande d'utiliser des techniques d''''émulation''', plus complexes à expliquer. Un hyperviseur peut parfaitement simuler du matériel qui n'est pas installé sur l'ordinateur. Par exemple, il peut faire croire à un OS qu'une carte réseau obsolète, datant d'il y a 20 ans, est installée sur l'ordinateur, alors que ce n'est pas le cas. Les commandes envoyées par l'OS à cette carte réseau fictive sont en réalité traitées par une vraie carte réseau par l’hyperviseur. Pour cela, l’hyperviseur intercepte les commandes envoyées aux entrées-sorties, et les traduit en commandes compatibles avec les entrées-sorties réellement installées sur l'ordinateur.
==Les machines virtuelles==
L'exemple avec la carte réseau est un cas particulier, l'hyperviseur faisant beaucoup de choses dans le genre. L'hyperviseur peut faire croire à l'ordinateur qu'il a plus ou moins de RAM que ce qui est réellement installé, par exemple. L'hyperviseur implémente ce qu'on appelle des '''machines virtuelles'''. Il s'agit d'une sorte de faux matériel, simulé par un logiciel. Un logiciel qui s’exécute dans une machine virtuelle aura l'impression de s’exécuter sur un matériel et/ou un O.S différent du matériel sur lequel il est en train de s’exécuter.
: Dans ce qui suit, nous parlerons de V.M (virtual machine), pour parler des machines virtuelles.
[[File:VM-monitor-french.png|centre|vignette|upright=2|Machines virtuelles avec la virtualisation.]]
L'hyperviseur crée plusieurs machines virtuelles, chacune étant réservée à un système d'exploitation. Il s'agit là d'une des utilisations possibles, mais il y en a d'autres. La plus intéressante est celle des émulateurs. Ces derniers sont des logiciels qui permettent de simuler le fonctionnement d'anciens ordinateurs ou consoles de jeux. L'émulateur crée une machine virtuelle qui est réservée à un programme, à savoir le jeu à émuler.
Il y a une différence de taille entre un émulateur et un hyperviseur. L'émulation émule une machine virtuelle totalement différente, alors que la virtualisation doit émuler les entrées-sorties mais pas le processeur. Avec un hyperviseur, le système d'exploitation s'exécute sur le processeur lui-même. Le code de l'OS est compatible avec le processeur de la machine, dans le sens où il est compilé pour le jeu d'instruction du processeur de la machine réelle. Les instructions de l'OS s'exécutent directement. Par contre, un émulateur exécute un jeu qui est programmé pour une machine dont le processeur est totalement différent. Le jeu d'instruction de la machine virtuelle et celui du vrai processeur n'est pas le même. L'émulation implique donc de traduire les instructions à exécuter dans la V.M par des instructions exécutables par le processeur. Ce n'est pas le cas avec la virtualisation, le jeu d'instruction étant le même.
[[File:Diagramme ArchiEmulateurNonNatif.png|centre|vignette|upright=2|Emulateur]]
==La virtualisation du CPU par détournement d'interruptions==
Pour être considéré comme un logiciel de virtualisation, un logiciel doit remplir trois critères :
* L'équivalence : l'O.S virtualisé et les applications qui s’exécutent doivent se comporter comme s'ils étaient exécutés sur le matériel de base, sans virtualisation.
* L'efficacité : La grande partie des instructions machines doit s’exécuter directement sur le processeur, afin de garder des performances correctes. Ce critère n'est pas respecté par les émulateurs matériels, qui doivent simuler le jeu d'instruction du processeur émulé.
* Le contrôle des ressources : tout accès au matériel par l'O.S virtualisé doit être intercepté par la machine virtuelle et intégralement pris en charge par l'hyperviseur.
===La méthode ''trap and emulate'' basique===
Remplir ces trois critères est possible sous certaines conditions, établies par les théorèmes de Popek et Goldberg. Ces théorèmes se basent sur la présence de différents types d'instructions machines. Pour rappel, il faut distinguer les instructions privilégiées de celles qui ne le sont pas. Les instructions privilégiées ne peuvent s'exécuter que en mode noyau, les programmes en mode utilisateur ne peuvent pas les exécuter.
Parmi les instructions privilégiées on peut distinguer un sous-groupe appelé les '''instructions systèmes'''. Le premier type regroupe les '''instructions d'accès aux entrées-sorties''', aussi appelées instructions sensibles à la configuration. Le second type est celui des '''instructions de configuration du processeur''', qui agissent sur les registres de contrôle du processeur, aussi appelées instructions sensibles au comportement.
La théorie de Popek et Goldberg dit qu'il est possible de virtualiser un O.S à une condition : que les instructions systèmes soient toutes des instructions privilégiées, c’est-à-dire exécutables seulement en mode noyau. Virtualiser un O.S demande simplement de le démarrer en mode utilisateur. Quand l'O.S fait un accès au matériel, il le fait via une instruction privilégiée. Vu que l'OS est en mode utilisateur, cela déclenche une exception matérielle, qui émule l'instruction privilégiée.
L'hyperviseur n'est ni plus ni moins qu'un ensemble de routines d'interruptions, chaque routine simulant le fonctionnement du matériel émulé. Par exemple, un accès au disque dur sera émulé par une routine d'interruption, qui utilisera les appels systèmes fournit par l'OS pour accéder au disque dur réellement présent dans l'ordinateur. Cette méthode est souvent appelée la méthode ''trap and emulate''.
[[File:Virtualisation avec la méthode trap-and-emulate.png|centre|vignette|upright=2.0|Virtualisation avec la méthode trap-and-emulate]]
===Le mode hyperviseur pour la virtualisation===
Sur certains CPU modernes, il existe un niveau de privilège appelé le '''mode hyperviseur''' qui est utilisé pour les techniques de virtualisation. Le mode hyperviseur est réservé à l’hyperviseur et il a des droits d'accès spécifiques. Il n'est cependant pas toujours activé. Par exemple, si aucun hyperviseur n'est installé sur la machine, le processeur dispose seulement d'un mode noyau et d'un mode utilisateur normaux, le mode noyau n'ayant alors aucune limitation précise. Mais quand le mode hyperviseur est activé, une partie des manipulations est bloquée en mode noyau et n'est possible qu'en mode hyperviseur.
Le fonctionnement se base sur la différence entre instruction privilégiée et instruction système. Les instructions privilégiées peuvent s'exécuter en mode noyau, alors que les instructions systèmes ne peuvent s'exécuter qu'en mode hyperviseur. L'idée est que quand le noyau d'un OS exécute une instruction système, une exception matérielle est levée. L'exception bascule en mode hyperviseur et laisse la main à une routine de l'hyperviseur. L'hyperviseur fait alors des manipulations précise pour que l'instruction système donne le même résultat que si elle avait été exécutée par l'ordinateur simulé par la machine virtuelle.
[[File:Virtualisation avec un mode hyperviseur.png|centre|vignette|upright=2|Virtualisation avec un mode hyperviseur.]]
Il est ainsi possible d'émuler des entrées-sorties avec un cout en performance assez léger. Précisément, ce mode hyperviseur améliore les performances de la méthode du ''trap-and-emulate''. La méthode ''trap-and-emulate'' basique exécute une exception matérielle pour toute instruction privilégiées, qu'elle soit une instruction système ou non. Mais avec le mode hyperviseur, seules les instructions systèmes déclenchent une exception, pas les instructions privilégiées non-système. Les performances sont donc un peu meilleures, pour un résultat identique. Après tout, les entrées-sorties et la configuration du processeur suffisent à émuler une machine virtuelle, les autres instructions noyau ne le sont pas.
Sur les processeurs ARM, il est possible de configurer quelles instructions sont détournées vers le mode hyperviseur et celles qui restent en mode noyau. En clair, on peut configurer quelles sont les instructions systèmes et celles qui sont simplement privilégiées. Et il en est de même pour les interruptions : on peut configurer si elles exécutent la routine de l'OS normal en mode noyau, ou si elles déclenchent une exception matérielle qui redirige vers une routine de l’hyperviseur. En l'absence d'hyperviseur, toutes les interruptions redirigent vers la routine de l'OS normale, vers le mode noyau.
===Le jeu d'instruction peut être incompatible avec le ''trap and emulate''===
Le critère précédent n'est pas respecté par beaucoup de jeux d'instructions. Par exemple, ce n'est pas le cas sur les processeurs x86, qu'ils soient 32 bits. Diverses instructions systèmes ne sont pas des instructions privilégiées. Par exemple, les instructions qui manipulent les drapeaux d'interruption ne sont pas toutes des instructions privilégiées. Il en est de même avec les instructions qui manipulent les registres pour la segmentation, celles liées aux ''call gates'', etc. A cause de cela, il est impossible d'utiliser la méthode du ''trap and emulate''. La seule solution qui ne requiert pas de techniques matérielles est de traduire à la volée les instructions systèmes problématiques en appels systèmes équivalents, grâce à des techniques de '''réécriture de code'''.
D'autres limitations font que la méthode ''trap and emulate'' ne fonctionne pas. Déjà, il faut que l'ordinateur utilise la mémoire virtuelle, sans quoi plusieurs OS ne peuvent pas se partager la même mémoire physique. De plus, il ne faut pas que la mémoire physique, non-virtuelle, puisse être adressée directement. Et cette contrainte est violée, par exemple sur les architectures MIPS qui exposent des portions de la mémoire physique dans certaines zones fixées à l'avance de la mémoire virtuelle. l'OS est compilé pour utiliser ces zones de mémoire pour accéder aux entrées-sorties mappées en mémoire, entre autres. En théorie, on peut passer outre le problème en marquant ces zones de mémoire comme inaccessibles, toute lecture/écriture à ces adresses déclenche alors une exception traitée par l'hyperviseur. Mais le cout en performance est alors trop important.
Enfin, certaines instructions dites '''sensibles au contexte''' ont un comportement différent entre le mode noyau et le mode utilisateur. En présence de telles instructions, la méthode ''trap and emulate'' ne fonctionne tout simplement pas. Grâce à ces instructions, le système d’exploitation ou un programme applicatif peut savoir s'il s'exécute en mode utilisateur ou noyau, ou hyperviseur, ou autre.
Les processeurs ARM de version v8 et plus incorporent un mode hyperviseur, mais pas les processeurs x86. A la place, ils incorporent des technologies alternatives nommées Intel Vtx ou l'AMD-V. Elles fonctionnent sur un principe totalement différent.
==La virtualisation de la mémoire RAM==
Avec la virtualisation, les différentes machines virtuelles, les différents OS doivent se partager la mémoire physique. Et ce partage doit isoler les différents OS les uns des autres. Il est possible de comparer cette isolation avec l'isolation des processus : chaque OS doit avoir sa propre mémoire physique rien qu'à lui. L'idée est d'utiliser la mémoire virtuelle pour cela.
L'espace d'adressage physique vu par chaque OS est en réalité virtualisé, c’est-à-dire que c'est un espace d'adressage fictif, qui ne correspond pas à la mémoire virtuelle. Les adresses physiques vues par l'OS sont en réalité des adresses intermédiaires entre les adresses physiques liées à la RAM, et les adresses virtuelles vues par les processus. Pour les distinguer, nous parlerons d'adresses physiques de l'hôte pour parler des adresses de la RAM, et des adresses physiques invitées pour parler des adresses manipulées par les OS virtualisés. La raison est que les OS sont appelés des OS invités, alors que l'hyperviseur est parfois appelé l'OS hôte.
Sans accélération matérielle, la traduction des adresses physiques invitées en adresses hôte est réalisée par une seconde table des pages, appelée la ''shadow page table'', ce qui donnerait '''table des pages cachée''' en français. La table des pages cachée est prise en charge par l'hyperviseur. Toute modification de la table des pages cachée est réalisée par l'hyperviseur, les OS ne savent même pas qu'elle existe.
[[File:Shadowpagetables.png|centre|vignette|upright=2|Table des pages cachée.]]
Une autre solution demande un support matériel des tables des pages emboitées, à savoir qu'il y a un arbre de table des pages, chaque consultation de la première table des pages renvoie vers une seconde, qui renvoie vers une troisième, et ainsi de suite jusqu'à tomber sur la table des pages finale qui renvoie l'adresse physique réelle.
L'idée est l'utiliser une seule table des pages, mais d'ajouter un ou deux niveaux supplémentaires. Pour l'exemple, prenons le cas des processeurs x86. Sans virtualisation, l'OS utilise une table des pages de 4 niveaux. Avec, la table des pages a un niveau en plus, qui sont ajoutés à la fin de la dernière table des pages normale. Les niveaux ajoutés s'occupent de la traduction des adresses physiques invitées en adresses physiques hôte. Il faut que le processeur soit modifié de manière à parcourir automatiquement les niveaux ajoutés, ce qui demande quelques modifications de la TLB et du ''page table walker''.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les sections critiques et le modèle mémoire
| prevText=Les sections critiques et le modèle mémoire
| next=Le matériel réseau
| nextText=Le matériel réseau
}}
</noinclude>
6lz4sl6josb2h1ylr002vg4qn4szyei
744306
744305
2025-06-08T14:20:11Z
Mewtow
31375
744306
wikitext
text/x-wiki
La virtualisation est l'ensemble des techniques qui permettent de faire tourner plusieurs systèmes d'exploitation en même temps. Le terme est polysémique, mais c'est la définition que nous allons utiliser pour ce qui nous intéresse. La virtualisation demande d'utiliser un logiciel dit '''hyperviseur''', qui permet de faire tourner plusieurs OS en même temps. Les hyperviseurs sont en quelque sorte situés sous le système d'exploitation et on peut les voir comme une sorte de sous-système d'exploitation, de système d'exploitation pour les systèmes d'exploitation.
[[File:Diagramme ArchiHyperviseur.png|centre|vignette|upright=2|Différence entre système d'exploitation et hyperviseur.]]
Pour faire tourner plusieurs OS en même temps, l'hyperviseur recourt à de nombreux stratagèmes. Il doit partager le processeur, la RAM et les entrées-sorties entre plusieurs OS. Les trois demandent des techniques différentes. Le partage de la RAM demande concrètement des modifications au niveau de la mémoire virtuelle. Le partage du processeur est assez simple : les OS s'exécutent à tour de rôle sur le processeur, chacun pendant un temps défini, fixe. Une fois leur temps d'exécution passé, ils laissent la main à l'OS suivant. C'est l’hyperviseur qui s'occupe de tout cela, grâce à une interruption commandée à un ''timer''. Ce système de partage est une forme de '''multiplexage'''.
La gestion des entrées-sorties demande d'utiliser des techniques d''''émulation''', plus complexes à expliquer. Un hyperviseur peut parfaitement simuler du matériel qui n'est pas installé sur l'ordinateur. Par exemple, il peut faire croire à un OS qu'une carte réseau obsolète, datant d'il y a 20 ans, est installée sur l'ordinateur, alors que ce n'est pas le cas. Les commandes envoyées par l'OS à cette carte réseau fictive sont en réalité traitées par une vraie carte réseau par l’hyperviseur. Pour cela, l’hyperviseur intercepte les commandes envoyées aux entrées-sorties, et les traduit en commandes compatibles avec les entrées-sorties réellement installées sur l'ordinateur.
Les processeurs modernes intègrent des techniques pour accélérer matériellement la virtualisation. Les techniques en question sont assez variées, allant d'un niveau de privilège en plus des modes noyau/utilisateur à des techniques de duplication de ces mêmes modes. Les techniques de virtualisation demandent de détourner des interruptions, ce qui fait que ces techniques d'accélération demandent de modifier la manière dont le processeur gère les interruptions. Mais pour comprendre tout cela, il va falloir faire quelques explications sur la virtualisation elle-même.
==Les machines virtuelles==
L'exemple avec la carte réseau est un cas particulier, l'hyperviseur faisant beaucoup de choses dans le genre. L'hyperviseur peut faire croire à l'ordinateur qu'il a plus ou moins de RAM que ce qui est réellement installé, par exemple. L'hyperviseur implémente ce qu'on appelle des '''machines virtuelles'''. Il s'agit d'une sorte de faux matériel, simulé par un logiciel. Un logiciel qui s’exécute dans une machine virtuelle aura l'impression de s’exécuter sur un matériel et/ou un O.S différent du matériel sur lequel il est en train de s’exécuter.
: Dans ce qui suit, nous parlerons de V.M (virtual machine), pour parler des machines virtuelles.
[[File:VM-monitor-french.png|centre|vignette|upright=2|Machines virtuelles avec la virtualisation.]]
L'hyperviseur crée plusieurs machines virtuelles, chacune étant réservée à un système d'exploitation. Il s'agit là d'une des utilisations possibles, mais il y en a d'autres. La plus intéressante est celle des émulateurs. Ces derniers sont des logiciels qui permettent de simuler le fonctionnement d'anciens ordinateurs ou consoles de jeux. L'émulateur crée une machine virtuelle qui est réservée à un programme, à savoir le jeu à émuler.
Il y a une différence de taille entre un émulateur et un hyperviseur. L'émulation émule une machine virtuelle totalement différente, alors que la virtualisation doit émuler les entrées-sorties mais pas le processeur. Avec un hyperviseur, le système d'exploitation s'exécute sur le processeur lui-même. Le code de l'OS est compatible avec le processeur de la machine, dans le sens où il est compilé pour le jeu d'instruction du processeur de la machine réelle. Les instructions de l'OS s'exécutent directement. Par contre, un émulateur exécute un jeu qui est programmé pour une machine dont le processeur est totalement différent. Le jeu d'instruction de la machine virtuelle et celui du vrai processeur n'est pas le même. L'émulation implique donc de traduire les instructions à exécuter dans la V.M par des instructions exécutables par le processeur. Ce n'est pas le cas avec la virtualisation, le jeu d'instruction étant le même.
[[File:Diagramme ArchiEmulateurNonNatif.png|centre|vignette|upright=2|Emulateur]]
==La virtualisation du CPU par détournement d'interruptions==
Pour être considéré comme un logiciel de virtualisation, un logiciel doit remplir trois critères :
* L'équivalence : l'O.S virtualisé et les applications qui s’exécutent doivent se comporter comme s'ils étaient exécutés sur le matériel de base, sans virtualisation.
* L'efficacité : La grande partie des instructions machines doit s’exécuter directement sur le processeur, afin de garder des performances correctes. Ce critère n'est pas respecté par les émulateurs matériels, qui doivent simuler le jeu d'instruction du processeur émulé.
* Le contrôle des ressources : tout accès au matériel par l'O.S virtualisé doit être intercepté par la machine virtuelle et intégralement pris en charge par l'hyperviseur.
===La méthode ''trap and emulate'' basique===
Remplir ces trois critères est possible sous certaines conditions, établies par les théorèmes de Popek et Goldberg. Ces théorèmes se basent sur la présence de différents types d'instructions machines. Pour rappel, il faut distinguer les instructions privilégiées de celles qui ne le sont pas. Les instructions privilégiées ne peuvent s'exécuter que en mode noyau, les programmes en mode utilisateur ne peuvent pas les exécuter.
Parmi les instructions privilégiées on peut distinguer un sous-groupe appelé les '''instructions systèmes'''. Le premier type regroupe les '''instructions d'accès aux entrées-sorties''', aussi appelées instructions sensibles à la configuration. Le second type est celui des '''instructions de configuration du processeur''', qui agissent sur les registres de contrôle du processeur, aussi appelées instructions sensibles au comportement.
La théorie de Popek et Goldberg dit qu'il est possible de virtualiser un O.S à une condition : que les instructions systèmes soient toutes des instructions privilégiées, c’est-à-dire exécutables seulement en mode noyau. Virtualiser un O.S demande simplement de le démarrer en mode utilisateur. Quand l'O.S fait un accès au matériel, il le fait via une instruction privilégiée. Vu que l'OS est en mode utilisateur, cela déclenche une exception matérielle, qui émule l'instruction privilégiée.
L'hyperviseur n'est ni plus ni moins qu'un ensemble de routines d'interruptions, chaque routine simulant le fonctionnement du matériel émulé. Par exemple, un accès au disque dur sera émulé par une routine d'interruption, qui utilisera les appels systèmes fournit par l'OS pour accéder au disque dur réellement présent dans l'ordinateur. Cette méthode est souvent appelée la méthode ''trap and emulate''.
[[File:Virtualisation avec la méthode trap-and-emulate.png|centre|vignette|upright=2.0|Virtualisation avec la méthode trap-and-emulate]]
===Le mode hyperviseur pour la virtualisation===
Sur certains CPU modernes, il existe un niveau de privilège appelé le '''mode hyperviseur''' qui est utilisé pour les techniques de virtualisation. Le mode hyperviseur est réservé à l’hyperviseur et il a des droits d'accès spécifiques. Il n'est cependant pas toujours activé. Par exemple, si aucun hyperviseur n'est installé sur la machine, le processeur dispose seulement d'un mode noyau et d'un mode utilisateur normaux, le mode noyau n'ayant alors aucune limitation précise. Mais quand le mode hyperviseur est activé, une partie des manipulations est bloquée en mode noyau et n'est possible qu'en mode hyperviseur.
Le fonctionnement se base sur la différence entre instruction privilégiée et instruction système. Les instructions privilégiées peuvent s'exécuter en mode noyau, alors que les instructions systèmes ne peuvent s'exécuter qu'en mode hyperviseur. L'idée est que quand le noyau d'un OS exécute une instruction système, une exception matérielle est levée. L'exception bascule en mode hyperviseur et laisse la main à une routine de l'hyperviseur. L'hyperviseur fait alors des manipulations précise pour que l'instruction système donne le même résultat que si elle avait été exécutée par l'ordinateur simulé par la machine virtuelle.
[[File:Virtualisation avec un mode hyperviseur.png|centre|vignette|upright=2|Virtualisation avec un mode hyperviseur.]]
Il est ainsi possible d'émuler des entrées-sorties avec un cout en performance assez léger. Précisément, ce mode hyperviseur améliore les performances de la méthode du ''trap-and-emulate''. La méthode ''trap-and-emulate'' basique exécute une exception matérielle pour toute instruction privilégiées, qu'elle soit une instruction système ou non. Mais avec le mode hyperviseur, seules les instructions systèmes déclenchent une exception, pas les instructions privilégiées non-système. Les performances sont donc un peu meilleures, pour un résultat identique. Après tout, les entrées-sorties et la configuration du processeur suffisent à émuler une machine virtuelle, les autres instructions noyau ne le sont pas.
Sur les processeurs ARM, il est possible de configurer quelles instructions sont détournées vers le mode hyperviseur et celles qui restent en mode noyau. En clair, on peut configurer quelles sont les instructions systèmes et celles qui sont simplement privilégiées. Et il en est de même pour les interruptions : on peut configurer si elles exécutent la routine de l'OS normal en mode noyau, ou si elles déclenchent une exception matérielle qui redirige vers une routine de l’hyperviseur. En l'absence d'hyperviseur, toutes les interruptions redirigent vers la routine de l'OS normale, vers le mode noyau.
===Le jeu d'instruction peut être incompatible avec le ''trap and emulate''===
Le critère précédent n'est pas respecté par beaucoup de jeux d'instructions. Par exemple, ce n'est pas le cas sur les processeurs x86, qu'ils soient 32 bits. Diverses instructions systèmes ne sont pas des instructions privilégiées. Par exemple, les instructions qui manipulent les drapeaux d'interruption ne sont pas toutes des instructions privilégiées. Il en est de même avec les instructions qui manipulent les registres pour la segmentation, celles liées aux ''call gates'', etc. A cause de cela, il est impossible d'utiliser la méthode du ''trap and emulate''. La seule solution qui ne requiert pas de techniques matérielles est de traduire à la volée les instructions systèmes problématiques en appels systèmes équivalents, grâce à des techniques de '''réécriture de code'''.
D'autres limitations font que la méthode ''trap and emulate'' ne fonctionne pas. Déjà, il faut que l'ordinateur utilise la mémoire virtuelle, sans quoi plusieurs OS ne peuvent pas se partager la même mémoire physique. De plus, il ne faut pas que la mémoire physique, non-virtuelle, puisse être adressée directement. Et cette contrainte est violée, par exemple sur les architectures MIPS qui exposent des portions de la mémoire physique dans certaines zones fixées à l'avance de la mémoire virtuelle. l'OS est compilé pour utiliser ces zones de mémoire pour accéder aux entrées-sorties mappées en mémoire, entre autres. En théorie, on peut passer outre le problème en marquant ces zones de mémoire comme inaccessibles, toute lecture/écriture à ces adresses déclenche alors une exception traitée par l'hyperviseur. Mais le cout en performance est alors trop important.
Enfin, certaines instructions dites '''sensibles au contexte''' ont un comportement différent entre le mode noyau et le mode utilisateur. En présence de telles instructions, la méthode ''trap and emulate'' ne fonctionne tout simplement pas. Grâce à ces instructions, le système d’exploitation ou un programme applicatif peut savoir s'il s'exécute en mode utilisateur ou noyau, ou hyperviseur, ou autre.
Les processeurs ARM de version v8 et plus incorporent un mode hyperviseur, mais pas les processeurs x86. A la place, ils incorporent des technologies alternatives nommées Intel Vtx ou l'AMD-V. Elles fonctionnent sur un principe totalement différent.
==La virtualisation de la mémoire RAM==
Avec la virtualisation, les différentes machines virtuelles, les différents OS doivent se partager la mémoire physique. Et ce partage doit isoler les différents OS les uns des autres. Il est possible de comparer cette isolation avec l'isolation des processus : chaque OS doit avoir sa propre mémoire physique rien qu'à lui. L'idée est d'utiliser la mémoire virtuelle pour cela.
L'espace d'adressage physique vu par chaque OS est en réalité virtualisé, c’est-à-dire que c'est un espace d'adressage fictif, qui ne correspond pas à la mémoire virtuelle. Les adresses physiques vues par l'OS sont en réalité des adresses intermédiaires entre les adresses physiques liées à la RAM, et les adresses virtuelles vues par les processus. Pour les distinguer, nous parlerons d'adresses physiques de l'hôte pour parler des adresses de la RAM, et des adresses physiques invitées pour parler des adresses manipulées par les OS virtualisés. La raison est que les OS sont appelés des OS invités, alors que l'hyperviseur est parfois appelé l'OS hôte.
Sans accélération matérielle, la traduction des adresses physiques invitées en adresses hôte est réalisée par une seconde table des pages, appelée la ''shadow page table'', ce qui donnerait '''table des pages cachée''' en français. La table des pages cachée est prise en charge par l'hyperviseur. Toute modification de la table des pages cachée est réalisée par l'hyperviseur, les OS ne savent même pas qu'elle existe.
[[File:Shadowpagetables.png|centre|vignette|upright=2|Table des pages cachée.]]
Une autre solution demande un support matériel des tables des pages emboitées, à savoir qu'il y a un arbre de table des pages, chaque consultation de la première table des pages renvoie vers une seconde, qui renvoie vers une troisième, et ainsi de suite jusqu'à tomber sur la table des pages finale qui renvoie l'adresse physique réelle.
L'idée est l'utiliser une seule table des pages, mais d'ajouter un ou deux niveaux supplémentaires. Pour l'exemple, prenons le cas des processeurs x86. Sans virtualisation, l'OS utilise une table des pages de 4 niveaux. Avec, la table des pages a un niveau en plus, qui sont ajoutés à la fin de la dernière table des pages normale. Les niveaux ajoutés s'occupent de la traduction des adresses physiques invitées en adresses physiques hôte. Il faut que le processeur soit modifié de manière à parcourir automatiquement les niveaux ajoutés, ce qui demande quelques modifications de la TLB et du ''page table walker''.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les sections critiques et le modèle mémoire
| prevText=Les sections critiques et le modèle mémoire
| next=Le matériel réseau
| nextText=Le matériel réseau
}}
</noinclude>
2tjncty6l8fya1dqwjfjj0kmjmvv7ug
744307
744306
2025-06-08T14:20:35Z
Mewtow
31375
744307
wikitext
text/x-wiki
La virtualisation est l'ensemble des techniques qui permettent de faire tourner plusieurs systèmes d'exploitation en même temps. Le terme est polysémique, mais c'est la définition que nous allons utiliser pour ce qui nous intéresse. La virtualisation demande d'utiliser un logiciel dit '''hyperviseur''', qui permet de faire tourner plusieurs OS en même temps. Les hyperviseurs sont en quelque sorte situés sous le système d'exploitation et on peut les voir comme une sorte de sous-système d'exploitation, de système d'exploitation pour les systèmes d'exploitation.
[[File:Diagramme ArchiHyperviseur.png|centre|vignette|upright=2|Différence entre système d'exploitation et hyperviseur.]]
Les processeurs modernes intègrent des techniques pour accélérer matériellement la virtualisation. Les techniques en question sont assez variées, allant d'un niveau de privilège en plus des modes noyau/utilisateur à des techniques de duplication de ces mêmes modes. Les techniques de virtualisation demandent de détourner des interruptions, ce qui fait que ces techniques d'accélération demandent de modifier la manière dont le processeur gère les interruptions. Mais pour comprendre tout cela, il va falloir faire quelques explications sur la virtualisation elle-même.
==Les machines virtuelles==
Pour faire tourner plusieurs OS en même temps, l'hyperviseur recourt à de nombreux stratagèmes. Il doit partager le processeur, la RAM et les entrées-sorties entre plusieurs OS. Les trois demandent des techniques différentes. Le partage de la RAM demande concrètement des modifications au niveau de la mémoire virtuelle. Le partage du processeur est assez simple : les OS s'exécutent à tour de rôle sur le processeur, chacun pendant un temps défini, fixe. Une fois leur temps d'exécution passé, ils laissent la main à l'OS suivant. C'est l’hyperviseur qui s'occupe de tout cela, grâce à une interruption commandée à un ''timer''. Ce système de partage est une forme de '''multiplexage'''.
La gestion des entrées-sorties demande d'utiliser des techniques d''''émulation''', plus complexes à expliquer. Un hyperviseur peut parfaitement simuler du matériel qui n'est pas installé sur l'ordinateur. Par exemple, il peut faire croire à un OS qu'une carte réseau obsolète, datant d'il y a 20 ans, est installée sur l'ordinateur, alors que ce n'est pas le cas. Les commandes envoyées par l'OS à cette carte réseau fictive sont en réalité traitées par une vraie carte réseau par l’hyperviseur. Pour cela, l’hyperviseur intercepte les commandes envoyées aux entrées-sorties, et les traduit en commandes compatibles avec les entrées-sorties réellement installées sur l'ordinateur.
L'exemple avec la carte réseau est un cas particulier, l'hyperviseur faisant beaucoup de choses dans le genre. L'hyperviseur peut faire croire à l'ordinateur qu'il a plus ou moins de RAM que ce qui est réellement installé, par exemple. L'hyperviseur implémente ce qu'on appelle des '''machines virtuelles'''. Il s'agit d'une sorte de faux matériel, simulé par un logiciel. Un logiciel qui s’exécute dans une machine virtuelle aura l'impression de s’exécuter sur un matériel et/ou un O.S différent du matériel sur lequel il est en train de s’exécuter.
: Dans ce qui suit, nous parlerons de V.M (virtual machine), pour parler des machines virtuelles.
[[File:VM-monitor-french.png|centre|vignette|upright=2|Machines virtuelles avec la virtualisation.]]
L'hyperviseur crée plusieurs machines virtuelles, chacune étant réservée à un système d'exploitation. Il s'agit là d'une des utilisations possibles, mais il y en a d'autres. La plus intéressante est celle des émulateurs. Ces derniers sont des logiciels qui permettent de simuler le fonctionnement d'anciens ordinateurs ou consoles de jeux. L'émulateur crée une machine virtuelle qui est réservée à un programme, à savoir le jeu à émuler.
Il y a une différence de taille entre un émulateur et un hyperviseur. L'émulation émule une machine virtuelle totalement différente, alors que la virtualisation doit émuler les entrées-sorties mais pas le processeur. Avec un hyperviseur, le système d'exploitation s'exécute sur le processeur lui-même. Le code de l'OS est compatible avec le processeur de la machine, dans le sens où il est compilé pour le jeu d'instruction du processeur de la machine réelle. Les instructions de l'OS s'exécutent directement. Par contre, un émulateur exécute un jeu qui est programmé pour une machine dont le processeur est totalement différent. Le jeu d'instruction de la machine virtuelle et celui du vrai processeur n'est pas le même. L'émulation implique donc de traduire les instructions à exécuter dans la V.M par des instructions exécutables par le processeur. Ce n'est pas le cas avec la virtualisation, le jeu d'instruction étant le même.
[[File:Diagramme ArchiEmulateurNonNatif.png|centre|vignette|upright=2|Emulateur]]
==La virtualisation du CPU par détournement d'interruptions==
Pour être considéré comme un logiciel de virtualisation, un logiciel doit remplir trois critères :
* L'équivalence : l'O.S virtualisé et les applications qui s’exécutent doivent se comporter comme s'ils étaient exécutés sur le matériel de base, sans virtualisation.
* L'efficacité : La grande partie des instructions machines doit s’exécuter directement sur le processeur, afin de garder des performances correctes. Ce critère n'est pas respecté par les émulateurs matériels, qui doivent simuler le jeu d'instruction du processeur émulé.
* Le contrôle des ressources : tout accès au matériel par l'O.S virtualisé doit être intercepté par la machine virtuelle et intégralement pris en charge par l'hyperviseur.
===La méthode ''trap and emulate'' basique===
Remplir ces trois critères est possible sous certaines conditions, établies par les théorèmes de Popek et Goldberg. Ces théorèmes se basent sur la présence de différents types d'instructions machines. Pour rappel, il faut distinguer les instructions privilégiées de celles qui ne le sont pas. Les instructions privilégiées ne peuvent s'exécuter que en mode noyau, les programmes en mode utilisateur ne peuvent pas les exécuter.
Parmi les instructions privilégiées on peut distinguer un sous-groupe appelé les '''instructions systèmes'''. Le premier type regroupe les '''instructions d'accès aux entrées-sorties''', aussi appelées instructions sensibles à la configuration. Le second type est celui des '''instructions de configuration du processeur''', qui agissent sur les registres de contrôle du processeur, aussi appelées instructions sensibles au comportement.
La théorie de Popek et Goldberg dit qu'il est possible de virtualiser un O.S à une condition : que les instructions systèmes soient toutes des instructions privilégiées, c’est-à-dire exécutables seulement en mode noyau. Virtualiser un O.S demande simplement de le démarrer en mode utilisateur. Quand l'O.S fait un accès au matériel, il le fait via une instruction privilégiée. Vu que l'OS est en mode utilisateur, cela déclenche une exception matérielle, qui émule l'instruction privilégiée.
L'hyperviseur n'est ni plus ni moins qu'un ensemble de routines d'interruptions, chaque routine simulant le fonctionnement du matériel émulé. Par exemple, un accès au disque dur sera émulé par une routine d'interruption, qui utilisera les appels systèmes fournit par l'OS pour accéder au disque dur réellement présent dans l'ordinateur. Cette méthode est souvent appelée la méthode ''trap and emulate''.
[[File:Virtualisation avec la méthode trap-and-emulate.png|centre|vignette|upright=2.0|Virtualisation avec la méthode trap-and-emulate]]
===Le mode hyperviseur pour la virtualisation===
Sur certains CPU modernes, il existe un niveau de privilège appelé le '''mode hyperviseur''' qui est utilisé pour les techniques de virtualisation. Le mode hyperviseur est réservé à l’hyperviseur et il a des droits d'accès spécifiques. Il n'est cependant pas toujours activé. Par exemple, si aucun hyperviseur n'est installé sur la machine, le processeur dispose seulement d'un mode noyau et d'un mode utilisateur normaux, le mode noyau n'ayant alors aucune limitation précise. Mais quand le mode hyperviseur est activé, une partie des manipulations est bloquée en mode noyau et n'est possible qu'en mode hyperviseur.
Le fonctionnement se base sur la différence entre instruction privilégiée et instruction système. Les instructions privilégiées peuvent s'exécuter en mode noyau, alors que les instructions systèmes ne peuvent s'exécuter qu'en mode hyperviseur. L'idée est que quand le noyau d'un OS exécute une instruction système, une exception matérielle est levée. L'exception bascule en mode hyperviseur et laisse la main à une routine de l'hyperviseur. L'hyperviseur fait alors des manipulations précise pour que l'instruction système donne le même résultat que si elle avait été exécutée par l'ordinateur simulé par la machine virtuelle.
[[File:Virtualisation avec un mode hyperviseur.png|centre|vignette|upright=2|Virtualisation avec un mode hyperviseur.]]
Il est ainsi possible d'émuler des entrées-sorties avec un cout en performance assez léger. Précisément, ce mode hyperviseur améliore les performances de la méthode du ''trap-and-emulate''. La méthode ''trap-and-emulate'' basique exécute une exception matérielle pour toute instruction privilégiées, qu'elle soit une instruction système ou non. Mais avec le mode hyperviseur, seules les instructions systèmes déclenchent une exception, pas les instructions privilégiées non-système. Les performances sont donc un peu meilleures, pour un résultat identique. Après tout, les entrées-sorties et la configuration du processeur suffisent à émuler une machine virtuelle, les autres instructions noyau ne le sont pas.
Sur les processeurs ARM, il est possible de configurer quelles instructions sont détournées vers le mode hyperviseur et celles qui restent en mode noyau. En clair, on peut configurer quelles sont les instructions systèmes et celles qui sont simplement privilégiées. Et il en est de même pour les interruptions : on peut configurer si elles exécutent la routine de l'OS normal en mode noyau, ou si elles déclenchent une exception matérielle qui redirige vers une routine de l’hyperviseur. En l'absence d'hyperviseur, toutes les interruptions redirigent vers la routine de l'OS normale, vers le mode noyau.
===Le jeu d'instruction peut être incompatible avec le ''trap and emulate''===
Le critère précédent n'est pas respecté par beaucoup de jeux d'instructions. Par exemple, ce n'est pas le cas sur les processeurs x86, qu'ils soient 32 bits. Diverses instructions systèmes ne sont pas des instructions privilégiées. Par exemple, les instructions qui manipulent les drapeaux d'interruption ne sont pas toutes des instructions privilégiées. Il en est de même avec les instructions qui manipulent les registres pour la segmentation, celles liées aux ''call gates'', etc. A cause de cela, il est impossible d'utiliser la méthode du ''trap and emulate''. La seule solution qui ne requiert pas de techniques matérielles est de traduire à la volée les instructions systèmes problématiques en appels systèmes équivalents, grâce à des techniques de '''réécriture de code'''.
D'autres limitations font que la méthode ''trap and emulate'' ne fonctionne pas. Déjà, il faut que l'ordinateur utilise la mémoire virtuelle, sans quoi plusieurs OS ne peuvent pas se partager la même mémoire physique. De plus, il ne faut pas que la mémoire physique, non-virtuelle, puisse être adressée directement. Et cette contrainte est violée, par exemple sur les architectures MIPS qui exposent des portions de la mémoire physique dans certaines zones fixées à l'avance de la mémoire virtuelle. l'OS est compilé pour utiliser ces zones de mémoire pour accéder aux entrées-sorties mappées en mémoire, entre autres. En théorie, on peut passer outre le problème en marquant ces zones de mémoire comme inaccessibles, toute lecture/écriture à ces adresses déclenche alors une exception traitée par l'hyperviseur. Mais le cout en performance est alors trop important.
Enfin, certaines instructions dites '''sensibles au contexte''' ont un comportement différent entre le mode noyau et le mode utilisateur. En présence de telles instructions, la méthode ''trap and emulate'' ne fonctionne tout simplement pas. Grâce à ces instructions, le système d’exploitation ou un programme applicatif peut savoir s'il s'exécute en mode utilisateur ou noyau, ou hyperviseur, ou autre.
Les processeurs ARM de version v8 et plus incorporent un mode hyperviseur, mais pas les processeurs x86. A la place, ils incorporent des technologies alternatives nommées Intel Vtx ou l'AMD-V. Elles fonctionnent sur un principe totalement différent.
==La virtualisation de la mémoire RAM==
Avec la virtualisation, les différentes machines virtuelles, les différents OS doivent se partager la mémoire physique. Et ce partage doit isoler les différents OS les uns des autres. Il est possible de comparer cette isolation avec l'isolation des processus : chaque OS doit avoir sa propre mémoire physique rien qu'à lui. L'idée est d'utiliser la mémoire virtuelle pour cela.
L'espace d'adressage physique vu par chaque OS est en réalité virtualisé, c’est-à-dire que c'est un espace d'adressage fictif, qui ne correspond pas à la mémoire virtuelle. Les adresses physiques vues par l'OS sont en réalité des adresses intermédiaires entre les adresses physiques liées à la RAM, et les adresses virtuelles vues par les processus. Pour les distinguer, nous parlerons d'adresses physiques de l'hôte pour parler des adresses de la RAM, et des adresses physiques invitées pour parler des adresses manipulées par les OS virtualisés. La raison est que les OS sont appelés des OS invités, alors que l'hyperviseur est parfois appelé l'OS hôte.
Sans accélération matérielle, la traduction des adresses physiques invitées en adresses hôte est réalisée par une seconde table des pages, appelée la ''shadow page table'', ce qui donnerait '''table des pages cachée''' en français. La table des pages cachée est prise en charge par l'hyperviseur. Toute modification de la table des pages cachée est réalisée par l'hyperviseur, les OS ne savent même pas qu'elle existe.
[[File:Shadowpagetables.png|centre|vignette|upright=2|Table des pages cachée.]]
Une autre solution demande un support matériel des tables des pages emboitées, à savoir qu'il y a un arbre de table des pages, chaque consultation de la première table des pages renvoie vers une seconde, qui renvoie vers une troisième, et ainsi de suite jusqu'à tomber sur la table des pages finale qui renvoie l'adresse physique réelle.
L'idée est l'utiliser une seule table des pages, mais d'ajouter un ou deux niveaux supplémentaires. Pour l'exemple, prenons le cas des processeurs x86. Sans virtualisation, l'OS utilise une table des pages de 4 niveaux. Avec, la table des pages a un niveau en plus, qui sont ajoutés à la fin de la dernière table des pages normale. Les niveaux ajoutés s'occupent de la traduction des adresses physiques invitées en adresses physiques hôte. Il faut que le processeur soit modifié de manière à parcourir automatiquement les niveaux ajoutés, ce qui demande quelques modifications de la TLB et du ''page table walker''.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les sections critiques et le modèle mémoire
| prevText=Les sections critiques et le modèle mémoire
| next=Le matériel réseau
| nextText=Le matériel réseau
}}
</noinclude>
hr3s0p8dv6j99hjee8uafifcaej7eme
744308
744307
2025-06-08T14:21:02Z
Mewtow
31375
/* Les machines virtuelles */
744308
wikitext
text/x-wiki
La virtualisation est l'ensemble des techniques qui permettent de faire tourner plusieurs systèmes d'exploitation en même temps. Le terme est polysémique, mais c'est la définition que nous allons utiliser pour ce qui nous intéresse. La virtualisation demande d'utiliser un logiciel dit '''hyperviseur''', qui permet de faire tourner plusieurs OS en même temps. Les hyperviseurs sont en quelque sorte situés sous le système d'exploitation et on peut les voir comme une sorte de sous-système d'exploitation, de système d'exploitation pour les systèmes d'exploitation.
[[File:Diagramme ArchiHyperviseur.png|centre|vignette|upright=2|Différence entre système d'exploitation et hyperviseur.]]
Les processeurs modernes intègrent des techniques pour accélérer matériellement la virtualisation. Les techniques en question sont assez variées, allant d'un niveau de privilège en plus des modes noyau/utilisateur à des techniques de duplication de ces mêmes modes. Les techniques de virtualisation demandent de détourner des interruptions, ce qui fait que ces techniques d'accélération demandent de modifier la manière dont le processeur gère les interruptions. Mais pour comprendre tout cela, il va falloir faire quelques explications sur la virtualisation elle-même.
==La virtualisation : généralités==
Pour faire tourner plusieurs OS en même temps, l'hyperviseur recourt à de nombreux stratagèmes. Il doit partager le processeur, la RAM et les entrées-sorties entre plusieurs OS. Les trois demandent des techniques différentes. Le partage de la RAM demande concrètement des modifications au niveau de la mémoire virtuelle. Le partage du processeur est assez simple : les OS s'exécutent à tour de rôle sur le processeur, chacun pendant un temps défini, fixe. Une fois leur temps d'exécution passé, ils laissent la main à l'OS suivant. C'est l’hyperviseur qui s'occupe de tout cela, grâce à une interruption commandée à un ''timer''. Ce système de partage est une forme de '''multiplexage'''.
La gestion des entrées-sorties demande d'utiliser des techniques d''''émulation''', plus complexes à expliquer. Un hyperviseur peut parfaitement simuler du matériel qui n'est pas installé sur l'ordinateur. Par exemple, il peut faire croire à un OS qu'une carte réseau obsolète, datant d'il y a 20 ans, est installée sur l'ordinateur, alors que ce n'est pas le cas. Les commandes envoyées par l'OS à cette carte réseau fictive sont en réalité traitées par une vraie carte réseau par l’hyperviseur. Pour cela, l’hyperviseur intercepte les commandes envoyées aux entrées-sorties, et les traduit en commandes compatibles avec les entrées-sorties réellement installées sur l'ordinateur.
===Les machines virtuelles===
L'exemple avec la carte réseau est un cas particulier, l'hyperviseur faisant beaucoup de choses dans le genre. L'hyperviseur peut faire croire à l'ordinateur qu'il a plus ou moins de RAM que ce qui est réellement installé, par exemple. L'hyperviseur implémente ce qu'on appelle des '''machines virtuelles'''. Il s'agit d'une sorte de faux matériel, simulé par un logiciel. Un logiciel qui s’exécute dans une machine virtuelle aura l'impression de s’exécuter sur un matériel et/ou un O.S différent du matériel sur lequel il est en train de s’exécuter.
: Dans ce qui suit, nous parlerons de V.M (virtual machine), pour parler des machines virtuelles.
[[File:VM-monitor-french.png|centre|vignette|upright=2|Machines virtuelles avec la virtualisation.]]
L'hyperviseur crée plusieurs machines virtuelles, chacune étant réservée à un système d'exploitation. Il s'agit là d'une des utilisations possibles, mais il y en a d'autres. La plus intéressante est celle des émulateurs. Ces derniers sont des logiciels qui permettent de simuler le fonctionnement d'anciens ordinateurs ou consoles de jeux. L'émulateur crée une machine virtuelle qui est réservée à un programme, à savoir le jeu à émuler.
Il y a une différence de taille entre un émulateur et un hyperviseur. L'émulation émule une machine virtuelle totalement différente, alors que la virtualisation doit émuler les entrées-sorties mais pas le processeur. Avec un hyperviseur, le système d'exploitation s'exécute sur le processeur lui-même. Le code de l'OS est compatible avec le processeur de la machine, dans le sens où il est compilé pour le jeu d'instruction du processeur de la machine réelle. Les instructions de l'OS s'exécutent directement. Par contre, un émulateur exécute un jeu qui est programmé pour une machine dont le processeur est totalement différent. Le jeu d'instruction de la machine virtuelle et celui du vrai processeur n'est pas le même. L'émulation implique donc de traduire les instructions à exécuter dans la V.M par des instructions exécutables par le processeur. Ce n'est pas le cas avec la virtualisation, le jeu d'instruction étant le même.
[[File:Diagramme ArchiEmulateurNonNatif.png|centre|vignette|upright=2|Emulateur]]
==La virtualisation du CPU par détournement d'interruptions==
Pour être considéré comme un logiciel de virtualisation, un logiciel doit remplir trois critères :
* L'équivalence : l'O.S virtualisé et les applications qui s’exécutent doivent se comporter comme s'ils étaient exécutés sur le matériel de base, sans virtualisation.
* L'efficacité : La grande partie des instructions machines doit s’exécuter directement sur le processeur, afin de garder des performances correctes. Ce critère n'est pas respecté par les émulateurs matériels, qui doivent simuler le jeu d'instruction du processeur émulé.
* Le contrôle des ressources : tout accès au matériel par l'O.S virtualisé doit être intercepté par la machine virtuelle et intégralement pris en charge par l'hyperviseur.
===La méthode ''trap and emulate'' basique===
Remplir ces trois critères est possible sous certaines conditions, établies par les théorèmes de Popek et Goldberg. Ces théorèmes se basent sur la présence de différents types d'instructions machines. Pour rappel, il faut distinguer les instructions privilégiées de celles qui ne le sont pas. Les instructions privilégiées ne peuvent s'exécuter que en mode noyau, les programmes en mode utilisateur ne peuvent pas les exécuter.
Parmi les instructions privilégiées on peut distinguer un sous-groupe appelé les '''instructions systèmes'''. Le premier type regroupe les '''instructions d'accès aux entrées-sorties''', aussi appelées instructions sensibles à la configuration. Le second type est celui des '''instructions de configuration du processeur''', qui agissent sur les registres de contrôle du processeur, aussi appelées instructions sensibles au comportement.
La théorie de Popek et Goldberg dit qu'il est possible de virtualiser un O.S à une condition : que les instructions systèmes soient toutes des instructions privilégiées, c’est-à-dire exécutables seulement en mode noyau. Virtualiser un O.S demande simplement de le démarrer en mode utilisateur. Quand l'O.S fait un accès au matériel, il le fait via une instruction privilégiée. Vu que l'OS est en mode utilisateur, cela déclenche une exception matérielle, qui émule l'instruction privilégiée.
L'hyperviseur n'est ni plus ni moins qu'un ensemble de routines d'interruptions, chaque routine simulant le fonctionnement du matériel émulé. Par exemple, un accès au disque dur sera émulé par une routine d'interruption, qui utilisera les appels systèmes fournit par l'OS pour accéder au disque dur réellement présent dans l'ordinateur. Cette méthode est souvent appelée la méthode ''trap and emulate''.
[[File:Virtualisation avec la méthode trap-and-emulate.png|centre|vignette|upright=2.0|Virtualisation avec la méthode trap-and-emulate]]
===Le mode hyperviseur pour la virtualisation===
Sur certains CPU modernes, il existe un niveau de privilège appelé le '''mode hyperviseur''' qui est utilisé pour les techniques de virtualisation. Le mode hyperviseur est réservé à l’hyperviseur et il a des droits d'accès spécifiques. Il n'est cependant pas toujours activé. Par exemple, si aucun hyperviseur n'est installé sur la machine, le processeur dispose seulement d'un mode noyau et d'un mode utilisateur normaux, le mode noyau n'ayant alors aucune limitation précise. Mais quand le mode hyperviseur est activé, une partie des manipulations est bloquée en mode noyau et n'est possible qu'en mode hyperviseur.
Le fonctionnement se base sur la différence entre instruction privilégiée et instruction système. Les instructions privilégiées peuvent s'exécuter en mode noyau, alors que les instructions systèmes ne peuvent s'exécuter qu'en mode hyperviseur. L'idée est que quand le noyau d'un OS exécute une instruction système, une exception matérielle est levée. L'exception bascule en mode hyperviseur et laisse la main à une routine de l'hyperviseur. L'hyperviseur fait alors des manipulations précise pour que l'instruction système donne le même résultat que si elle avait été exécutée par l'ordinateur simulé par la machine virtuelle.
[[File:Virtualisation avec un mode hyperviseur.png|centre|vignette|upright=2|Virtualisation avec un mode hyperviseur.]]
Il est ainsi possible d'émuler des entrées-sorties avec un cout en performance assez léger. Précisément, ce mode hyperviseur améliore les performances de la méthode du ''trap-and-emulate''. La méthode ''trap-and-emulate'' basique exécute une exception matérielle pour toute instruction privilégiées, qu'elle soit une instruction système ou non. Mais avec le mode hyperviseur, seules les instructions systèmes déclenchent une exception, pas les instructions privilégiées non-système. Les performances sont donc un peu meilleures, pour un résultat identique. Après tout, les entrées-sorties et la configuration du processeur suffisent à émuler une machine virtuelle, les autres instructions noyau ne le sont pas.
Sur les processeurs ARM, il est possible de configurer quelles instructions sont détournées vers le mode hyperviseur et celles qui restent en mode noyau. En clair, on peut configurer quelles sont les instructions systèmes et celles qui sont simplement privilégiées. Et il en est de même pour les interruptions : on peut configurer si elles exécutent la routine de l'OS normal en mode noyau, ou si elles déclenchent une exception matérielle qui redirige vers une routine de l’hyperviseur. En l'absence d'hyperviseur, toutes les interruptions redirigent vers la routine de l'OS normale, vers le mode noyau.
===Le jeu d'instruction peut être incompatible avec le ''trap and emulate''===
Le critère précédent n'est pas respecté par beaucoup de jeux d'instructions. Par exemple, ce n'est pas le cas sur les processeurs x86, qu'ils soient 32 bits. Diverses instructions systèmes ne sont pas des instructions privilégiées. Par exemple, les instructions qui manipulent les drapeaux d'interruption ne sont pas toutes des instructions privilégiées. Il en est de même avec les instructions qui manipulent les registres pour la segmentation, celles liées aux ''call gates'', etc. A cause de cela, il est impossible d'utiliser la méthode du ''trap and emulate''. La seule solution qui ne requiert pas de techniques matérielles est de traduire à la volée les instructions systèmes problématiques en appels systèmes équivalents, grâce à des techniques de '''réécriture de code'''.
D'autres limitations font que la méthode ''trap and emulate'' ne fonctionne pas. Déjà, il faut que l'ordinateur utilise la mémoire virtuelle, sans quoi plusieurs OS ne peuvent pas se partager la même mémoire physique. De plus, il ne faut pas que la mémoire physique, non-virtuelle, puisse être adressée directement. Et cette contrainte est violée, par exemple sur les architectures MIPS qui exposent des portions de la mémoire physique dans certaines zones fixées à l'avance de la mémoire virtuelle. l'OS est compilé pour utiliser ces zones de mémoire pour accéder aux entrées-sorties mappées en mémoire, entre autres. En théorie, on peut passer outre le problème en marquant ces zones de mémoire comme inaccessibles, toute lecture/écriture à ces adresses déclenche alors une exception traitée par l'hyperviseur. Mais le cout en performance est alors trop important.
Enfin, certaines instructions dites '''sensibles au contexte''' ont un comportement différent entre le mode noyau et le mode utilisateur. En présence de telles instructions, la méthode ''trap and emulate'' ne fonctionne tout simplement pas. Grâce à ces instructions, le système d’exploitation ou un programme applicatif peut savoir s'il s'exécute en mode utilisateur ou noyau, ou hyperviseur, ou autre.
Les processeurs ARM de version v8 et plus incorporent un mode hyperviseur, mais pas les processeurs x86. A la place, ils incorporent des technologies alternatives nommées Intel Vtx ou l'AMD-V. Elles fonctionnent sur un principe totalement différent.
==La virtualisation de la mémoire RAM==
Avec la virtualisation, les différentes machines virtuelles, les différents OS doivent se partager la mémoire physique. Et ce partage doit isoler les différents OS les uns des autres. Il est possible de comparer cette isolation avec l'isolation des processus : chaque OS doit avoir sa propre mémoire physique rien qu'à lui. L'idée est d'utiliser la mémoire virtuelle pour cela.
L'espace d'adressage physique vu par chaque OS est en réalité virtualisé, c’est-à-dire que c'est un espace d'adressage fictif, qui ne correspond pas à la mémoire virtuelle. Les adresses physiques vues par l'OS sont en réalité des adresses intermédiaires entre les adresses physiques liées à la RAM, et les adresses virtuelles vues par les processus. Pour les distinguer, nous parlerons d'adresses physiques de l'hôte pour parler des adresses de la RAM, et des adresses physiques invitées pour parler des adresses manipulées par les OS virtualisés. La raison est que les OS sont appelés des OS invités, alors que l'hyperviseur est parfois appelé l'OS hôte.
Sans accélération matérielle, la traduction des adresses physiques invitées en adresses hôte est réalisée par une seconde table des pages, appelée la ''shadow page table'', ce qui donnerait '''table des pages cachée''' en français. La table des pages cachée est prise en charge par l'hyperviseur. Toute modification de la table des pages cachée est réalisée par l'hyperviseur, les OS ne savent même pas qu'elle existe.
[[File:Shadowpagetables.png|centre|vignette|upright=2|Table des pages cachée.]]
Une autre solution demande un support matériel des tables des pages emboitées, à savoir qu'il y a un arbre de table des pages, chaque consultation de la première table des pages renvoie vers une seconde, qui renvoie vers une troisième, et ainsi de suite jusqu'à tomber sur la table des pages finale qui renvoie l'adresse physique réelle.
L'idée est l'utiliser une seule table des pages, mais d'ajouter un ou deux niveaux supplémentaires. Pour l'exemple, prenons le cas des processeurs x86. Sans virtualisation, l'OS utilise une table des pages de 4 niveaux. Avec, la table des pages a un niveau en plus, qui sont ajoutés à la fin de la dernière table des pages normale. Les niveaux ajoutés s'occupent de la traduction des adresses physiques invitées en adresses physiques hôte. Il faut que le processeur soit modifié de manière à parcourir automatiquement les niveaux ajoutés, ce qui demande quelques modifications de la TLB et du ''page table walker''.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les sections critiques et le modèle mémoire
| prevText=Les sections critiques et le modèle mémoire
| next=Le matériel réseau
| nextText=Le matériel réseau
}}
</noinclude>
an4601m5c41f2k29dzj71qrnjwxkcqd
744309
744308
2025-06-08T14:24:54Z
Mewtow
31375
/* La virtualisation du CPU par détournement d'interruptions */
744309
wikitext
text/x-wiki
La virtualisation est l'ensemble des techniques qui permettent de faire tourner plusieurs systèmes d'exploitation en même temps. Le terme est polysémique, mais c'est la définition que nous allons utiliser pour ce qui nous intéresse. La virtualisation demande d'utiliser un logiciel dit '''hyperviseur''', qui permet de faire tourner plusieurs OS en même temps. Les hyperviseurs sont en quelque sorte situés sous le système d'exploitation et on peut les voir comme une sorte de sous-système d'exploitation, de système d'exploitation pour les systèmes d'exploitation.
[[File:Diagramme ArchiHyperviseur.png|centre|vignette|upright=2|Différence entre système d'exploitation et hyperviseur.]]
Les processeurs modernes intègrent des techniques pour accélérer matériellement la virtualisation. Les techniques en question sont assez variées, allant d'un niveau de privilège en plus des modes noyau/utilisateur à des techniques de duplication de ces mêmes modes. Les techniques de virtualisation demandent de détourner des interruptions, ce qui fait que ces techniques d'accélération demandent de modifier la manière dont le processeur gère les interruptions. Mais pour comprendre tout cela, il va falloir faire quelques explications sur la virtualisation elle-même.
==La virtualisation : généralités==
Pour faire tourner plusieurs OS en même temps, l'hyperviseur recourt à de nombreux stratagèmes. Il doit partager le processeur, la RAM et les entrées-sorties entre plusieurs OS. Les trois demandent des techniques différentes. Le partage de la RAM demande concrètement des modifications au niveau de la mémoire virtuelle. Le partage du processeur est assez simple : les OS s'exécutent à tour de rôle sur le processeur, chacun pendant un temps défini, fixe. Une fois leur temps d'exécution passé, ils laissent la main à l'OS suivant. C'est l’hyperviseur qui s'occupe de tout cela, grâce à une interruption commandée à un ''timer''. Ce système de partage est une forme de '''multiplexage'''.
La gestion des entrées-sorties demande d'utiliser des techniques d''''émulation''', plus complexes à expliquer. Un hyperviseur peut parfaitement simuler du matériel qui n'est pas installé sur l'ordinateur. Par exemple, il peut faire croire à un OS qu'une carte réseau obsolète, datant d'il y a 20 ans, est installée sur l'ordinateur, alors que ce n'est pas le cas. Les commandes envoyées par l'OS à cette carte réseau fictive sont en réalité traitées par une vraie carte réseau par l’hyperviseur. Pour cela, l’hyperviseur intercepte les commandes envoyées aux entrées-sorties, et les traduit en commandes compatibles avec les entrées-sorties réellement installées sur l'ordinateur.
===Les machines virtuelles===
L'exemple avec la carte réseau est un cas particulier, l'hyperviseur faisant beaucoup de choses dans le genre. L'hyperviseur peut faire croire à l'ordinateur qu'il a plus ou moins de RAM que ce qui est réellement installé, par exemple. L'hyperviseur implémente ce qu'on appelle des '''machines virtuelles'''. Il s'agit d'une sorte de faux matériel, simulé par un logiciel. Un logiciel qui s’exécute dans une machine virtuelle aura l'impression de s’exécuter sur un matériel et/ou un O.S différent du matériel sur lequel il est en train de s’exécuter.
: Dans ce qui suit, nous parlerons de V.M (virtual machine), pour parler des machines virtuelles.
[[File:VM-monitor-french.png|centre|vignette|upright=2|Machines virtuelles avec la virtualisation.]]
L'hyperviseur crée plusieurs machines virtuelles, chacune étant réservée à un système d'exploitation. Il s'agit là d'une des utilisations possibles, mais il y en a d'autres. La plus intéressante est celle des émulateurs. Ces derniers sont des logiciels qui permettent de simuler le fonctionnement d'anciens ordinateurs ou consoles de jeux. L'émulateur crée une machine virtuelle qui est réservée à un programme, à savoir le jeu à émuler.
Il y a une différence de taille entre un émulateur et un hyperviseur. L'émulation émule une machine virtuelle totalement différente, alors que la virtualisation doit émuler les entrées-sorties mais pas le processeur. Avec un hyperviseur, le système d'exploitation s'exécute sur le processeur lui-même. Le code de l'OS est compatible avec le processeur de la machine, dans le sens où il est compilé pour le jeu d'instruction du processeur de la machine réelle. Les instructions de l'OS s'exécutent directement. Par contre, un émulateur exécute un jeu qui est programmé pour une machine dont le processeur est totalement différent. Le jeu d'instruction de la machine virtuelle et celui du vrai processeur n'est pas le même. L'émulation implique donc de traduire les instructions à exécuter dans la V.M par des instructions exécutables par le processeur. Ce n'est pas le cas avec la virtualisation, le jeu d'instruction étant le même.
[[File:Diagramme ArchiEmulateurNonNatif.png|centre|vignette|upright=2|Emulateur]]
==La virtualisation du CPU par détournement d'interruptions==
Pour être considéré comme un logiciel de virtualisation, un logiciel doit remplir trois critères :
* L'équivalence : l'O.S virtualisé et les applications qui s’exécutent doivent se comporter comme s'ils étaient exécutés sur le matériel de base, sans virtualisation.
* L'efficacité : La grande partie des instructions machines doit s’exécuter directement sur le processeur, afin de garder des performances correctes. Ce critère n'est pas respecté par les émulateurs matériels, qui doivent simuler le jeu d'instruction du processeur émulé.
* Le contrôle des ressources : tout accès au matériel par l'O.S virtualisé doit être intercepté par la machine virtuelle et intégralement pris en charge par l'hyperviseur.
===La méthode ''trap and emulate'' basique===
Remplir ces trois critères est possible sous certaines conditions, établies par les théorèmes de Popek et Goldberg. Ces théorèmes se basent sur la présence de différents types d'instructions machines. Pour rappel, il faut distinguer les instructions privilégiées de celles qui ne le sont pas. Les instructions privilégiées ne peuvent s'exécuter que en mode noyau, les programmes en mode utilisateur ne peuvent pas les exécuter.
Parmi les instructions privilégiées on peut distinguer un sous-groupe appelé les '''instructions systèmes'''. Le premier type regroupe les '''instructions d'accès aux entrées-sorties''', aussi appelées instructions sensibles à la configuration. Le second type est celui des '''instructions de configuration du processeur''', qui agissent sur les registres de contrôle du processeur, aussi appelées instructions sensibles au comportement.
La théorie de Popek et Goldberg dit qu'il est possible de virtualiser un O.S à une condition : que les instructions systèmes soient toutes des instructions privilégiées, c’est-à-dire exécutables seulement en mode noyau. Virtualiser un O.S demande simplement de le démarrer en mode utilisateur. Quand l'O.S fait un accès au matériel, il le fait via une instruction privilégiée. Vu que l'OS est en mode utilisateur, cela déclenche une exception matérielle, qui émule l'instruction privilégiée.
L'hyperviseur n'est ni plus ni moins qu'un ensemble de routines d'interruptions, chaque routine simulant le fonctionnement du matériel émulé. Par exemple, un accès au disque dur sera émulé par une routine d'interruption, qui utilisera les appels systèmes fournit par l'OS pour accéder au disque dur réellement présent dans l'ordinateur. Cette méthode est souvent appelée la méthode ''trap and emulate''.
[[File:Virtualisation avec la méthode trap-and-emulate.png|centre|vignette|upright=2.0|Virtualisation avec la méthode trap-and-emulate]]
===Le jeu d'instruction peut être incompatible avec le ''trap and emulate''===
Le critère précédent n'est pas respecté par beaucoup de jeux d'instructions. Par exemple, ce n'est pas le cas sur les processeurs x86, qu'ils soient 32 bits. Diverses instructions systèmes ne sont pas des instructions privilégiées. Par exemple, les instructions qui manipulent les drapeaux d'interruption ne sont pas toutes des instructions privilégiées. Il en est de même avec les instructions qui manipulent les registres pour la segmentation, celles liées aux ''call gates'', etc. A cause de cela, il est impossible d'utiliser la méthode du ''trap and emulate''. La seule solution qui ne requiert pas de techniques matérielles est de traduire à la volée les instructions systèmes problématiques en appels systèmes équivalents, grâce à des techniques de '''réécriture de code'''.
D'autres limitations font que la méthode ''trap and emulate'' ne fonctionne pas. Déjà, il faut que l'ordinateur utilise la mémoire virtuelle, sans quoi plusieurs OS ne peuvent pas se partager la même mémoire physique. De plus, il ne faut pas que la mémoire physique, non-virtuelle, puisse être adressée directement. Et cette contrainte est violée, par exemple sur les architectures MIPS qui exposent des portions de la mémoire physique dans certaines zones fixées à l'avance de la mémoire virtuelle. l'OS est compilé pour utiliser ces zones de mémoire pour accéder aux entrées-sorties mappées en mémoire, entre autres. En théorie, on peut passer outre le problème en marquant ces zones de mémoire comme inaccessibles, toute lecture/écriture à ces adresses déclenche alors une exception traitée par l'hyperviseur. Mais le cout en performance est alors trop important.
Enfin, certaines instructions dites '''sensibles au contexte''' ont un comportement différent entre le mode noyau et le mode utilisateur. En présence de telles instructions, la méthode ''trap and emulate'' ne fonctionne tout simplement pas. Grâce à ces instructions, le système d’exploitation ou un programme applicatif peut savoir s'il s'exécute en mode utilisateur ou noyau, ou hyperviseur, ou autre.
Les processeurs ARM de version v8 et plus incorporent un mode hyperviseur, mais pas les processeurs x86. A la place, ils incorporent des technologies alternatives nommées Intel Vtx ou l'AMD-V. Elles fonctionnent sur un principe totalement différent.
===Le mode hyperviseur pour la virtualisation===
Sur certains CPU modernes, il existe un niveau de privilège appelé le '''mode hyperviseur''' qui est utilisé pour les techniques de virtualisation. Le mode hyperviseur est réservé à l’hyperviseur et il a des droits d'accès spécifiques. Il n'est cependant pas toujours activé. Par exemple, si aucun hyperviseur n'est installé sur la machine, le processeur dispose seulement d'un mode noyau et d'un mode utilisateur normaux, le mode noyau n'ayant alors aucune limitation précise. Mais quand le mode hyperviseur est activé, une partie des manipulations est bloquée en mode noyau et n'est possible qu'en mode hyperviseur.
Le fonctionnement se base sur la différence entre instruction privilégiée et instruction système. Les instructions privilégiées peuvent s'exécuter en mode noyau, alors que les instructions systèmes ne peuvent s'exécuter qu'en mode hyperviseur. L'idée est que quand le noyau d'un OS exécute une instruction système, une exception matérielle est levée. L'exception bascule en mode hyperviseur et laisse la main à une routine de l'hyperviseur. L'hyperviseur fait alors des manipulations précise pour que l'instruction système donne le même résultat que si elle avait été exécutée par l'ordinateur simulé par la machine virtuelle.
[[File:Virtualisation avec un mode hyperviseur.png|centre|vignette|upright=2|Virtualisation avec un mode hyperviseur.]]
Il est ainsi possible d'émuler des entrées-sorties avec un cout en performance assez léger. Précisément, ce mode hyperviseur améliore les performances de la méthode du ''trap-and-emulate''. La méthode ''trap-and-emulate'' basique exécute une exception matérielle pour toute instruction privilégiées, qu'elle soit une instruction système ou non. Mais avec le mode hyperviseur, seules les instructions systèmes déclenchent une exception, pas les instructions privilégiées non-système. Les performances sont donc un peu meilleures, pour un résultat identique. Après tout, les entrées-sorties et la configuration du processeur suffisent à émuler une machine virtuelle, les autres instructions noyau ne le sont pas.
Sur les processeurs ARM, il est possible de configurer quelles instructions sont détournées vers le mode hyperviseur et celles qui restent en mode noyau. En clair, on peut configurer quelles sont les instructions systèmes et celles qui sont simplement privilégiées. Et il en est de même pour les interruptions : on peut configurer si elles exécutent la routine de l'OS normal en mode noyau, ou si elles déclenchent une exception matérielle qui redirige vers une routine de l’hyperviseur. En l'absence d'hyperviseur, toutes les interruptions redirigent vers la routine de l'OS normale, vers le mode noyau.
==La virtualisation de la mémoire RAM==
Avec la virtualisation, les différentes machines virtuelles, les différents OS doivent se partager la mémoire physique. Et ce partage doit isoler les différents OS les uns des autres. Il est possible de comparer cette isolation avec l'isolation des processus : chaque OS doit avoir sa propre mémoire physique rien qu'à lui. L'idée est d'utiliser la mémoire virtuelle pour cela.
L'espace d'adressage physique vu par chaque OS est en réalité virtualisé, c’est-à-dire que c'est un espace d'adressage fictif, qui ne correspond pas à la mémoire virtuelle. Les adresses physiques vues par l'OS sont en réalité des adresses intermédiaires entre les adresses physiques liées à la RAM, et les adresses virtuelles vues par les processus. Pour les distinguer, nous parlerons d'adresses physiques de l'hôte pour parler des adresses de la RAM, et des adresses physiques invitées pour parler des adresses manipulées par les OS virtualisés. La raison est que les OS sont appelés des OS invités, alors que l'hyperviseur est parfois appelé l'OS hôte.
Sans accélération matérielle, la traduction des adresses physiques invitées en adresses hôte est réalisée par une seconde table des pages, appelée la ''shadow page table'', ce qui donnerait '''table des pages cachée''' en français. La table des pages cachée est prise en charge par l'hyperviseur. Toute modification de la table des pages cachée est réalisée par l'hyperviseur, les OS ne savent même pas qu'elle existe.
[[File:Shadowpagetables.png|centre|vignette|upright=2|Table des pages cachée.]]
Une autre solution demande un support matériel des tables des pages emboitées, à savoir qu'il y a un arbre de table des pages, chaque consultation de la première table des pages renvoie vers une seconde, qui renvoie vers une troisième, et ainsi de suite jusqu'à tomber sur la table des pages finale qui renvoie l'adresse physique réelle.
L'idée est l'utiliser une seule table des pages, mais d'ajouter un ou deux niveaux supplémentaires. Pour l'exemple, prenons le cas des processeurs x86. Sans virtualisation, l'OS utilise une table des pages de 4 niveaux. Avec, la table des pages a un niveau en plus, qui sont ajoutés à la fin de la dernière table des pages normale. Les niveaux ajoutés s'occupent de la traduction des adresses physiques invitées en adresses physiques hôte. Il faut que le processeur soit modifié de manière à parcourir automatiquement les niveaux ajoutés, ce qui demande quelques modifications de la TLB et du ''page table walker''.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les sections critiques et le modèle mémoire
| prevText=Les sections critiques et le modèle mémoire
| next=Le matériel réseau
| nextText=Le matériel réseau
}}
</noinclude>
mflsaz5638cghwrmt44dw42c5l5b2si
744310
744309
2025-06-08T14:25:07Z
Mewtow
31375
/* Le jeu d'instruction peut être incompatible avec le trap and emulate */
744310
wikitext
text/x-wiki
La virtualisation est l'ensemble des techniques qui permettent de faire tourner plusieurs systèmes d'exploitation en même temps. Le terme est polysémique, mais c'est la définition que nous allons utiliser pour ce qui nous intéresse. La virtualisation demande d'utiliser un logiciel dit '''hyperviseur''', qui permet de faire tourner plusieurs OS en même temps. Les hyperviseurs sont en quelque sorte situés sous le système d'exploitation et on peut les voir comme une sorte de sous-système d'exploitation, de système d'exploitation pour les systèmes d'exploitation.
[[File:Diagramme ArchiHyperviseur.png|centre|vignette|upright=2|Différence entre système d'exploitation et hyperviseur.]]
Les processeurs modernes intègrent des techniques pour accélérer matériellement la virtualisation. Les techniques en question sont assez variées, allant d'un niveau de privilège en plus des modes noyau/utilisateur à des techniques de duplication de ces mêmes modes. Les techniques de virtualisation demandent de détourner des interruptions, ce qui fait que ces techniques d'accélération demandent de modifier la manière dont le processeur gère les interruptions. Mais pour comprendre tout cela, il va falloir faire quelques explications sur la virtualisation elle-même.
==La virtualisation : généralités==
Pour faire tourner plusieurs OS en même temps, l'hyperviseur recourt à de nombreux stratagèmes. Il doit partager le processeur, la RAM et les entrées-sorties entre plusieurs OS. Les trois demandent des techniques différentes. Le partage de la RAM demande concrètement des modifications au niveau de la mémoire virtuelle. Le partage du processeur est assez simple : les OS s'exécutent à tour de rôle sur le processeur, chacun pendant un temps défini, fixe. Une fois leur temps d'exécution passé, ils laissent la main à l'OS suivant. C'est l’hyperviseur qui s'occupe de tout cela, grâce à une interruption commandée à un ''timer''. Ce système de partage est une forme de '''multiplexage'''.
La gestion des entrées-sorties demande d'utiliser des techniques d''''émulation''', plus complexes à expliquer. Un hyperviseur peut parfaitement simuler du matériel qui n'est pas installé sur l'ordinateur. Par exemple, il peut faire croire à un OS qu'une carte réseau obsolète, datant d'il y a 20 ans, est installée sur l'ordinateur, alors que ce n'est pas le cas. Les commandes envoyées par l'OS à cette carte réseau fictive sont en réalité traitées par une vraie carte réseau par l’hyperviseur. Pour cela, l’hyperviseur intercepte les commandes envoyées aux entrées-sorties, et les traduit en commandes compatibles avec les entrées-sorties réellement installées sur l'ordinateur.
===Les machines virtuelles===
L'exemple avec la carte réseau est un cas particulier, l'hyperviseur faisant beaucoup de choses dans le genre. L'hyperviseur peut faire croire à l'ordinateur qu'il a plus ou moins de RAM que ce qui est réellement installé, par exemple. L'hyperviseur implémente ce qu'on appelle des '''machines virtuelles'''. Il s'agit d'une sorte de faux matériel, simulé par un logiciel. Un logiciel qui s’exécute dans une machine virtuelle aura l'impression de s’exécuter sur un matériel et/ou un O.S différent du matériel sur lequel il est en train de s’exécuter.
: Dans ce qui suit, nous parlerons de V.M (virtual machine), pour parler des machines virtuelles.
[[File:VM-monitor-french.png|centre|vignette|upright=2|Machines virtuelles avec la virtualisation.]]
L'hyperviseur crée plusieurs machines virtuelles, chacune étant réservée à un système d'exploitation. Il s'agit là d'une des utilisations possibles, mais il y en a d'autres. La plus intéressante est celle des émulateurs. Ces derniers sont des logiciels qui permettent de simuler le fonctionnement d'anciens ordinateurs ou consoles de jeux. L'émulateur crée une machine virtuelle qui est réservée à un programme, à savoir le jeu à émuler.
Il y a une différence de taille entre un émulateur et un hyperviseur. L'émulation émule une machine virtuelle totalement différente, alors que la virtualisation doit émuler les entrées-sorties mais pas le processeur. Avec un hyperviseur, le système d'exploitation s'exécute sur le processeur lui-même. Le code de l'OS est compatible avec le processeur de la machine, dans le sens où il est compilé pour le jeu d'instruction du processeur de la machine réelle. Les instructions de l'OS s'exécutent directement. Par contre, un émulateur exécute un jeu qui est programmé pour une machine dont le processeur est totalement différent. Le jeu d'instruction de la machine virtuelle et celui du vrai processeur n'est pas le même. L'émulation implique donc de traduire les instructions à exécuter dans la V.M par des instructions exécutables par le processeur. Ce n'est pas le cas avec la virtualisation, le jeu d'instruction étant le même.
[[File:Diagramme ArchiEmulateurNonNatif.png|centre|vignette|upright=2|Emulateur]]
==La virtualisation du CPU par détournement d'interruptions==
Pour être considéré comme un logiciel de virtualisation, un logiciel doit remplir trois critères :
* L'équivalence : l'O.S virtualisé et les applications qui s’exécutent doivent se comporter comme s'ils étaient exécutés sur le matériel de base, sans virtualisation.
* L'efficacité : La grande partie des instructions machines doit s’exécuter directement sur le processeur, afin de garder des performances correctes. Ce critère n'est pas respecté par les émulateurs matériels, qui doivent simuler le jeu d'instruction du processeur émulé.
* Le contrôle des ressources : tout accès au matériel par l'O.S virtualisé doit être intercepté par la machine virtuelle et intégralement pris en charge par l'hyperviseur.
===La méthode ''trap and emulate'' basique===
Remplir ces trois critères est possible sous certaines conditions, établies par les théorèmes de Popek et Goldberg. Ces théorèmes se basent sur la présence de différents types d'instructions machines. Pour rappel, il faut distinguer les instructions privilégiées de celles qui ne le sont pas. Les instructions privilégiées ne peuvent s'exécuter que en mode noyau, les programmes en mode utilisateur ne peuvent pas les exécuter.
Parmi les instructions privilégiées on peut distinguer un sous-groupe appelé les '''instructions systèmes'''. Le premier type regroupe les '''instructions d'accès aux entrées-sorties''', aussi appelées instructions sensibles à la configuration. Le second type est celui des '''instructions de configuration du processeur''', qui agissent sur les registres de contrôle du processeur, aussi appelées instructions sensibles au comportement.
La théorie de Popek et Goldberg dit qu'il est possible de virtualiser un O.S à une condition : que les instructions systèmes soient toutes des instructions privilégiées, c’est-à-dire exécutables seulement en mode noyau. Virtualiser un O.S demande simplement de le démarrer en mode utilisateur. Quand l'O.S fait un accès au matériel, il le fait via une instruction privilégiée. Vu que l'OS est en mode utilisateur, cela déclenche une exception matérielle, qui émule l'instruction privilégiée.
L'hyperviseur n'est ni plus ni moins qu'un ensemble de routines d'interruptions, chaque routine simulant le fonctionnement du matériel émulé. Par exemple, un accès au disque dur sera émulé par une routine d'interruption, qui utilisera les appels systèmes fournit par l'OS pour accéder au disque dur réellement présent dans l'ordinateur. Cette méthode est souvent appelée la méthode ''trap and emulate''.
[[File:Virtualisation avec la méthode trap-and-emulate.png|centre|vignette|upright=2.0|Virtualisation avec la méthode trap-and-emulate]]
===Le jeu d'instruction peut être incompatible avec le ''trap and emulate''===
Le critère précédent n'est pas respecté par beaucoup de jeux d'instructions. Par exemple, ce n'est pas le cas sur les processeurs x86, qu'ils soient 32 bits. Diverses instructions systèmes ne sont pas des instructions privilégiées. Par exemple, les instructions qui manipulent les drapeaux d'interruption ne sont pas toutes des instructions privilégiées. Il en est de même avec les instructions qui manipulent les registres pour la segmentation, celles liées aux ''call gates'', etc. A cause de cela, il est impossible d'utiliser la méthode du ''trap and emulate''. La seule solution qui ne requiert pas de techniques matérielles est de traduire à la volée les instructions systèmes problématiques en appels systèmes équivalents, grâce à des techniques de '''réécriture de code'''.
D'autres limitations font que la méthode ''trap and emulate'' ne fonctionne pas. Déjà, il faut que l'ordinateur utilise la mémoire virtuelle, sans quoi plusieurs OS ne peuvent pas se partager la même mémoire physique. De plus, il ne faut pas que la mémoire physique, non-virtuelle, puisse être adressée directement. Et cette contrainte est violée, par exemple sur les architectures MIPS qui exposent des portions de la mémoire physique dans certaines zones fixées à l'avance de la mémoire virtuelle. l'OS est compilé pour utiliser ces zones de mémoire pour accéder aux entrées-sorties mappées en mémoire, entre autres. En théorie, on peut passer outre le problème en marquant ces zones de mémoire comme inaccessibles, toute lecture/écriture à ces adresses déclenche alors une exception traitée par l'hyperviseur. Mais le cout en performance est alors trop important.
Enfin, certaines instructions dites '''sensibles au contexte''' ont un comportement différent entre le mode noyau et le mode utilisateur. En présence de telles instructions, la méthode ''trap and emulate'' ne fonctionne tout simplement pas. Grâce à ces instructions, le système d’exploitation ou un programme applicatif peut savoir s'il s'exécute en mode utilisateur ou noyau, ou hyperviseur, ou autre.
===Le mode hyperviseur pour la virtualisation===
Sur certains CPU modernes, il existe un niveau de privilège appelé le '''mode hyperviseur''' qui est utilisé pour les techniques de virtualisation. Le mode hyperviseur est réservé à l’hyperviseur et il a des droits d'accès spécifiques. Il n'est cependant pas toujours activé. Par exemple, si aucun hyperviseur n'est installé sur la machine, le processeur dispose seulement d'un mode noyau et d'un mode utilisateur normaux, le mode noyau n'ayant alors aucune limitation précise. Mais quand le mode hyperviseur est activé, une partie des manipulations est bloquée en mode noyau et n'est possible qu'en mode hyperviseur.
Le fonctionnement se base sur la différence entre instruction privilégiée et instruction système. Les instructions privilégiées peuvent s'exécuter en mode noyau, alors que les instructions systèmes ne peuvent s'exécuter qu'en mode hyperviseur. L'idée est que quand le noyau d'un OS exécute une instruction système, une exception matérielle est levée. L'exception bascule en mode hyperviseur et laisse la main à une routine de l'hyperviseur. L'hyperviseur fait alors des manipulations précise pour que l'instruction système donne le même résultat que si elle avait été exécutée par l'ordinateur simulé par la machine virtuelle.
[[File:Virtualisation avec un mode hyperviseur.png|centre|vignette|upright=2|Virtualisation avec un mode hyperviseur.]]
Il est ainsi possible d'émuler des entrées-sorties avec un cout en performance assez léger. Précisément, ce mode hyperviseur améliore les performances de la méthode du ''trap-and-emulate''. La méthode ''trap-and-emulate'' basique exécute une exception matérielle pour toute instruction privilégiées, qu'elle soit une instruction système ou non. Mais avec le mode hyperviseur, seules les instructions systèmes déclenchent une exception, pas les instructions privilégiées non-système. Les performances sont donc un peu meilleures, pour un résultat identique. Après tout, les entrées-sorties et la configuration du processeur suffisent à émuler une machine virtuelle, les autres instructions noyau ne le sont pas.
Sur les processeurs ARM, il est possible de configurer quelles instructions sont détournées vers le mode hyperviseur et celles qui restent en mode noyau. En clair, on peut configurer quelles sont les instructions systèmes et celles qui sont simplement privilégiées. Et il en est de même pour les interruptions : on peut configurer si elles exécutent la routine de l'OS normal en mode noyau, ou si elles déclenchent une exception matérielle qui redirige vers une routine de l’hyperviseur. En l'absence d'hyperviseur, toutes les interruptions redirigent vers la routine de l'OS normale, vers le mode noyau.
==La virtualisation de la mémoire RAM==
Avec la virtualisation, les différentes machines virtuelles, les différents OS doivent se partager la mémoire physique. Et ce partage doit isoler les différents OS les uns des autres. Il est possible de comparer cette isolation avec l'isolation des processus : chaque OS doit avoir sa propre mémoire physique rien qu'à lui. L'idée est d'utiliser la mémoire virtuelle pour cela.
L'espace d'adressage physique vu par chaque OS est en réalité virtualisé, c’est-à-dire que c'est un espace d'adressage fictif, qui ne correspond pas à la mémoire virtuelle. Les adresses physiques vues par l'OS sont en réalité des adresses intermédiaires entre les adresses physiques liées à la RAM, et les adresses virtuelles vues par les processus. Pour les distinguer, nous parlerons d'adresses physiques de l'hôte pour parler des adresses de la RAM, et des adresses physiques invitées pour parler des adresses manipulées par les OS virtualisés. La raison est que les OS sont appelés des OS invités, alors que l'hyperviseur est parfois appelé l'OS hôte.
Sans accélération matérielle, la traduction des adresses physiques invitées en adresses hôte est réalisée par une seconde table des pages, appelée la ''shadow page table'', ce qui donnerait '''table des pages cachée''' en français. La table des pages cachée est prise en charge par l'hyperviseur. Toute modification de la table des pages cachée est réalisée par l'hyperviseur, les OS ne savent même pas qu'elle existe.
[[File:Shadowpagetables.png|centre|vignette|upright=2|Table des pages cachée.]]
Une autre solution demande un support matériel des tables des pages emboitées, à savoir qu'il y a un arbre de table des pages, chaque consultation de la première table des pages renvoie vers une seconde, qui renvoie vers une troisième, et ainsi de suite jusqu'à tomber sur la table des pages finale qui renvoie l'adresse physique réelle.
L'idée est l'utiliser une seule table des pages, mais d'ajouter un ou deux niveaux supplémentaires. Pour l'exemple, prenons le cas des processeurs x86. Sans virtualisation, l'OS utilise une table des pages de 4 niveaux. Avec, la table des pages a un niveau en plus, qui sont ajoutés à la fin de la dernière table des pages normale. Les niveaux ajoutés s'occupent de la traduction des adresses physiques invitées en adresses physiques hôte. Il faut que le processeur soit modifié de manière à parcourir automatiquement les niveaux ajoutés, ce qui demande quelques modifications de la TLB et du ''page table walker''.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les sections critiques et le modèle mémoire
| prevText=Les sections critiques et le modèle mémoire
| next=Le matériel réseau
| nextText=Le matériel réseau
}}
</noinclude>
0svpvd84c7b4764oktovgvetigev3zb
744311
744310
2025-06-08T14:25:14Z
Mewtow
31375
/* Le mode hyperviseur pour la virtualisation */
744311
wikitext
text/x-wiki
La virtualisation est l'ensemble des techniques qui permettent de faire tourner plusieurs systèmes d'exploitation en même temps. Le terme est polysémique, mais c'est la définition que nous allons utiliser pour ce qui nous intéresse. La virtualisation demande d'utiliser un logiciel dit '''hyperviseur''', qui permet de faire tourner plusieurs OS en même temps. Les hyperviseurs sont en quelque sorte situés sous le système d'exploitation et on peut les voir comme une sorte de sous-système d'exploitation, de système d'exploitation pour les systèmes d'exploitation.
[[File:Diagramme ArchiHyperviseur.png|centre|vignette|upright=2|Différence entre système d'exploitation et hyperviseur.]]
Les processeurs modernes intègrent des techniques pour accélérer matériellement la virtualisation. Les techniques en question sont assez variées, allant d'un niveau de privilège en plus des modes noyau/utilisateur à des techniques de duplication de ces mêmes modes. Les techniques de virtualisation demandent de détourner des interruptions, ce qui fait que ces techniques d'accélération demandent de modifier la manière dont le processeur gère les interruptions. Mais pour comprendre tout cela, il va falloir faire quelques explications sur la virtualisation elle-même.
==La virtualisation : généralités==
Pour faire tourner plusieurs OS en même temps, l'hyperviseur recourt à de nombreux stratagèmes. Il doit partager le processeur, la RAM et les entrées-sorties entre plusieurs OS. Les trois demandent des techniques différentes. Le partage de la RAM demande concrètement des modifications au niveau de la mémoire virtuelle. Le partage du processeur est assez simple : les OS s'exécutent à tour de rôle sur le processeur, chacun pendant un temps défini, fixe. Une fois leur temps d'exécution passé, ils laissent la main à l'OS suivant. C'est l’hyperviseur qui s'occupe de tout cela, grâce à une interruption commandée à un ''timer''. Ce système de partage est une forme de '''multiplexage'''.
La gestion des entrées-sorties demande d'utiliser des techniques d''''émulation''', plus complexes à expliquer. Un hyperviseur peut parfaitement simuler du matériel qui n'est pas installé sur l'ordinateur. Par exemple, il peut faire croire à un OS qu'une carte réseau obsolète, datant d'il y a 20 ans, est installée sur l'ordinateur, alors que ce n'est pas le cas. Les commandes envoyées par l'OS à cette carte réseau fictive sont en réalité traitées par une vraie carte réseau par l’hyperviseur. Pour cela, l’hyperviseur intercepte les commandes envoyées aux entrées-sorties, et les traduit en commandes compatibles avec les entrées-sorties réellement installées sur l'ordinateur.
===Les machines virtuelles===
L'exemple avec la carte réseau est un cas particulier, l'hyperviseur faisant beaucoup de choses dans le genre. L'hyperviseur peut faire croire à l'ordinateur qu'il a plus ou moins de RAM que ce qui est réellement installé, par exemple. L'hyperviseur implémente ce qu'on appelle des '''machines virtuelles'''. Il s'agit d'une sorte de faux matériel, simulé par un logiciel. Un logiciel qui s’exécute dans une machine virtuelle aura l'impression de s’exécuter sur un matériel et/ou un O.S différent du matériel sur lequel il est en train de s’exécuter.
: Dans ce qui suit, nous parlerons de V.M (virtual machine), pour parler des machines virtuelles.
[[File:VM-monitor-french.png|centre|vignette|upright=2|Machines virtuelles avec la virtualisation.]]
L'hyperviseur crée plusieurs machines virtuelles, chacune étant réservée à un système d'exploitation. Il s'agit là d'une des utilisations possibles, mais il y en a d'autres. La plus intéressante est celle des émulateurs. Ces derniers sont des logiciels qui permettent de simuler le fonctionnement d'anciens ordinateurs ou consoles de jeux. L'émulateur crée une machine virtuelle qui est réservée à un programme, à savoir le jeu à émuler.
Il y a une différence de taille entre un émulateur et un hyperviseur. L'émulation émule une machine virtuelle totalement différente, alors que la virtualisation doit émuler les entrées-sorties mais pas le processeur. Avec un hyperviseur, le système d'exploitation s'exécute sur le processeur lui-même. Le code de l'OS est compatible avec le processeur de la machine, dans le sens où il est compilé pour le jeu d'instruction du processeur de la machine réelle. Les instructions de l'OS s'exécutent directement. Par contre, un émulateur exécute un jeu qui est programmé pour une machine dont le processeur est totalement différent. Le jeu d'instruction de la machine virtuelle et celui du vrai processeur n'est pas le même. L'émulation implique donc de traduire les instructions à exécuter dans la V.M par des instructions exécutables par le processeur. Ce n'est pas le cas avec la virtualisation, le jeu d'instruction étant le même.
[[File:Diagramme ArchiEmulateurNonNatif.png|centre|vignette|upright=2|Emulateur]]
==La virtualisation du CPU par détournement d'interruptions==
Pour être considéré comme un logiciel de virtualisation, un logiciel doit remplir trois critères :
* L'équivalence : l'O.S virtualisé et les applications qui s’exécutent doivent se comporter comme s'ils étaient exécutés sur le matériel de base, sans virtualisation.
* L'efficacité : La grande partie des instructions machines doit s’exécuter directement sur le processeur, afin de garder des performances correctes. Ce critère n'est pas respecté par les émulateurs matériels, qui doivent simuler le jeu d'instruction du processeur émulé.
* Le contrôle des ressources : tout accès au matériel par l'O.S virtualisé doit être intercepté par la machine virtuelle et intégralement pris en charge par l'hyperviseur.
===La méthode ''trap and emulate'' basique===
Remplir ces trois critères est possible sous certaines conditions, établies par les théorèmes de Popek et Goldberg. Ces théorèmes se basent sur la présence de différents types d'instructions machines. Pour rappel, il faut distinguer les instructions privilégiées de celles qui ne le sont pas. Les instructions privilégiées ne peuvent s'exécuter que en mode noyau, les programmes en mode utilisateur ne peuvent pas les exécuter.
Parmi les instructions privilégiées on peut distinguer un sous-groupe appelé les '''instructions systèmes'''. Le premier type regroupe les '''instructions d'accès aux entrées-sorties''', aussi appelées instructions sensibles à la configuration. Le second type est celui des '''instructions de configuration du processeur''', qui agissent sur les registres de contrôle du processeur, aussi appelées instructions sensibles au comportement.
La théorie de Popek et Goldberg dit qu'il est possible de virtualiser un O.S à une condition : que les instructions systèmes soient toutes des instructions privilégiées, c’est-à-dire exécutables seulement en mode noyau. Virtualiser un O.S demande simplement de le démarrer en mode utilisateur. Quand l'O.S fait un accès au matériel, il le fait via une instruction privilégiée. Vu que l'OS est en mode utilisateur, cela déclenche une exception matérielle, qui émule l'instruction privilégiée.
L'hyperviseur n'est ni plus ni moins qu'un ensemble de routines d'interruptions, chaque routine simulant le fonctionnement du matériel émulé. Par exemple, un accès au disque dur sera émulé par une routine d'interruption, qui utilisera les appels systèmes fournit par l'OS pour accéder au disque dur réellement présent dans l'ordinateur. Cette méthode est souvent appelée la méthode ''trap and emulate''.
[[File:Virtualisation avec la méthode trap-and-emulate.png|centre|vignette|upright=2.0|Virtualisation avec la méthode trap-and-emulate]]
===Le jeu d'instruction peut être incompatible avec le ''trap and emulate''===
Le critère précédent n'est pas respecté par beaucoup de jeux d'instructions. Par exemple, ce n'est pas le cas sur les processeurs x86, qu'ils soient 32 bits. Diverses instructions systèmes ne sont pas des instructions privilégiées. Par exemple, les instructions qui manipulent les drapeaux d'interruption ne sont pas toutes des instructions privilégiées. Il en est de même avec les instructions qui manipulent les registres pour la segmentation, celles liées aux ''call gates'', etc. A cause de cela, il est impossible d'utiliser la méthode du ''trap and emulate''. La seule solution qui ne requiert pas de techniques matérielles est de traduire à la volée les instructions systèmes problématiques en appels systèmes équivalents, grâce à des techniques de '''réécriture de code'''.
D'autres limitations font que la méthode ''trap and emulate'' ne fonctionne pas. Déjà, il faut que l'ordinateur utilise la mémoire virtuelle, sans quoi plusieurs OS ne peuvent pas se partager la même mémoire physique. De plus, il ne faut pas que la mémoire physique, non-virtuelle, puisse être adressée directement. Et cette contrainte est violée, par exemple sur les architectures MIPS qui exposent des portions de la mémoire physique dans certaines zones fixées à l'avance de la mémoire virtuelle. l'OS est compilé pour utiliser ces zones de mémoire pour accéder aux entrées-sorties mappées en mémoire, entre autres. En théorie, on peut passer outre le problème en marquant ces zones de mémoire comme inaccessibles, toute lecture/écriture à ces adresses déclenche alors une exception traitée par l'hyperviseur. Mais le cout en performance est alors trop important.
Enfin, certaines instructions dites '''sensibles au contexte''' ont un comportement différent entre le mode noyau et le mode utilisateur. En présence de telles instructions, la méthode ''trap and emulate'' ne fonctionne tout simplement pas. Grâce à ces instructions, le système d’exploitation ou un programme applicatif peut savoir s'il s'exécute en mode utilisateur ou noyau, ou hyperviseur, ou autre.
===Le mode hyperviseur pour la virtualisation===
Sur certains CPU modernes, il existe un niveau de privilège appelé le '''mode hyperviseur''' qui est utilisé pour les techniques de virtualisation. Le mode hyperviseur est réservé à l’hyperviseur et il a des droits d'accès spécifiques. Il n'est cependant pas toujours activé. Par exemple, si aucun hyperviseur n'est installé sur la machine, le processeur dispose seulement d'un mode noyau et d'un mode utilisateur normaux, le mode noyau n'ayant alors aucune limitation précise. Mais quand le mode hyperviseur est activé, une partie des manipulations est bloquée en mode noyau et n'est possible qu'en mode hyperviseur.
Le fonctionnement se base sur la différence entre instruction privilégiée et instruction système. Les instructions privilégiées peuvent s'exécuter en mode noyau, alors que les instructions systèmes ne peuvent s'exécuter qu'en mode hyperviseur. L'idée est que quand le noyau d'un OS exécute une instruction système, une exception matérielle est levée. L'exception bascule en mode hyperviseur et laisse la main à une routine de l'hyperviseur. L'hyperviseur fait alors des manipulations précise pour que l'instruction système donne le même résultat que si elle avait été exécutée par l'ordinateur simulé par la machine virtuelle.
[[File:Virtualisation avec un mode hyperviseur.png|centre|vignette|upright=2|Virtualisation avec un mode hyperviseur.]]
Il est ainsi possible d'émuler des entrées-sorties avec un cout en performance assez léger. Précisément, ce mode hyperviseur améliore les performances de la méthode du ''trap-and-emulate''. La méthode ''trap-and-emulate'' basique exécute une exception matérielle pour toute instruction privilégiées, qu'elle soit une instruction système ou non. Mais avec le mode hyperviseur, seules les instructions systèmes déclenchent une exception, pas les instructions privilégiées non-système. Les performances sont donc un peu meilleures, pour un résultat identique. Après tout, les entrées-sorties et la configuration du processeur suffisent à émuler une machine virtuelle, les autres instructions noyau ne le sont pas.
Sur les processeurs ARM, il est possible de configurer quelles instructions sont détournées vers le mode hyperviseur et celles qui restent en mode noyau. En clair, on peut configurer quelles sont les instructions systèmes et celles qui sont simplement privilégiées. Et il en est de même pour les interruptions : on peut configurer si elles exécutent la routine de l'OS normal en mode noyau, ou si elles déclenchent une exception matérielle qui redirige vers une routine de l’hyperviseur. En l'absence d'hyperviseur, toutes les interruptions redirigent vers la routine de l'OS normale, vers le mode noyau.
Les processeurs ARM de version v8 et plus incorporent un mode hyperviseur, mais pas les processeurs x86. A la place, ils incorporent des technologies alternatives nommées Intel Vtx ou l'AMD-V. Elles fonctionnent sur un principe totalement différent.
==La virtualisation de la mémoire RAM==
Avec la virtualisation, les différentes machines virtuelles, les différents OS doivent se partager la mémoire physique. Et ce partage doit isoler les différents OS les uns des autres. Il est possible de comparer cette isolation avec l'isolation des processus : chaque OS doit avoir sa propre mémoire physique rien qu'à lui. L'idée est d'utiliser la mémoire virtuelle pour cela.
L'espace d'adressage physique vu par chaque OS est en réalité virtualisé, c’est-à-dire que c'est un espace d'adressage fictif, qui ne correspond pas à la mémoire virtuelle. Les adresses physiques vues par l'OS sont en réalité des adresses intermédiaires entre les adresses physiques liées à la RAM, et les adresses virtuelles vues par les processus. Pour les distinguer, nous parlerons d'adresses physiques de l'hôte pour parler des adresses de la RAM, et des adresses physiques invitées pour parler des adresses manipulées par les OS virtualisés. La raison est que les OS sont appelés des OS invités, alors que l'hyperviseur est parfois appelé l'OS hôte.
Sans accélération matérielle, la traduction des adresses physiques invitées en adresses hôte est réalisée par une seconde table des pages, appelée la ''shadow page table'', ce qui donnerait '''table des pages cachée''' en français. La table des pages cachée est prise en charge par l'hyperviseur. Toute modification de la table des pages cachée est réalisée par l'hyperviseur, les OS ne savent même pas qu'elle existe.
[[File:Shadowpagetables.png|centre|vignette|upright=2|Table des pages cachée.]]
Une autre solution demande un support matériel des tables des pages emboitées, à savoir qu'il y a un arbre de table des pages, chaque consultation de la première table des pages renvoie vers une seconde, qui renvoie vers une troisième, et ainsi de suite jusqu'à tomber sur la table des pages finale qui renvoie l'adresse physique réelle.
L'idée est l'utiliser une seule table des pages, mais d'ajouter un ou deux niveaux supplémentaires. Pour l'exemple, prenons le cas des processeurs x86. Sans virtualisation, l'OS utilise une table des pages de 4 niveaux. Avec, la table des pages a un niveau en plus, qui sont ajoutés à la fin de la dernière table des pages normale. Les niveaux ajoutés s'occupent de la traduction des adresses physiques invitées en adresses physiques hôte. Il faut que le processeur soit modifié de manière à parcourir automatiquement les niveaux ajoutés, ce qui demande quelques modifications de la TLB et du ''page table walker''.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les sections critiques et le modèle mémoire
| prevText=Les sections critiques et le modèle mémoire
| next=Le matériel réseau
| nextText=Le matériel réseau
}}
</noinclude>
j43qkj9n5n5mgwtzxcjb14b90xjtch8
744312
744311
2025-06-08T14:26:55Z
Mewtow
31375
/* La virtualisation du CPU par détournement d'interruptions */
744312
wikitext
text/x-wiki
La virtualisation est l'ensemble des techniques qui permettent de faire tourner plusieurs systèmes d'exploitation en même temps. Le terme est polysémique, mais c'est la définition que nous allons utiliser pour ce qui nous intéresse. La virtualisation demande d'utiliser un logiciel dit '''hyperviseur''', qui permet de faire tourner plusieurs OS en même temps. Les hyperviseurs sont en quelque sorte situés sous le système d'exploitation et on peut les voir comme une sorte de sous-système d'exploitation, de système d'exploitation pour les systèmes d'exploitation.
[[File:Diagramme ArchiHyperviseur.png|centre|vignette|upright=2|Différence entre système d'exploitation et hyperviseur.]]
Les processeurs modernes intègrent des techniques pour accélérer matériellement la virtualisation. Les techniques en question sont assez variées, allant d'un niveau de privilège en plus des modes noyau/utilisateur à des techniques de duplication de ces mêmes modes. Les techniques de virtualisation demandent de détourner des interruptions, ce qui fait que ces techniques d'accélération demandent de modifier la manière dont le processeur gère les interruptions. Mais pour comprendre tout cela, il va falloir faire quelques explications sur la virtualisation elle-même.
==La virtualisation : généralités==
Pour faire tourner plusieurs OS en même temps, l'hyperviseur recourt à de nombreux stratagèmes. Il doit partager le processeur, la RAM et les entrées-sorties entre plusieurs OS. Les trois demandent des techniques différentes. Le partage de la RAM demande concrètement des modifications au niveau de la mémoire virtuelle. Le partage du processeur est assez simple : les OS s'exécutent à tour de rôle sur le processeur, chacun pendant un temps défini, fixe. Une fois leur temps d'exécution passé, ils laissent la main à l'OS suivant. C'est l’hyperviseur qui s'occupe de tout cela, grâce à une interruption commandée à un ''timer''. Ce système de partage est une forme de '''multiplexage'''.
La gestion des entrées-sorties demande d'utiliser des techniques d''''émulation''', plus complexes à expliquer. Un hyperviseur peut parfaitement simuler du matériel qui n'est pas installé sur l'ordinateur. Par exemple, il peut faire croire à un OS qu'une carte réseau obsolète, datant d'il y a 20 ans, est installée sur l'ordinateur, alors que ce n'est pas le cas. Les commandes envoyées par l'OS à cette carte réseau fictive sont en réalité traitées par une vraie carte réseau par l’hyperviseur. Pour cela, l’hyperviseur intercepte les commandes envoyées aux entrées-sorties, et les traduit en commandes compatibles avec les entrées-sorties réellement installées sur l'ordinateur.
===Les machines virtuelles===
L'exemple avec la carte réseau est un cas particulier, l'hyperviseur faisant beaucoup de choses dans le genre. L'hyperviseur peut faire croire à l'ordinateur qu'il a plus ou moins de RAM que ce qui est réellement installé, par exemple. L'hyperviseur implémente ce qu'on appelle des '''machines virtuelles'''. Il s'agit d'une sorte de faux matériel, simulé par un logiciel. Un logiciel qui s’exécute dans une machine virtuelle aura l'impression de s’exécuter sur un matériel et/ou un O.S différent du matériel sur lequel il est en train de s’exécuter.
: Dans ce qui suit, nous parlerons de V.M (virtual machine), pour parler des machines virtuelles.
[[File:VM-monitor-french.png|centre|vignette|upright=2|Machines virtuelles avec la virtualisation.]]
L'hyperviseur crée plusieurs machines virtuelles, chacune étant réservée à un système d'exploitation. Il s'agit là d'une des utilisations possibles, mais il y en a d'autres. La plus intéressante est celle des émulateurs. Ces derniers sont des logiciels qui permettent de simuler le fonctionnement d'anciens ordinateurs ou consoles de jeux. L'émulateur crée une machine virtuelle qui est réservée à un programme, à savoir le jeu à émuler.
Il y a une différence de taille entre un émulateur et un hyperviseur. L'émulation émule une machine virtuelle totalement différente, alors que la virtualisation doit émuler les entrées-sorties mais pas le processeur. Avec un hyperviseur, le système d'exploitation s'exécute sur le processeur lui-même. Le code de l'OS est compatible avec le processeur de la machine, dans le sens où il est compilé pour le jeu d'instruction du processeur de la machine réelle. Les instructions de l'OS s'exécutent directement. Par contre, un émulateur exécute un jeu qui est programmé pour une machine dont le processeur est totalement différent. Le jeu d'instruction de la machine virtuelle et celui du vrai processeur n'est pas le même. L'émulation implique donc de traduire les instructions à exécuter dans la V.M par des instructions exécutables par le processeur. Ce n'est pas le cas avec la virtualisation, le jeu d'instruction étant le même.
[[File:Diagramme ArchiEmulateurNonNatif.png|centre|vignette|upright=2|Emulateur]]
===La méthode ''trap and emulate'' basique===
Pour être considéré comme un logiciel de virtualisation, un logiciel doit remplir trois critères :
* L'équivalence : l'O.S virtualisé et les applications qui s’exécutent doivent se comporter comme s'ils étaient exécutés sur le matériel de base, sans virtualisation.
* L'efficacité : La grande partie des instructions machines doit s’exécuter directement sur le processeur, afin de garder des performances correctes. Ce critère n'est pas respecté par les émulateurs matériels, qui doivent simuler le jeu d'instruction du processeur émulé.
* Le contrôle des ressources : tout accès au matériel par l'O.S virtualisé doit être intercepté par la machine virtuelle et intégralement pris en charge par l'hyperviseur.
Remplir ces trois critères est possible sous certaines conditions, établies par les théorèmes de Popek et Goldberg. Ces théorèmes se basent sur la présence de différents types d'instructions machines. Pour rappel, il faut distinguer les instructions privilégiées de celles qui ne le sont pas. Les instructions privilégiées ne peuvent s'exécuter que en mode noyau, les programmes en mode utilisateur ne peuvent pas les exécuter.
Parmi les instructions privilégiées on peut distinguer un sous-groupe appelé les '''instructions systèmes'''. Le premier type regroupe les '''instructions d'accès aux entrées-sorties''', aussi appelées instructions sensibles à la configuration. Le second type est celui des '''instructions de configuration du processeur''', qui agissent sur les registres de contrôle du processeur, aussi appelées instructions sensibles au comportement.
La théorie de Popek et Goldberg dit qu'il est possible de virtualiser un O.S à une condition : que les instructions systèmes soient toutes des instructions privilégiées, c’est-à-dire exécutables seulement en mode noyau. Virtualiser un O.S demande simplement de le démarrer en mode utilisateur. Quand l'O.S fait un accès au matériel, il le fait via une instruction privilégiée. Vu que l'OS est en mode utilisateur, cela déclenche une exception matérielle, qui émule l'instruction privilégiée.
L'hyperviseur n'est ni plus ni moins qu'un ensemble de routines d'interruptions, chaque routine simulant le fonctionnement du matériel émulé. Par exemple, un accès au disque dur sera émulé par une routine d'interruption, qui utilisera les appels systèmes fournit par l'OS pour accéder au disque dur réellement présent dans l'ordinateur. Cette méthode est souvent appelée la méthode ''trap and emulate''.
[[File:Virtualisation avec la méthode trap-and-emulate.png|centre|vignette|upright=2.0|Virtualisation avec la méthode trap-and-emulate]]
===Le jeu d'instruction peut être incompatible avec le ''trap and emulate''===
Le critère précédent n'est pas respecté par beaucoup de jeux d'instructions. Par exemple, ce n'est pas le cas sur les processeurs x86, qu'ils soient 32 bits. Diverses instructions systèmes ne sont pas des instructions privilégiées. Par exemple, les instructions qui manipulent les drapeaux d'interruption ne sont pas toutes des instructions privilégiées. Il en est de même avec les instructions qui manipulent les registres pour la segmentation, celles liées aux ''call gates'', etc. A cause de cela, il est impossible d'utiliser la méthode du ''trap and emulate''. La seule solution qui ne requiert pas de techniques matérielles est de traduire à la volée les instructions systèmes problématiques en appels systèmes équivalents, grâce à des techniques de '''réécriture de code'''.
D'autres limitations font que la méthode ''trap and emulate'' ne fonctionne pas. Déjà, il faut que l'ordinateur utilise la mémoire virtuelle, sans quoi plusieurs OS ne peuvent pas se partager la même mémoire physique. De plus, il ne faut pas que la mémoire physique, non-virtuelle, puisse être adressée directement. Et cette contrainte est violée, par exemple sur les architectures MIPS qui exposent des portions de la mémoire physique dans certaines zones fixées à l'avance de la mémoire virtuelle. l'OS est compilé pour utiliser ces zones de mémoire pour accéder aux entrées-sorties mappées en mémoire, entre autres. En théorie, on peut passer outre le problème en marquant ces zones de mémoire comme inaccessibles, toute lecture/écriture à ces adresses déclenche alors une exception traitée par l'hyperviseur. Mais le cout en performance est alors trop important.
Enfin, certaines instructions dites '''sensibles au contexte''' ont un comportement différent entre le mode noyau et le mode utilisateur. En présence de telles instructions, la méthode ''trap and emulate'' ne fonctionne tout simplement pas. Grâce à ces instructions, le système d’exploitation ou un programme applicatif peut savoir s'il s'exécute en mode utilisateur ou noyau, ou hyperviseur, ou autre.
==La virtualisation du CPU : le mode hyperviseur==
Sur certains CPU modernes, il existe un niveau de privilège appelé le '''mode hyperviseur''' qui est utilisé pour les techniques de virtualisation. Le mode hyperviseur est réservé à l’hyperviseur et il a des droits d'accès spécifiques. Il n'est cependant pas toujours activé. Par exemple, si aucun hyperviseur n'est installé sur la machine, le processeur dispose seulement d'un mode noyau et d'un mode utilisateur normaux, le mode noyau n'ayant alors aucune limitation précise. Mais quand le mode hyperviseur est activé, une partie des manipulations est bloquée en mode noyau et n'est possible qu'en mode hyperviseur.
Le fonctionnement se base sur la différence entre instruction privilégiée et instruction système. Les instructions privilégiées peuvent s'exécuter en mode noyau, alors que les instructions systèmes ne peuvent s'exécuter qu'en mode hyperviseur. L'idée est que quand le noyau d'un OS exécute une instruction système, une exception matérielle est levée. L'exception bascule en mode hyperviseur et laisse la main à une routine de l'hyperviseur. L'hyperviseur fait alors des manipulations précise pour que l'instruction système donne le même résultat que si elle avait été exécutée par l'ordinateur simulé par la machine virtuelle.
[[File:Virtualisation avec un mode hyperviseur.png|centre|vignette|upright=2|Virtualisation avec un mode hyperviseur.]]
Il est ainsi possible d'émuler des entrées-sorties avec un cout en performance assez léger. Précisément, ce mode hyperviseur améliore les performances de la méthode du ''trap-and-emulate''. La méthode ''trap-and-emulate'' basique exécute une exception matérielle pour toute instruction privilégiées, qu'elle soit une instruction système ou non. Mais avec le mode hyperviseur, seules les instructions systèmes déclenchent une exception, pas les instructions privilégiées non-système. Les performances sont donc un peu meilleures, pour un résultat identique. Après tout, les entrées-sorties et la configuration du processeur suffisent à émuler une machine virtuelle, les autres instructions noyau ne le sont pas.
Sur les processeurs ARM, il est possible de configurer quelles instructions sont détournées vers le mode hyperviseur et celles qui restent en mode noyau. En clair, on peut configurer quelles sont les instructions systèmes et celles qui sont simplement privilégiées. Et il en est de même pour les interruptions : on peut configurer si elles exécutent la routine de l'OS normal en mode noyau, ou si elles déclenchent une exception matérielle qui redirige vers une routine de l’hyperviseur. En l'absence d'hyperviseur, toutes les interruptions redirigent vers la routine de l'OS normale, vers le mode noyau.
Les processeurs ARM de version v8 et plus incorporent un mode hyperviseur, mais pas les processeurs x86. A la place, ils incorporent des technologies alternatives nommées Intel Vtx ou l'AMD-V. Elles fonctionnent sur un principe totalement différent.
==La virtualisation de la mémoire RAM==
Avec la virtualisation, les différentes machines virtuelles, les différents OS doivent se partager la mémoire physique. Et ce partage doit isoler les différents OS les uns des autres. Il est possible de comparer cette isolation avec l'isolation des processus : chaque OS doit avoir sa propre mémoire physique rien qu'à lui. L'idée est d'utiliser la mémoire virtuelle pour cela.
L'espace d'adressage physique vu par chaque OS est en réalité virtualisé, c’est-à-dire que c'est un espace d'adressage fictif, qui ne correspond pas à la mémoire virtuelle. Les adresses physiques vues par l'OS sont en réalité des adresses intermédiaires entre les adresses physiques liées à la RAM, et les adresses virtuelles vues par les processus. Pour les distinguer, nous parlerons d'adresses physiques de l'hôte pour parler des adresses de la RAM, et des adresses physiques invitées pour parler des adresses manipulées par les OS virtualisés. La raison est que les OS sont appelés des OS invités, alors que l'hyperviseur est parfois appelé l'OS hôte.
Sans accélération matérielle, la traduction des adresses physiques invitées en adresses hôte est réalisée par une seconde table des pages, appelée la ''shadow page table'', ce qui donnerait '''table des pages cachée''' en français. La table des pages cachée est prise en charge par l'hyperviseur. Toute modification de la table des pages cachée est réalisée par l'hyperviseur, les OS ne savent même pas qu'elle existe.
[[File:Shadowpagetables.png|centre|vignette|upright=2|Table des pages cachée.]]
Une autre solution demande un support matériel des tables des pages emboitées, à savoir qu'il y a un arbre de table des pages, chaque consultation de la première table des pages renvoie vers une seconde, qui renvoie vers une troisième, et ainsi de suite jusqu'à tomber sur la table des pages finale qui renvoie l'adresse physique réelle.
L'idée est l'utiliser une seule table des pages, mais d'ajouter un ou deux niveaux supplémentaires. Pour l'exemple, prenons le cas des processeurs x86. Sans virtualisation, l'OS utilise une table des pages de 4 niveaux. Avec, la table des pages a un niveau en plus, qui sont ajoutés à la fin de la dernière table des pages normale. Les niveaux ajoutés s'occupent de la traduction des adresses physiques invitées en adresses physiques hôte. Il faut que le processeur soit modifié de manière à parcourir automatiquement les niveaux ajoutés, ce qui demande quelques modifications de la TLB et du ''page table walker''.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les sections critiques et le modèle mémoire
| prevText=Les sections critiques et le modèle mémoire
| next=Le matériel réseau
| nextText=Le matériel réseau
}}
</noinclude>
67at1u45xrlrf6hty4yurdbfopt0r9v
744313
744312
2025-06-08T14:30:02Z
Mewtow
31375
/* La virtualisation de la mémoire RAM */
744313
wikitext
text/x-wiki
La virtualisation est l'ensemble des techniques qui permettent de faire tourner plusieurs systèmes d'exploitation en même temps. Le terme est polysémique, mais c'est la définition que nous allons utiliser pour ce qui nous intéresse. La virtualisation demande d'utiliser un logiciel dit '''hyperviseur''', qui permet de faire tourner plusieurs OS en même temps. Les hyperviseurs sont en quelque sorte situés sous le système d'exploitation et on peut les voir comme une sorte de sous-système d'exploitation, de système d'exploitation pour les systèmes d'exploitation.
[[File:Diagramme ArchiHyperviseur.png|centre|vignette|upright=2|Différence entre système d'exploitation et hyperviseur.]]
Les processeurs modernes intègrent des techniques pour accélérer matériellement la virtualisation. Les techniques en question sont assez variées, allant d'un niveau de privilège en plus des modes noyau/utilisateur à des techniques de duplication de ces mêmes modes. Les techniques de virtualisation demandent de détourner des interruptions, ce qui fait que ces techniques d'accélération demandent de modifier la manière dont le processeur gère les interruptions. Mais pour comprendre tout cela, il va falloir faire quelques explications sur la virtualisation elle-même.
==La virtualisation : généralités==
Pour faire tourner plusieurs OS en même temps, l'hyperviseur recourt à de nombreux stratagèmes. Il doit partager le processeur, la RAM et les entrées-sorties entre plusieurs OS. Les trois demandent des techniques différentes. Le partage de la RAM demande concrètement des modifications au niveau de la mémoire virtuelle. Le partage du processeur est assez simple : les OS s'exécutent à tour de rôle sur le processeur, chacun pendant un temps défini, fixe. Une fois leur temps d'exécution passé, ils laissent la main à l'OS suivant. C'est l’hyperviseur qui s'occupe de tout cela, grâce à une interruption commandée à un ''timer''. Ce système de partage est une forme de '''multiplexage'''.
La gestion des entrées-sorties demande d'utiliser des techniques d''''émulation''', plus complexes à expliquer. Un hyperviseur peut parfaitement simuler du matériel qui n'est pas installé sur l'ordinateur. Par exemple, il peut faire croire à un OS qu'une carte réseau obsolète, datant d'il y a 20 ans, est installée sur l'ordinateur, alors que ce n'est pas le cas. Les commandes envoyées par l'OS à cette carte réseau fictive sont en réalité traitées par une vraie carte réseau par l’hyperviseur. Pour cela, l’hyperviseur intercepte les commandes envoyées aux entrées-sorties, et les traduit en commandes compatibles avec les entrées-sorties réellement installées sur l'ordinateur.
===Les machines virtuelles===
L'exemple avec la carte réseau est un cas particulier, l'hyperviseur faisant beaucoup de choses dans le genre. L'hyperviseur peut faire croire à l'ordinateur qu'il a plus ou moins de RAM que ce qui est réellement installé, par exemple. L'hyperviseur implémente ce qu'on appelle des '''machines virtuelles'''. Il s'agit d'une sorte de faux matériel, simulé par un logiciel. Un logiciel qui s’exécute dans une machine virtuelle aura l'impression de s’exécuter sur un matériel et/ou un O.S différent du matériel sur lequel il est en train de s’exécuter.
: Dans ce qui suit, nous parlerons de V.M (virtual machine), pour parler des machines virtuelles.
[[File:VM-monitor-french.png|centre|vignette|upright=2|Machines virtuelles avec la virtualisation.]]
L'hyperviseur crée plusieurs machines virtuelles, chacune étant réservée à un système d'exploitation. Il s'agit là d'une des utilisations possibles, mais il y en a d'autres. La plus intéressante est celle des émulateurs. Ces derniers sont des logiciels qui permettent de simuler le fonctionnement d'anciens ordinateurs ou consoles de jeux. L'émulateur crée une machine virtuelle qui est réservée à un programme, à savoir le jeu à émuler.
Il y a une différence de taille entre un émulateur et un hyperviseur. L'émulation émule une machine virtuelle totalement différente, alors que la virtualisation doit émuler les entrées-sorties mais pas le processeur. Avec un hyperviseur, le système d'exploitation s'exécute sur le processeur lui-même. Le code de l'OS est compatible avec le processeur de la machine, dans le sens où il est compilé pour le jeu d'instruction du processeur de la machine réelle. Les instructions de l'OS s'exécutent directement. Par contre, un émulateur exécute un jeu qui est programmé pour une machine dont le processeur est totalement différent. Le jeu d'instruction de la machine virtuelle et celui du vrai processeur n'est pas le même. L'émulation implique donc de traduire les instructions à exécuter dans la V.M par des instructions exécutables par le processeur. Ce n'est pas le cas avec la virtualisation, le jeu d'instruction étant le même.
[[File:Diagramme ArchiEmulateurNonNatif.png|centre|vignette|upright=2|Emulateur]]
===La méthode ''trap and emulate'' basique===
Pour être considéré comme un logiciel de virtualisation, un logiciel doit remplir trois critères :
* L'équivalence : l'O.S virtualisé et les applications qui s’exécutent doivent se comporter comme s'ils étaient exécutés sur le matériel de base, sans virtualisation.
* L'efficacité : La grande partie des instructions machines doit s’exécuter directement sur le processeur, afin de garder des performances correctes. Ce critère n'est pas respecté par les émulateurs matériels, qui doivent simuler le jeu d'instruction du processeur émulé.
* Le contrôle des ressources : tout accès au matériel par l'O.S virtualisé doit être intercepté par la machine virtuelle et intégralement pris en charge par l'hyperviseur.
Remplir ces trois critères est possible sous certaines conditions, établies par les théorèmes de Popek et Goldberg. Ces théorèmes se basent sur la présence de différents types d'instructions machines. Pour rappel, il faut distinguer les instructions privilégiées de celles qui ne le sont pas. Les instructions privilégiées ne peuvent s'exécuter que en mode noyau, les programmes en mode utilisateur ne peuvent pas les exécuter.
Parmi les instructions privilégiées on peut distinguer un sous-groupe appelé les '''instructions systèmes'''. Le premier type regroupe les '''instructions d'accès aux entrées-sorties''', aussi appelées instructions sensibles à la configuration. Le second type est celui des '''instructions de configuration du processeur''', qui agissent sur les registres de contrôle du processeur, aussi appelées instructions sensibles au comportement.
La théorie de Popek et Goldberg dit qu'il est possible de virtualiser un O.S à une condition : que les instructions systèmes soient toutes des instructions privilégiées, c’est-à-dire exécutables seulement en mode noyau. Virtualiser un O.S demande simplement de le démarrer en mode utilisateur. Quand l'O.S fait un accès au matériel, il le fait via une instruction privilégiée. Vu que l'OS est en mode utilisateur, cela déclenche une exception matérielle, qui émule l'instruction privilégiée.
L'hyperviseur n'est ni plus ni moins qu'un ensemble de routines d'interruptions, chaque routine simulant le fonctionnement du matériel émulé. Par exemple, un accès au disque dur sera émulé par une routine d'interruption, qui utilisera les appels systèmes fournit par l'OS pour accéder au disque dur réellement présent dans l'ordinateur. Cette méthode est souvent appelée la méthode ''trap and emulate''.
[[File:Virtualisation avec la méthode trap-and-emulate.png|centre|vignette|upright=2.0|Virtualisation avec la méthode trap-and-emulate]]
===Le jeu d'instruction peut être incompatible avec le ''trap and emulate''===
Le critère précédent n'est pas respecté par beaucoup de jeux d'instructions. Par exemple, ce n'est pas le cas sur les processeurs x86, qu'ils soient 32 bits. Diverses instructions systèmes ne sont pas des instructions privilégiées. Par exemple, les instructions qui manipulent les drapeaux d'interruption ne sont pas toutes des instructions privilégiées. Il en est de même avec les instructions qui manipulent les registres pour la segmentation, celles liées aux ''call gates'', etc. A cause de cela, il est impossible d'utiliser la méthode du ''trap and emulate''. La seule solution qui ne requiert pas de techniques matérielles est de traduire à la volée les instructions systèmes problématiques en appels systèmes équivalents, grâce à des techniques de '''réécriture de code'''.
D'autres limitations font que la méthode ''trap and emulate'' ne fonctionne pas. Déjà, il faut que l'ordinateur utilise la mémoire virtuelle, sans quoi plusieurs OS ne peuvent pas se partager la même mémoire physique. De plus, il ne faut pas que la mémoire physique, non-virtuelle, puisse être adressée directement. Et cette contrainte est violée, par exemple sur les architectures MIPS qui exposent des portions de la mémoire physique dans certaines zones fixées à l'avance de la mémoire virtuelle. l'OS est compilé pour utiliser ces zones de mémoire pour accéder aux entrées-sorties mappées en mémoire, entre autres. En théorie, on peut passer outre le problème en marquant ces zones de mémoire comme inaccessibles, toute lecture/écriture à ces adresses déclenche alors une exception traitée par l'hyperviseur. Mais le cout en performance est alors trop important.
Enfin, certaines instructions dites '''sensibles au contexte''' ont un comportement différent entre le mode noyau et le mode utilisateur. En présence de telles instructions, la méthode ''trap and emulate'' ne fonctionne tout simplement pas. Grâce à ces instructions, le système d’exploitation ou un programme applicatif peut savoir s'il s'exécute en mode utilisateur ou noyau, ou hyperviseur, ou autre.
==La virtualisation du CPU : le mode hyperviseur==
Sur certains CPU modernes, il existe un niveau de privilège appelé le '''mode hyperviseur''' qui est utilisé pour les techniques de virtualisation. Le mode hyperviseur est réservé à l’hyperviseur et il a des droits d'accès spécifiques. Il n'est cependant pas toujours activé. Par exemple, si aucun hyperviseur n'est installé sur la machine, le processeur dispose seulement d'un mode noyau et d'un mode utilisateur normaux, le mode noyau n'ayant alors aucune limitation précise. Mais quand le mode hyperviseur est activé, une partie des manipulations est bloquée en mode noyau et n'est possible qu'en mode hyperviseur.
Le fonctionnement se base sur la différence entre instruction privilégiée et instruction système. Les instructions privilégiées peuvent s'exécuter en mode noyau, alors que les instructions systèmes ne peuvent s'exécuter qu'en mode hyperviseur. L'idée est que quand le noyau d'un OS exécute une instruction système, une exception matérielle est levée. L'exception bascule en mode hyperviseur et laisse la main à une routine de l'hyperviseur. L'hyperviseur fait alors des manipulations précise pour que l'instruction système donne le même résultat que si elle avait été exécutée par l'ordinateur simulé par la machine virtuelle.
[[File:Virtualisation avec un mode hyperviseur.png|centre|vignette|upright=2|Virtualisation avec un mode hyperviseur.]]
Il est ainsi possible d'émuler des entrées-sorties avec un cout en performance assez léger. Précisément, ce mode hyperviseur améliore les performances de la méthode du ''trap-and-emulate''. La méthode ''trap-and-emulate'' basique exécute une exception matérielle pour toute instruction privilégiées, qu'elle soit une instruction système ou non. Mais avec le mode hyperviseur, seules les instructions systèmes déclenchent une exception, pas les instructions privilégiées non-système. Les performances sont donc un peu meilleures, pour un résultat identique. Après tout, les entrées-sorties et la configuration du processeur suffisent à émuler une machine virtuelle, les autres instructions noyau ne le sont pas.
Sur les processeurs ARM, il est possible de configurer quelles instructions sont détournées vers le mode hyperviseur et celles qui restent en mode noyau. En clair, on peut configurer quelles sont les instructions systèmes et celles qui sont simplement privilégiées. Et il en est de même pour les interruptions : on peut configurer si elles exécutent la routine de l'OS normal en mode noyau, ou si elles déclenchent une exception matérielle qui redirige vers une routine de l’hyperviseur. En l'absence d'hyperviseur, toutes les interruptions redirigent vers la routine de l'OS normale, vers le mode noyau.
Les processeurs ARM de version v8 et plus incorporent un mode hyperviseur, mais pas les processeurs x86. A la place, ils incorporent des technologies alternatives nommées Intel Vtx ou l'AMD-V. Elles fonctionnent sur un principe totalement différent.
==La virtualisation de la mémoire RAM : l'extension des tables des pages emboitées==
Avec la virtualisation, les différentes machines virtuelles, les différents OS doivent se partager la mémoire physique. Et ce partage doit isoler les différents OS les uns des autres. Il est possible de comparer cette isolation avec l'isolation des processus : chaque OS doit avoir sa propre mémoire physique rien qu'à lui. L'idée est d'utiliser la mémoire virtuelle pour cela.
L'espace d'adressage physique vu par chaque OS est en réalité virtualisé, c’est-à-dire que c'est un espace d'adressage fictif, qui ne correspond pas à la mémoire virtuelle. Les adresses physiques vues par l'OS sont en réalité des adresses intermédiaires entre les adresses physiques liées à la RAM, et les adresses virtuelles vues par les processus. Pour les distinguer, nous parlerons d'adresses physiques de l'hôte pour parler des adresses de la RAM, et des adresses physiques invitées pour parler des adresses manipulées par les OS virtualisés. La raison est que les OS sont appelés des OS invités, alors que l'hyperviseur est parfois appelé l'OS hôte.
Sans accélération matérielle, la traduction des adresses physiques invitées en adresses hôte est réalisée par une seconde table des pages, appelée la ''shadow page table'', ce qui donnerait '''table des pages cachée''' en français. La table des pages cachée est prise en charge par l'hyperviseur. Toute modification de la table des pages cachée est réalisée par l'hyperviseur, les OS ne savent même pas qu'elle existe.
[[File:Shadowpagetables.png|centre|vignette|upright=2|Table des pages cachée.]]
Une autre solution demande un support matériel des tables des pages emboitées, à savoir qu'il y a un arbre de table des pages, chaque consultation de la première table des pages renvoie vers une seconde, qui renvoie vers une troisième, et ainsi de suite jusqu'à tomber sur la table des pages finale qui renvoie l'adresse physique réelle.
L'idée est l'utiliser une seule table des pages, mais d'ajouter un ou deux niveaux supplémentaires. Pour l'exemple, prenons le cas des processeurs x86. Sans virtualisation, l'OS utilise une table des pages de 4 niveaux. Avec, la table des pages a un niveau en plus, qui sont ajoutés à la fin de la dernière table des pages normale. Les niveaux ajoutés s'occupent de la traduction des adresses physiques invitées en adresses physiques hôte. Il faut que le processeur soit modifié de manière à parcourir automatiquement les niveaux ajoutés, ce qui demande quelques modifications de la TLB et du ''page table walker''.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les sections critiques et le modèle mémoire
| prevText=Les sections critiques et le modèle mémoire
| next=Le matériel réseau
| nextText=Le matériel réseau
}}
</noinclude>
rpvop91dasdinxyxs8eeq7f3wsx24sx
744314
744313
2025-06-08T14:34:19Z
Mewtow
31375
/* La méthode trap and emulate basique */
744314
wikitext
text/x-wiki
La virtualisation est l'ensemble des techniques qui permettent de faire tourner plusieurs systèmes d'exploitation en même temps. Le terme est polysémique, mais c'est la définition que nous allons utiliser pour ce qui nous intéresse. La virtualisation demande d'utiliser un logiciel dit '''hyperviseur''', qui permet de faire tourner plusieurs OS en même temps. Les hyperviseurs sont en quelque sorte situés sous le système d'exploitation et on peut les voir comme une sorte de sous-système d'exploitation, de système d'exploitation pour les systèmes d'exploitation.
[[File:Diagramme ArchiHyperviseur.png|centre|vignette|upright=2|Différence entre système d'exploitation et hyperviseur.]]
Les processeurs modernes intègrent des techniques pour accélérer matériellement la virtualisation. Les techniques en question sont assez variées, allant d'un niveau de privilège en plus des modes noyau/utilisateur à des techniques de duplication de ces mêmes modes. Les techniques de virtualisation demandent de détourner des interruptions, ce qui fait que ces techniques d'accélération demandent de modifier la manière dont le processeur gère les interruptions. Mais pour comprendre tout cela, il va falloir faire quelques explications sur la virtualisation elle-même.
==La virtualisation : généralités==
Pour faire tourner plusieurs OS en même temps, l'hyperviseur recourt à de nombreux stratagèmes. Il doit partager le processeur, la RAM et les entrées-sorties entre plusieurs OS. Les trois demandent des techniques différentes. Le partage de la RAM demande concrètement des modifications au niveau de la mémoire virtuelle. Le partage du processeur est assez simple : les OS s'exécutent à tour de rôle sur le processeur, chacun pendant un temps défini, fixe. Une fois leur temps d'exécution passé, ils laissent la main à l'OS suivant. C'est l’hyperviseur qui s'occupe de tout cela, grâce à une interruption commandée à un ''timer''. Ce système de partage est une forme de '''multiplexage'''.
La gestion des entrées-sorties demande d'utiliser des techniques d''''émulation''', plus complexes à expliquer. Un hyperviseur peut parfaitement simuler du matériel qui n'est pas installé sur l'ordinateur. Par exemple, il peut faire croire à un OS qu'une carte réseau obsolète, datant d'il y a 20 ans, est installée sur l'ordinateur, alors que ce n'est pas le cas. Les commandes envoyées par l'OS à cette carte réseau fictive sont en réalité traitées par une vraie carte réseau par l’hyperviseur. Pour cela, l’hyperviseur intercepte les commandes envoyées aux entrées-sorties, et les traduit en commandes compatibles avec les entrées-sorties réellement installées sur l'ordinateur.
===Les machines virtuelles===
L'exemple avec la carte réseau est un cas particulier, l'hyperviseur faisant beaucoup de choses dans le genre. L'hyperviseur peut faire croire à l'ordinateur qu'il a plus ou moins de RAM que ce qui est réellement installé, par exemple. L'hyperviseur implémente ce qu'on appelle des '''machines virtuelles'''. Il s'agit d'une sorte de faux matériel, simulé par un logiciel. Un logiciel qui s’exécute dans une machine virtuelle aura l'impression de s’exécuter sur un matériel et/ou un O.S différent du matériel sur lequel il est en train de s’exécuter.
: Dans ce qui suit, nous parlerons de V.M (virtual machine), pour parler des machines virtuelles.
[[File:VM-monitor-french.png|centre|vignette|upright=2|Machines virtuelles avec la virtualisation.]]
L'hyperviseur crée plusieurs machines virtuelles, chacune étant réservée à un système d'exploitation. Il s'agit là d'une des utilisations possibles, mais il y en a d'autres. La plus intéressante est celle des émulateurs. Ces derniers sont des logiciels qui permettent de simuler le fonctionnement d'anciens ordinateurs ou consoles de jeux. L'émulateur crée une machine virtuelle qui est réservée à un programme, à savoir le jeu à émuler.
Il y a une différence de taille entre un émulateur et un hyperviseur. L'émulation émule une machine virtuelle totalement différente, alors que la virtualisation doit émuler les entrées-sorties mais pas le processeur. Avec un hyperviseur, le système d'exploitation s'exécute sur le processeur lui-même. Le code de l'OS est compatible avec le processeur de la machine, dans le sens où il est compilé pour le jeu d'instruction du processeur de la machine réelle. Les instructions de l'OS s'exécutent directement. Par contre, un émulateur exécute un jeu qui est programmé pour une machine dont le processeur est totalement différent. Le jeu d'instruction de la machine virtuelle et celui du vrai processeur n'est pas le même. L'émulation implique donc de traduire les instructions à exécuter dans la V.M par des instructions exécutables par le processeur. Ce n'est pas le cas avec la virtualisation, le jeu d'instruction étant le même.
[[File:Diagramme ArchiEmulateurNonNatif.png|centre|vignette|upright=2|Emulateur]]
===La méthode ''trap and emulate'' basique===
Pour être considéré comme un logiciel de virtualisation, un logiciel doit remplir trois critères :
* L'équivalence : l'O.S virtualisé et les applications qui s’exécutent doivent se comporter comme s'ils étaient exécutés sur le matériel de base, sans virtualisation.
* L'efficacité : La grande partie des instructions machines doit s’exécuter directement sur le processeur, afin de garder des performances correctes. Ce critère n'est pas respecté par les émulateurs matériels, qui doivent simuler le jeu d'instruction du processeur émulé.
* Le contrôle des ressources : tout accès au matériel par l'O.S virtualisé doit être intercepté par la machine virtuelle et intégralement pris en charge par l'hyperviseur.
Remplir ces trois critères est possible sous certaines conditions, établies par les théorèmes de Popek et Goldberg. Ces théorèmes se basent sur des hypothèses précises. De fait, la portée de ces théorèmes est limitée, notamment pour le critère de performance. Ils partent notamment du principe que l'ordinateur utilise la segmentation pour la mémoire virtuelle, et non la pagination. Il part aussi du principe que les interruptions ont un cout assez faible, qu'elles sont assez rares. Mais laissons ces détails de côté, le cœur de ces théorèmes repose sur une hypothèse simple : la présence de différents types d'instructions machines.
Pour rappel, il faut distinguer les instructions privilégiées de celles qui ne le sont pas. Les instructions privilégiées ne peuvent s'exécuter que en mode noyau, les programmes en mode utilisateur ne peuvent pas les exécuter. Parmi les instructions privilégiées on peut distinguer un sous-groupe appelé les '''instructions systèmes'''. Le premier type regroupe les '''instructions d'accès aux entrées-sorties''', aussi appelées instructions sensibles à la configuration. Le second type est celui des '''instructions de configuration du processeur''', qui agissent sur les registres de contrôle du processeur, aussi appelées instructions sensibles au comportement.
La théorie de Popek et Goldberg dit qu'il est possible de virtualiser un O.S à une condition : que les instructions systèmes soient toutes des instructions privilégiées, c’est-à-dire exécutables seulement en mode noyau. Virtualiser un O.S demande simplement de le démarrer en mode utilisateur. Quand l'O.S fait un accès au matériel, il le fait via une instruction privilégiée. Vu que l'OS est en mode utilisateur, cela déclenche une exception matérielle, qui émule l'instruction privilégiée.
L'hyperviseur n'est ni plus ni moins qu'un ensemble de routines d'interruptions, chaque routine simulant le fonctionnement du matériel émulé. Par exemple, un accès au disque dur sera émulé par une routine d'interruption, qui utilisera les appels systèmes fournit par l'OS pour accéder au disque dur réellement présent dans l'ordinateur. Cette méthode est souvent appelée la méthode ''trap and emulate''.
[[File:Virtualisation avec la méthode trap-and-emulate.png|centre|vignette|upright=2.0|Virtualisation avec la méthode trap-and-emulate]]
===Le jeu d'instruction peut être incompatible avec le ''trap and emulate''===
Le critère précédent n'est pas respecté par beaucoup de jeux d'instructions. Par exemple, ce n'est pas le cas sur les processeurs x86, qu'ils soient 32 bits. Diverses instructions systèmes ne sont pas des instructions privilégiées. Par exemple, les instructions qui manipulent les drapeaux d'interruption ne sont pas toutes des instructions privilégiées. Il en est de même avec les instructions qui manipulent les registres pour la segmentation, celles liées aux ''call gates'', etc. A cause de cela, il est impossible d'utiliser la méthode du ''trap and emulate''. La seule solution qui ne requiert pas de techniques matérielles est de traduire à la volée les instructions systèmes problématiques en appels systèmes équivalents, grâce à des techniques de '''réécriture de code'''.
D'autres limitations font que la méthode ''trap and emulate'' ne fonctionne pas. Déjà, il faut que l'ordinateur utilise la mémoire virtuelle, sans quoi plusieurs OS ne peuvent pas se partager la même mémoire physique. De plus, il ne faut pas que la mémoire physique, non-virtuelle, puisse être adressée directement. Et cette contrainte est violée, par exemple sur les architectures MIPS qui exposent des portions de la mémoire physique dans certaines zones fixées à l'avance de la mémoire virtuelle. l'OS est compilé pour utiliser ces zones de mémoire pour accéder aux entrées-sorties mappées en mémoire, entre autres. En théorie, on peut passer outre le problème en marquant ces zones de mémoire comme inaccessibles, toute lecture/écriture à ces adresses déclenche alors une exception traitée par l'hyperviseur. Mais le cout en performance est alors trop important.
Enfin, certaines instructions dites '''sensibles au contexte''' ont un comportement différent entre le mode noyau et le mode utilisateur. En présence de telles instructions, la méthode ''trap and emulate'' ne fonctionne tout simplement pas. Grâce à ces instructions, le système d’exploitation ou un programme applicatif peut savoir s'il s'exécute en mode utilisateur ou noyau, ou hyperviseur, ou autre.
==La virtualisation du CPU : le mode hyperviseur==
Sur certains CPU modernes, il existe un niveau de privilège appelé le '''mode hyperviseur''' qui est utilisé pour les techniques de virtualisation. Le mode hyperviseur est réservé à l’hyperviseur et il a des droits d'accès spécifiques. Il n'est cependant pas toujours activé. Par exemple, si aucun hyperviseur n'est installé sur la machine, le processeur dispose seulement d'un mode noyau et d'un mode utilisateur normaux, le mode noyau n'ayant alors aucune limitation précise. Mais quand le mode hyperviseur est activé, une partie des manipulations est bloquée en mode noyau et n'est possible qu'en mode hyperviseur.
Le fonctionnement se base sur la différence entre instruction privilégiée et instruction système. Les instructions privilégiées peuvent s'exécuter en mode noyau, alors que les instructions systèmes ne peuvent s'exécuter qu'en mode hyperviseur. L'idée est que quand le noyau d'un OS exécute une instruction système, une exception matérielle est levée. L'exception bascule en mode hyperviseur et laisse la main à une routine de l'hyperviseur. L'hyperviseur fait alors des manipulations précise pour que l'instruction système donne le même résultat que si elle avait été exécutée par l'ordinateur simulé par la machine virtuelle.
[[File:Virtualisation avec un mode hyperviseur.png|centre|vignette|upright=2|Virtualisation avec un mode hyperviseur.]]
Il est ainsi possible d'émuler des entrées-sorties avec un cout en performance assez léger. Précisément, ce mode hyperviseur améliore les performances de la méthode du ''trap-and-emulate''. La méthode ''trap-and-emulate'' basique exécute une exception matérielle pour toute instruction privilégiées, qu'elle soit une instruction système ou non. Mais avec le mode hyperviseur, seules les instructions systèmes déclenchent une exception, pas les instructions privilégiées non-système. Les performances sont donc un peu meilleures, pour un résultat identique. Après tout, les entrées-sorties et la configuration du processeur suffisent à émuler une machine virtuelle, les autres instructions noyau ne le sont pas.
Sur les processeurs ARM, il est possible de configurer quelles instructions sont détournées vers le mode hyperviseur et celles qui restent en mode noyau. En clair, on peut configurer quelles sont les instructions systèmes et celles qui sont simplement privilégiées. Et il en est de même pour les interruptions : on peut configurer si elles exécutent la routine de l'OS normal en mode noyau, ou si elles déclenchent une exception matérielle qui redirige vers une routine de l’hyperviseur. En l'absence d'hyperviseur, toutes les interruptions redirigent vers la routine de l'OS normale, vers le mode noyau.
Les processeurs ARM de version v8 et plus incorporent un mode hyperviseur, mais pas les processeurs x86. A la place, ils incorporent des technologies alternatives nommées Intel Vtx ou l'AMD-V. Elles fonctionnent sur un principe totalement différent.
==La virtualisation de la mémoire RAM : l'extension des tables des pages emboitées==
Avec la virtualisation, les différentes machines virtuelles, les différents OS doivent se partager la mémoire physique. Et ce partage doit isoler les différents OS les uns des autres. Il est possible de comparer cette isolation avec l'isolation des processus : chaque OS doit avoir sa propre mémoire physique rien qu'à lui. L'idée est d'utiliser la mémoire virtuelle pour cela.
L'espace d'adressage physique vu par chaque OS est en réalité virtualisé, c’est-à-dire que c'est un espace d'adressage fictif, qui ne correspond pas à la mémoire virtuelle. Les adresses physiques vues par l'OS sont en réalité des adresses intermédiaires entre les adresses physiques liées à la RAM, et les adresses virtuelles vues par les processus. Pour les distinguer, nous parlerons d'adresses physiques de l'hôte pour parler des adresses de la RAM, et des adresses physiques invitées pour parler des adresses manipulées par les OS virtualisés. La raison est que les OS sont appelés des OS invités, alors que l'hyperviseur est parfois appelé l'OS hôte.
Sans accélération matérielle, la traduction des adresses physiques invitées en adresses hôte est réalisée par une seconde table des pages, appelée la ''shadow page table'', ce qui donnerait '''table des pages cachée''' en français. La table des pages cachée est prise en charge par l'hyperviseur. Toute modification de la table des pages cachée est réalisée par l'hyperviseur, les OS ne savent même pas qu'elle existe.
[[File:Shadowpagetables.png|centre|vignette|upright=2|Table des pages cachée.]]
Une autre solution demande un support matériel des tables des pages emboitées, à savoir qu'il y a un arbre de table des pages, chaque consultation de la première table des pages renvoie vers une seconde, qui renvoie vers une troisième, et ainsi de suite jusqu'à tomber sur la table des pages finale qui renvoie l'adresse physique réelle.
L'idée est l'utiliser une seule table des pages, mais d'ajouter un ou deux niveaux supplémentaires. Pour l'exemple, prenons le cas des processeurs x86. Sans virtualisation, l'OS utilise une table des pages de 4 niveaux. Avec, la table des pages a un niveau en plus, qui sont ajoutés à la fin de la dernière table des pages normale. Les niveaux ajoutés s'occupent de la traduction des adresses physiques invitées en adresses physiques hôte. Il faut que le processeur soit modifié de manière à parcourir automatiquement les niveaux ajoutés, ce qui demande quelques modifications de la TLB et du ''page table walker''.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les sections critiques et le modèle mémoire
| prevText=Les sections critiques et le modèle mémoire
| next=Le matériel réseau
| nextText=Le matériel réseau
}}
</noinclude>
86rxev8ax64odes9lgfjccy4yixs055
744315
744314
2025-06-08T14:39:52Z
Mewtow
31375
/* Le jeu d'instruction peut être incompatible avec le trap and emulate */
744315
wikitext
text/x-wiki
La virtualisation est l'ensemble des techniques qui permettent de faire tourner plusieurs systèmes d'exploitation en même temps. Le terme est polysémique, mais c'est la définition que nous allons utiliser pour ce qui nous intéresse. La virtualisation demande d'utiliser un logiciel dit '''hyperviseur''', qui permet de faire tourner plusieurs OS en même temps. Les hyperviseurs sont en quelque sorte situés sous le système d'exploitation et on peut les voir comme une sorte de sous-système d'exploitation, de système d'exploitation pour les systèmes d'exploitation.
[[File:Diagramme ArchiHyperviseur.png|centre|vignette|upright=2|Différence entre système d'exploitation et hyperviseur.]]
Les processeurs modernes intègrent des techniques pour accélérer matériellement la virtualisation. Les techniques en question sont assez variées, allant d'un niveau de privilège en plus des modes noyau/utilisateur à des techniques de duplication de ces mêmes modes. Les techniques de virtualisation demandent de détourner des interruptions, ce qui fait que ces techniques d'accélération demandent de modifier la manière dont le processeur gère les interruptions. Mais pour comprendre tout cela, il va falloir faire quelques explications sur la virtualisation elle-même.
==La virtualisation : généralités==
Pour faire tourner plusieurs OS en même temps, l'hyperviseur recourt à de nombreux stratagèmes. Il doit partager le processeur, la RAM et les entrées-sorties entre plusieurs OS. Les trois demandent des techniques différentes. Le partage de la RAM demande concrètement des modifications au niveau de la mémoire virtuelle. Le partage du processeur est assez simple : les OS s'exécutent à tour de rôle sur le processeur, chacun pendant un temps défini, fixe. Une fois leur temps d'exécution passé, ils laissent la main à l'OS suivant. C'est l’hyperviseur qui s'occupe de tout cela, grâce à une interruption commandée à un ''timer''. Ce système de partage est une forme de '''multiplexage'''.
La gestion des entrées-sorties demande d'utiliser des techniques d''''émulation''', plus complexes à expliquer. Un hyperviseur peut parfaitement simuler du matériel qui n'est pas installé sur l'ordinateur. Par exemple, il peut faire croire à un OS qu'une carte réseau obsolète, datant d'il y a 20 ans, est installée sur l'ordinateur, alors que ce n'est pas le cas. Les commandes envoyées par l'OS à cette carte réseau fictive sont en réalité traitées par une vraie carte réseau par l’hyperviseur. Pour cela, l’hyperviseur intercepte les commandes envoyées aux entrées-sorties, et les traduit en commandes compatibles avec les entrées-sorties réellement installées sur l'ordinateur.
===Les machines virtuelles===
L'exemple avec la carte réseau est un cas particulier, l'hyperviseur faisant beaucoup de choses dans le genre. L'hyperviseur peut faire croire à l'ordinateur qu'il a plus ou moins de RAM que ce qui est réellement installé, par exemple. L'hyperviseur implémente ce qu'on appelle des '''machines virtuelles'''. Il s'agit d'une sorte de faux matériel, simulé par un logiciel. Un logiciel qui s’exécute dans une machine virtuelle aura l'impression de s’exécuter sur un matériel et/ou un O.S différent du matériel sur lequel il est en train de s’exécuter.
: Dans ce qui suit, nous parlerons de V.M (virtual machine), pour parler des machines virtuelles.
[[File:VM-monitor-french.png|centre|vignette|upright=2|Machines virtuelles avec la virtualisation.]]
L'hyperviseur crée plusieurs machines virtuelles, chacune étant réservée à un système d'exploitation. Il s'agit là d'une des utilisations possibles, mais il y en a d'autres. La plus intéressante est celle des émulateurs. Ces derniers sont des logiciels qui permettent de simuler le fonctionnement d'anciens ordinateurs ou consoles de jeux. L'émulateur crée une machine virtuelle qui est réservée à un programme, à savoir le jeu à émuler.
Il y a une différence de taille entre un émulateur et un hyperviseur. L'émulation émule une machine virtuelle totalement différente, alors que la virtualisation doit émuler les entrées-sorties mais pas le processeur. Avec un hyperviseur, le système d'exploitation s'exécute sur le processeur lui-même. Le code de l'OS est compatible avec le processeur de la machine, dans le sens où il est compilé pour le jeu d'instruction du processeur de la machine réelle. Les instructions de l'OS s'exécutent directement. Par contre, un émulateur exécute un jeu qui est programmé pour une machine dont le processeur est totalement différent. Le jeu d'instruction de la machine virtuelle et celui du vrai processeur n'est pas le même. L'émulation implique donc de traduire les instructions à exécuter dans la V.M par des instructions exécutables par le processeur. Ce n'est pas le cas avec la virtualisation, le jeu d'instruction étant le même.
[[File:Diagramme ArchiEmulateurNonNatif.png|centre|vignette|upright=2|Emulateur]]
===La méthode ''trap and emulate'' basique===
Pour être considéré comme un logiciel de virtualisation, un logiciel doit remplir trois critères :
* L'équivalence : l'O.S virtualisé et les applications qui s’exécutent doivent se comporter comme s'ils étaient exécutés sur le matériel de base, sans virtualisation.
* L'efficacité : La grande partie des instructions machines doit s’exécuter directement sur le processeur, afin de garder des performances correctes. Ce critère n'est pas respecté par les émulateurs matériels, qui doivent simuler le jeu d'instruction du processeur émulé.
* Le contrôle des ressources : tout accès au matériel par l'O.S virtualisé doit être intercepté par la machine virtuelle et intégralement pris en charge par l'hyperviseur.
Remplir ces trois critères est possible sous certaines conditions, établies par les théorèmes de Popek et Goldberg. Ces théorèmes se basent sur des hypothèses précises. De fait, la portée de ces théorèmes est limitée, notamment pour le critère de performance. Ils partent notamment du principe que l'ordinateur utilise la segmentation pour la mémoire virtuelle, et non la pagination. Il part aussi du principe que les interruptions ont un cout assez faible, qu'elles sont assez rares. Mais laissons ces détails de côté, le cœur de ces théorèmes repose sur une hypothèse simple : la présence de différents types d'instructions machines.
Pour rappel, il faut distinguer les instructions privilégiées de celles qui ne le sont pas. Les instructions privilégiées ne peuvent s'exécuter que en mode noyau, les programmes en mode utilisateur ne peuvent pas les exécuter. Parmi les instructions privilégiées on peut distinguer un sous-groupe appelé les '''instructions systèmes'''. Le premier type regroupe les '''instructions d'accès aux entrées-sorties''', aussi appelées instructions sensibles à la configuration. Le second type est celui des '''instructions de configuration du processeur''', qui agissent sur les registres de contrôle du processeur, aussi appelées instructions sensibles au comportement.
La théorie de Popek et Goldberg dit qu'il est possible de virtualiser un O.S à une condition : que les instructions systèmes soient toutes des instructions privilégiées, c’est-à-dire exécutables seulement en mode noyau. Virtualiser un O.S demande simplement de le démarrer en mode utilisateur. Quand l'O.S fait un accès au matériel, il le fait via une instruction privilégiée. Vu que l'OS est en mode utilisateur, cela déclenche une exception matérielle, qui émule l'instruction privilégiée.
L'hyperviseur n'est ni plus ni moins qu'un ensemble de routines d'interruptions, chaque routine simulant le fonctionnement du matériel émulé. Par exemple, un accès au disque dur sera émulé par une routine d'interruption, qui utilisera les appels systèmes fournit par l'OS pour accéder au disque dur réellement présent dans l'ordinateur. Cette méthode est souvent appelée la méthode ''trap and emulate''.
[[File:Virtualisation avec la méthode trap-and-emulate.png|centre|vignette|upright=2.0|Virtualisation avec la méthode trap-and-emulate]]
===Le jeu d'instruction peut être incompatible avec le ''trap and emulate''===
Diverses limitations font que la méthode ''trap and emulate'' ne fonctionne pas. Déjà, il faut que l'ordinateur utilise la mémoire virtuelle, sans quoi plusieurs OS ne peuvent pas se partager la même mémoire physique. De plus, il ne faut pas que la mémoire physique, non-virtuelle, puisse être adressée directement.
Et cette contrainte est violée, par exemple sur les architectures MIPS qui exposent des portions de la mémoire physique dans certaines zones fixées à l'avance de la mémoire virtuelle. l'OS est compilé pour utiliser ces zones de mémoire pour accéder aux entrées-sorties mappées en mémoire, entre autres. En théorie, on peut passer outre le problème en marquant ces zones de mémoire comme inaccessibles, toute lecture/écriture à ces adresses déclenche alors une exception traitée par l'hyperviseur. Mais le cout en performance est alors trop important.
Quelques hyperviseurs ont été conçus pour les architectures MIPS, dont le projet de recherche DISCO, mais ils ne fonctionnaient qu'avec des systèmes d'exploitation recompilés, de manière à passer outre ce problème. Les OS étaient recompilés afin de ne pas utiliser les zones mémoire problématiques. De plus, les OS étaient modifiés pour améliorer les performances en virtualisation. Les OS disposaient notamment d'appels systèmes spéciaux, appelés des ''hypercalls'', qui exécutaient des routines de l'hyperviseur directement.
Un autre problème est que beaucoup de jeux d'instructions anciens ne respectent pas la règle "les instructions systèmes sont toutes privilégiées". Par exemple, ce n'est pas le cas sur les processeurs x86 32 bits. Sur ces CPU, les instructions qui manipulent les drapeaux d'interruption ne sont pas toutes des instructions privilégiées, idem pour les instructions qui manipulent les registres de segmentation, celles liées aux ''call gates'', etc. A cause de cela, il est impossible d'utiliser la méthode du ''trap and emulate''. La seule solution qui ne requiert pas de techniques matérielles est de traduire à la volée les instructions systèmes problématiques en appels systèmes équivalents, grâce à des techniques de '''réécriture de code'''.
Enfin, certaines instructions dites '''sensibles au contexte''' ont un comportement différent entre le mode noyau et le mode utilisateur. En présence de telles instructions, la méthode ''trap and emulate'' ne fonctionne tout simplement pas. Grâce à ces instructions, le système d’exploitation ou un programme applicatif peut savoir s'il s'exécute en mode utilisateur ou noyau, ou hyperviseur, ou autre.
==La virtualisation du CPU : le mode hyperviseur==
Sur certains CPU modernes, il existe un niveau de privilège appelé le '''mode hyperviseur''' qui est utilisé pour les techniques de virtualisation. Le mode hyperviseur est réservé à l’hyperviseur et il a des droits d'accès spécifiques. Il n'est cependant pas toujours activé. Par exemple, si aucun hyperviseur n'est installé sur la machine, le processeur dispose seulement d'un mode noyau et d'un mode utilisateur normaux, le mode noyau n'ayant alors aucune limitation précise. Mais quand le mode hyperviseur est activé, une partie des manipulations est bloquée en mode noyau et n'est possible qu'en mode hyperviseur.
Le fonctionnement se base sur la différence entre instruction privilégiée et instruction système. Les instructions privilégiées peuvent s'exécuter en mode noyau, alors que les instructions systèmes ne peuvent s'exécuter qu'en mode hyperviseur. L'idée est que quand le noyau d'un OS exécute une instruction système, une exception matérielle est levée. L'exception bascule en mode hyperviseur et laisse la main à une routine de l'hyperviseur. L'hyperviseur fait alors des manipulations précise pour que l'instruction système donne le même résultat que si elle avait été exécutée par l'ordinateur simulé par la machine virtuelle.
[[File:Virtualisation avec un mode hyperviseur.png|centre|vignette|upright=2|Virtualisation avec un mode hyperviseur.]]
Il est ainsi possible d'émuler des entrées-sorties avec un cout en performance assez léger. Précisément, ce mode hyperviseur améliore les performances de la méthode du ''trap-and-emulate''. La méthode ''trap-and-emulate'' basique exécute une exception matérielle pour toute instruction privilégiées, qu'elle soit une instruction système ou non. Mais avec le mode hyperviseur, seules les instructions systèmes déclenchent une exception, pas les instructions privilégiées non-système. Les performances sont donc un peu meilleures, pour un résultat identique. Après tout, les entrées-sorties et la configuration du processeur suffisent à émuler une machine virtuelle, les autres instructions noyau ne le sont pas.
Sur les processeurs ARM, il est possible de configurer quelles instructions sont détournées vers le mode hyperviseur et celles qui restent en mode noyau. En clair, on peut configurer quelles sont les instructions systèmes et celles qui sont simplement privilégiées. Et il en est de même pour les interruptions : on peut configurer si elles exécutent la routine de l'OS normal en mode noyau, ou si elles déclenchent une exception matérielle qui redirige vers une routine de l’hyperviseur. En l'absence d'hyperviseur, toutes les interruptions redirigent vers la routine de l'OS normale, vers le mode noyau.
Les processeurs ARM de version v8 et plus incorporent un mode hyperviseur, mais pas les processeurs x86. A la place, ils incorporent des technologies alternatives nommées Intel Vtx ou l'AMD-V. Elles fonctionnent sur un principe totalement différent.
==La virtualisation de la mémoire RAM : l'extension des tables des pages emboitées==
Avec la virtualisation, les différentes machines virtuelles, les différents OS doivent se partager la mémoire physique. Et ce partage doit isoler les différents OS les uns des autres. Il est possible de comparer cette isolation avec l'isolation des processus : chaque OS doit avoir sa propre mémoire physique rien qu'à lui. L'idée est d'utiliser la mémoire virtuelle pour cela.
L'espace d'adressage physique vu par chaque OS est en réalité virtualisé, c’est-à-dire que c'est un espace d'adressage fictif, qui ne correspond pas à la mémoire virtuelle. Les adresses physiques vues par l'OS sont en réalité des adresses intermédiaires entre les adresses physiques liées à la RAM, et les adresses virtuelles vues par les processus. Pour les distinguer, nous parlerons d'adresses physiques de l'hôte pour parler des adresses de la RAM, et des adresses physiques invitées pour parler des adresses manipulées par les OS virtualisés. La raison est que les OS sont appelés des OS invités, alors que l'hyperviseur est parfois appelé l'OS hôte.
Sans accélération matérielle, la traduction des adresses physiques invitées en adresses hôte est réalisée par une seconde table des pages, appelée la ''shadow page table'', ce qui donnerait '''table des pages cachée''' en français. La table des pages cachée est prise en charge par l'hyperviseur. Toute modification de la table des pages cachée est réalisée par l'hyperviseur, les OS ne savent même pas qu'elle existe.
[[File:Shadowpagetables.png|centre|vignette|upright=2|Table des pages cachée.]]
Une autre solution demande un support matériel des tables des pages emboitées, à savoir qu'il y a un arbre de table des pages, chaque consultation de la première table des pages renvoie vers une seconde, qui renvoie vers une troisième, et ainsi de suite jusqu'à tomber sur la table des pages finale qui renvoie l'adresse physique réelle.
L'idée est l'utiliser une seule table des pages, mais d'ajouter un ou deux niveaux supplémentaires. Pour l'exemple, prenons le cas des processeurs x86. Sans virtualisation, l'OS utilise une table des pages de 4 niveaux. Avec, la table des pages a un niveau en plus, qui sont ajoutés à la fin de la dernière table des pages normale. Les niveaux ajoutés s'occupent de la traduction des adresses physiques invitées en adresses physiques hôte. Il faut que le processeur soit modifié de manière à parcourir automatiquement les niveaux ajoutés, ce qui demande quelques modifications de la TLB et du ''page table walker''.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les sections critiques et le modèle mémoire
| prevText=Les sections critiques et le modèle mémoire
| next=Le matériel réseau
| nextText=Le matériel réseau
}}
</noinclude>
098h4il3u241lg0lvznawp8pzq9nx1w
744318
744315
2025-06-08T16:03:36Z
Mewtow
31375
/* Le jeu d'instruction peut être incompatible avec le trap and emulate */
744318
wikitext
text/x-wiki
La virtualisation est l'ensemble des techniques qui permettent de faire tourner plusieurs systèmes d'exploitation en même temps. Le terme est polysémique, mais c'est la définition que nous allons utiliser pour ce qui nous intéresse. La virtualisation demande d'utiliser un logiciel dit '''hyperviseur''', qui permet de faire tourner plusieurs OS en même temps. Les hyperviseurs sont en quelque sorte situés sous le système d'exploitation et on peut les voir comme une sorte de sous-système d'exploitation, de système d'exploitation pour les systèmes d'exploitation.
[[File:Diagramme ArchiHyperviseur.png|centre|vignette|upright=2|Différence entre système d'exploitation et hyperviseur.]]
Les processeurs modernes intègrent des techniques pour accélérer matériellement la virtualisation. Les techniques en question sont assez variées, allant d'un niveau de privilège en plus des modes noyau/utilisateur à des techniques de duplication de ces mêmes modes. Les techniques de virtualisation demandent de détourner des interruptions, ce qui fait que ces techniques d'accélération demandent de modifier la manière dont le processeur gère les interruptions. Mais pour comprendre tout cela, il va falloir faire quelques explications sur la virtualisation elle-même.
==La virtualisation : généralités==
Pour faire tourner plusieurs OS en même temps, l'hyperviseur recourt à de nombreux stratagèmes. Il doit partager le processeur, la RAM et les entrées-sorties entre plusieurs OS. Les trois demandent des techniques différentes. Le partage de la RAM demande concrètement des modifications au niveau de la mémoire virtuelle. Le partage du processeur est assez simple : les OS s'exécutent à tour de rôle sur le processeur, chacun pendant un temps défini, fixe. Une fois leur temps d'exécution passé, ils laissent la main à l'OS suivant. C'est l’hyperviseur qui s'occupe de tout cela, grâce à une interruption commandée à un ''timer''. Ce système de partage est une forme de '''multiplexage'''.
La gestion des entrées-sorties demande d'utiliser des techniques d''''émulation''', plus complexes à expliquer. Un hyperviseur peut parfaitement simuler du matériel qui n'est pas installé sur l'ordinateur. Par exemple, il peut faire croire à un OS qu'une carte réseau obsolète, datant d'il y a 20 ans, est installée sur l'ordinateur, alors que ce n'est pas le cas. Les commandes envoyées par l'OS à cette carte réseau fictive sont en réalité traitées par une vraie carte réseau par l’hyperviseur. Pour cela, l’hyperviseur intercepte les commandes envoyées aux entrées-sorties, et les traduit en commandes compatibles avec les entrées-sorties réellement installées sur l'ordinateur.
===Les machines virtuelles===
L'exemple avec la carte réseau est un cas particulier, l'hyperviseur faisant beaucoup de choses dans le genre. L'hyperviseur peut faire croire à l'ordinateur qu'il a plus ou moins de RAM que ce qui est réellement installé, par exemple. L'hyperviseur implémente ce qu'on appelle des '''machines virtuelles'''. Il s'agit d'une sorte de faux matériel, simulé par un logiciel. Un logiciel qui s’exécute dans une machine virtuelle aura l'impression de s’exécuter sur un matériel et/ou un O.S différent du matériel sur lequel il est en train de s’exécuter.
: Dans ce qui suit, nous parlerons de V.M (virtual machine), pour parler des machines virtuelles.
[[File:VM-monitor-french.png|centre|vignette|upright=2|Machines virtuelles avec la virtualisation.]]
L'hyperviseur crée plusieurs machines virtuelles, chacune étant réservée à un système d'exploitation. Il s'agit là d'une des utilisations possibles, mais il y en a d'autres. La plus intéressante est celle des émulateurs. Ces derniers sont des logiciels qui permettent de simuler le fonctionnement d'anciens ordinateurs ou consoles de jeux. L'émulateur crée une machine virtuelle qui est réservée à un programme, à savoir le jeu à émuler.
Il y a une différence de taille entre un émulateur et un hyperviseur. L'émulation émule une machine virtuelle totalement différente, alors que la virtualisation doit émuler les entrées-sorties mais pas le processeur. Avec un hyperviseur, le système d'exploitation s'exécute sur le processeur lui-même. Le code de l'OS est compatible avec le processeur de la machine, dans le sens où il est compilé pour le jeu d'instruction du processeur de la machine réelle. Les instructions de l'OS s'exécutent directement. Par contre, un émulateur exécute un jeu qui est programmé pour une machine dont le processeur est totalement différent. Le jeu d'instruction de la machine virtuelle et celui du vrai processeur n'est pas le même. L'émulation implique donc de traduire les instructions à exécuter dans la V.M par des instructions exécutables par le processeur. Ce n'est pas le cas avec la virtualisation, le jeu d'instruction étant le même.
[[File:Diagramme ArchiEmulateurNonNatif.png|centre|vignette|upright=2|Emulateur]]
===La méthode ''trap and emulate'' basique===
Pour être considéré comme un logiciel de virtualisation, un logiciel doit remplir trois critères :
* L'équivalence : l'O.S virtualisé et les applications qui s’exécutent doivent se comporter comme s'ils étaient exécutés sur le matériel de base, sans virtualisation.
* L'efficacité : La grande partie des instructions machines doit s’exécuter directement sur le processeur, afin de garder des performances correctes. Ce critère n'est pas respecté par les émulateurs matériels, qui doivent simuler le jeu d'instruction du processeur émulé.
* Le contrôle des ressources : tout accès au matériel par l'O.S virtualisé doit être intercepté par la machine virtuelle et intégralement pris en charge par l'hyperviseur.
Remplir ces trois critères est possible sous certaines conditions, établies par les théorèmes de Popek et Goldberg. Ces théorèmes se basent sur des hypothèses précises. De fait, la portée de ces théorèmes est limitée, notamment pour le critère de performance. Ils partent notamment du principe que l'ordinateur utilise la segmentation pour la mémoire virtuelle, et non la pagination. Il part aussi du principe que les interruptions ont un cout assez faible, qu'elles sont assez rares. Mais laissons ces détails de côté, le cœur de ces théorèmes repose sur une hypothèse simple : la présence de différents types d'instructions machines.
Pour rappel, il faut distinguer les instructions privilégiées de celles qui ne le sont pas. Les instructions privilégiées ne peuvent s'exécuter que en mode noyau, les programmes en mode utilisateur ne peuvent pas les exécuter. Parmi les instructions privilégiées on peut distinguer un sous-groupe appelé les '''instructions systèmes'''. Le premier type regroupe les '''instructions d'accès aux entrées-sorties''', aussi appelées instructions sensibles à la configuration. Le second type est celui des '''instructions de configuration du processeur''', qui agissent sur les registres de contrôle du processeur, aussi appelées instructions sensibles au comportement.
La théorie de Popek et Goldberg dit qu'il est possible de virtualiser un O.S à une condition : que les instructions systèmes soient toutes des instructions privilégiées, c’est-à-dire exécutables seulement en mode noyau. Virtualiser un O.S demande simplement de le démarrer en mode utilisateur. Quand l'O.S fait un accès au matériel, il le fait via une instruction privilégiée. Vu que l'OS est en mode utilisateur, cela déclenche une exception matérielle, qui émule l'instruction privilégiée.
L'hyperviseur n'est ni plus ni moins qu'un ensemble de routines d'interruptions, chaque routine simulant le fonctionnement du matériel émulé. Par exemple, un accès au disque dur sera émulé par une routine d'interruption, qui utilisera les appels systèmes fournit par l'OS pour accéder au disque dur réellement présent dans l'ordinateur. Cette méthode est souvent appelée la méthode ''trap and emulate''.
[[File:Virtualisation avec la méthode trap-and-emulate.png|centre|vignette|upright=2.0|Virtualisation avec la méthode trap-and-emulate]]
===Le jeu d'instruction peut être incompatible avec le ''trap and emulate''===
La méthode ''trap and emulate'' ne fonctionne que si certaines contraintes sont respectées. Déjà, il faut que l'ordinateur utilise la mémoire virtuelle, sans quoi plusieurs OS ne peuvent pas se partager la même mémoire physique. De plus, il ne faut pas que la mémoire physique, non-virtuelle, puisse être adressée directement.
Et cette contrainte est violée, par exemple sur les architectures MIPS qui exposent des portions de la mémoire physique dans certaines zones fixées à l'avance de la mémoire virtuelle. L'OS est compilé pour utiliser ces zones de mémoire pour accéder aux entrées-sorties mappées en mémoire, entre autres. En théorie, on peut passer outre le problème en marquant ces zones de mémoire comme inaccessibles, toute lecture/écriture à ces adresses déclenche alors une exception traitée par l'hyperviseur. Mais le cout en performance est alors trop important.
Quelques hyperviseurs ont été conçus pour les architectures MIPS, dont le projet de recherche DISCO, mais ils ne fonctionnaient qu'avec des systèmes d'exploitation recompilés, de manière à passer outre ce problème. Les OS étaient recompilés afin de ne pas utiliser les zones mémoire problématiques. De plus, les OS étaient modifiés pour améliorer les performances en virtualisation. Les OS disposaient notamment d'appels systèmes spéciaux, appelés des ''hypercalls'', qui exécutaient des routines de l'hyperviseur directement.
Un autre problème est que beaucoup de jeux d'instructions anciens ne respectent pas la règle "les instructions systèmes sont toutes privilégiées". Par exemple, ce n'est pas le cas sur les processeurs x86 32 bits. Sur ces CPU, les instructions qui manipulent les drapeaux d'interruption ne sont pas toutes des instructions privilégiées, idem pour les instructions qui manipulent les registres de segmentation, celles liées aux ''call gates'', etc. A cause de cela, il est impossible d'utiliser la méthode du ''trap and emulate''. La seule solution qui ne requiert pas de techniques matérielles est de traduire à la volée les instructions systèmes problématiques en appels systèmes équivalents, grâce à des techniques de '''réécriture de code'''.
Enfin, certaines instructions dites '''sensibles au contexte''' ont un comportement différent entre le mode noyau et le mode utilisateur. En présence de telles instructions, la méthode ''trap and emulate'' ne fonctionne tout simplement pas. Grâce à ces instructions, le système d’exploitation ou un programme applicatif peut savoir s'il s'exécute en mode utilisateur ou noyau, ou hyperviseur, ou autre.
==La virtualisation du CPU : le mode hyperviseur==
Sur certains CPU modernes, il existe un niveau de privilège appelé le '''mode hyperviseur''' qui est utilisé pour les techniques de virtualisation. Le mode hyperviseur est réservé à l’hyperviseur et il a des droits d'accès spécifiques. Il n'est cependant pas toujours activé. Par exemple, si aucun hyperviseur n'est installé sur la machine, le processeur dispose seulement d'un mode noyau et d'un mode utilisateur normaux, le mode noyau n'ayant alors aucune limitation précise. Mais quand le mode hyperviseur est activé, une partie des manipulations est bloquée en mode noyau et n'est possible qu'en mode hyperviseur.
Le fonctionnement se base sur la différence entre instruction privilégiée et instruction système. Les instructions privilégiées peuvent s'exécuter en mode noyau, alors que les instructions systèmes ne peuvent s'exécuter qu'en mode hyperviseur. L'idée est que quand le noyau d'un OS exécute une instruction système, une exception matérielle est levée. L'exception bascule en mode hyperviseur et laisse la main à une routine de l'hyperviseur. L'hyperviseur fait alors des manipulations précise pour que l'instruction système donne le même résultat que si elle avait été exécutée par l'ordinateur simulé par la machine virtuelle.
[[File:Virtualisation avec un mode hyperviseur.png|centre|vignette|upright=2|Virtualisation avec un mode hyperviseur.]]
Il est ainsi possible d'émuler des entrées-sorties avec un cout en performance assez léger. Précisément, ce mode hyperviseur améliore les performances de la méthode du ''trap-and-emulate''. La méthode ''trap-and-emulate'' basique exécute une exception matérielle pour toute instruction privilégiées, qu'elle soit une instruction système ou non. Mais avec le mode hyperviseur, seules les instructions systèmes déclenchent une exception, pas les instructions privilégiées non-système. Les performances sont donc un peu meilleures, pour un résultat identique. Après tout, les entrées-sorties et la configuration du processeur suffisent à émuler une machine virtuelle, les autres instructions noyau ne le sont pas.
Sur les processeurs ARM, il est possible de configurer quelles instructions sont détournées vers le mode hyperviseur et celles qui restent en mode noyau. En clair, on peut configurer quelles sont les instructions systèmes et celles qui sont simplement privilégiées. Et il en est de même pour les interruptions : on peut configurer si elles exécutent la routine de l'OS normal en mode noyau, ou si elles déclenchent une exception matérielle qui redirige vers une routine de l’hyperviseur. En l'absence d'hyperviseur, toutes les interruptions redirigent vers la routine de l'OS normale, vers le mode noyau.
Les processeurs ARM de version v8 et plus incorporent un mode hyperviseur, mais pas les processeurs x86. A la place, ils incorporent des technologies alternatives nommées Intel Vtx ou l'AMD-V. Elles fonctionnent sur un principe totalement différent.
==La virtualisation de la mémoire RAM : l'extension des tables des pages emboitées==
Avec la virtualisation, les différentes machines virtuelles, les différents OS doivent se partager la mémoire physique. Et ce partage doit isoler les différents OS les uns des autres. Il est possible de comparer cette isolation avec l'isolation des processus : chaque OS doit avoir sa propre mémoire physique rien qu'à lui. L'idée est d'utiliser la mémoire virtuelle pour cela.
L'espace d'adressage physique vu par chaque OS est en réalité virtualisé, c’est-à-dire que c'est un espace d'adressage fictif, qui ne correspond pas à la mémoire virtuelle. Les adresses physiques vues par l'OS sont en réalité des adresses intermédiaires entre les adresses physiques liées à la RAM, et les adresses virtuelles vues par les processus. Pour les distinguer, nous parlerons d'adresses physiques de l'hôte pour parler des adresses de la RAM, et des adresses physiques invitées pour parler des adresses manipulées par les OS virtualisés. La raison est que les OS sont appelés des OS invités, alors que l'hyperviseur est parfois appelé l'OS hôte.
Sans accélération matérielle, la traduction des adresses physiques invitées en adresses hôte est réalisée par une seconde table des pages, appelée la ''shadow page table'', ce qui donnerait '''table des pages cachée''' en français. La table des pages cachée est prise en charge par l'hyperviseur. Toute modification de la table des pages cachée est réalisée par l'hyperviseur, les OS ne savent même pas qu'elle existe.
[[File:Shadowpagetables.png|centre|vignette|upright=2|Table des pages cachée.]]
Une autre solution demande un support matériel des tables des pages emboitées, à savoir qu'il y a un arbre de table des pages, chaque consultation de la première table des pages renvoie vers une seconde, qui renvoie vers une troisième, et ainsi de suite jusqu'à tomber sur la table des pages finale qui renvoie l'adresse physique réelle.
L'idée est l'utiliser une seule table des pages, mais d'ajouter un ou deux niveaux supplémentaires. Pour l'exemple, prenons le cas des processeurs x86. Sans virtualisation, l'OS utilise une table des pages de 4 niveaux. Avec, la table des pages a un niveau en plus, qui sont ajoutés à la fin de la dernière table des pages normale. Les niveaux ajoutés s'occupent de la traduction des adresses physiques invitées en adresses physiques hôte. Il faut que le processeur soit modifié de manière à parcourir automatiquement les niveaux ajoutés, ce qui demande quelques modifications de la TLB et du ''page table walker''.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les sections critiques et le modèle mémoire
| prevText=Les sections critiques et le modèle mémoire
| next=Le matériel réseau
| nextText=Le matériel réseau
}}
</noinclude>
7bgofzbz5fr2nuhqvkfhrytmd0o4f7w
744319
744318
2025-06-08T16:03:49Z
Mewtow
31375
/* Le jeu d'instruction peut être incompatible avec le trap and emulate */
744319
wikitext
text/x-wiki
La virtualisation est l'ensemble des techniques qui permettent de faire tourner plusieurs systèmes d'exploitation en même temps. Le terme est polysémique, mais c'est la définition que nous allons utiliser pour ce qui nous intéresse. La virtualisation demande d'utiliser un logiciel dit '''hyperviseur''', qui permet de faire tourner plusieurs OS en même temps. Les hyperviseurs sont en quelque sorte situés sous le système d'exploitation et on peut les voir comme une sorte de sous-système d'exploitation, de système d'exploitation pour les systèmes d'exploitation.
[[File:Diagramme ArchiHyperviseur.png|centre|vignette|upright=2|Différence entre système d'exploitation et hyperviseur.]]
Les processeurs modernes intègrent des techniques pour accélérer matériellement la virtualisation. Les techniques en question sont assez variées, allant d'un niveau de privilège en plus des modes noyau/utilisateur à des techniques de duplication de ces mêmes modes. Les techniques de virtualisation demandent de détourner des interruptions, ce qui fait que ces techniques d'accélération demandent de modifier la manière dont le processeur gère les interruptions. Mais pour comprendre tout cela, il va falloir faire quelques explications sur la virtualisation elle-même.
==La virtualisation : généralités==
Pour faire tourner plusieurs OS en même temps, l'hyperviseur recourt à de nombreux stratagèmes. Il doit partager le processeur, la RAM et les entrées-sorties entre plusieurs OS. Les trois demandent des techniques différentes. Le partage de la RAM demande concrètement des modifications au niveau de la mémoire virtuelle. Le partage du processeur est assez simple : les OS s'exécutent à tour de rôle sur le processeur, chacun pendant un temps défini, fixe. Une fois leur temps d'exécution passé, ils laissent la main à l'OS suivant. C'est l’hyperviseur qui s'occupe de tout cela, grâce à une interruption commandée à un ''timer''. Ce système de partage est une forme de '''multiplexage'''.
La gestion des entrées-sorties demande d'utiliser des techniques d''''émulation''', plus complexes à expliquer. Un hyperviseur peut parfaitement simuler du matériel qui n'est pas installé sur l'ordinateur. Par exemple, il peut faire croire à un OS qu'une carte réseau obsolète, datant d'il y a 20 ans, est installée sur l'ordinateur, alors que ce n'est pas le cas. Les commandes envoyées par l'OS à cette carte réseau fictive sont en réalité traitées par une vraie carte réseau par l’hyperviseur. Pour cela, l’hyperviseur intercepte les commandes envoyées aux entrées-sorties, et les traduit en commandes compatibles avec les entrées-sorties réellement installées sur l'ordinateur.
===Les machines virtuelles===
L'exemple avec la carte réseau est un cas particulier, l'hyperviseur faisant beaucoup de choses dans le genre. L'hyperviseur peut faire croire à l'ordinateur qu'il a plus ou moins de RAM que ce qui est réellement installé, par exemple. L'hyperviseur implémente ce qu'on appelle des '''machines virtuelles'''. Il s'agit d'une sorte de faux matériel, simulé par un logiciel. Un logiciel qui s’exécute dans une machine virtuelle aura l'impression de s’exécuter sur un matériel et/ou un O.S différent du matériel sur lequel il est en train de s’exécuter.
: Dans ce qui suit, nous parlerons de V.M (virtual machine), pour parler des machines virtuelles.
[[File:VM-monitor-french.png|centre|vignette|upright=2|Machines virtuelles avec la virtualisation.]]
L'hyperviseur crée plusieurs machines virtuelles, chacune étant réservée à un système d'exploitation. Il s'agit là d'une des utilisations possibles, mais il y en a d'autres. La plus intéressante est celle des émulateurs. Ces derniers sont des logiciels qui permettent de simuler le fonctionnement d'anciens ordinateurs ou consoles de jeux. L'émulateur crée une machine virtuelle qui est réservée à un programme, à savoir le jeu à émuler.
Il y a une différence de taille entre un émulateur et un hyperviseur. L'émulation émule une machine virtuelle totalement différente, alors que la virtualisation doit émuler les entrées-sorties mais pas le processeur. Avec un hyperviseur, le système d'exploitation s'exécute sur le processeur lui-même. Le code de l'OS est compatible avec le processeur de la machine, dans le sens où il est compilé pour le jeu d'instruction du processeur de la machine réelle. Les instructions de l'OS s'exécutent directement. Par contre, un émulateur exécute un jeu qui est programmé pour une machine dont le processeur est totalement différent. Le jeu d'instruction de la machine virtuelle et celui du vrai processeur n'est pas le même. L'émulation implique donc de traduire les instructions à exécuter dans la V.M par des instructions exécutables par le processeur. Ce n'est pas le cas avec la virtualisation, le jeu d'instruction étant le même.
[[File:Diagramme ArchiEmulateurNonNatif.png|centre|vignette|upright=2|Emulateur]]
===La méthode ''trap and emulate'' basique===
Pour être considéré comme un logiciel de virtualisation, un logiciel doit remplir trois critères :
* L'équivalence : l'O.S virtualisé et les applications qui s’exécutent doivent se comporter comme s'ils étaient exécutés sur le matériel de base, sans virtualisation.
* L'efficacité : La grande partie des instructions machines doit s’exécuter directement sur le processeur, afin de garder des performances correctes. Ce critère n'est pas respecté par les émulateurs matériels, qui doivent simuler le jeu d'instruction du processeur émulé.
* Le contrôle des ressources : tout accès au matériel par l'O.S virtualisé doit être intercepté par la machine virtuelle et intégralement pris en charge par l'hyperviseur.
Remplir ces trois critères est possible sous certaines conditions, établies par les théorèmes de Popek et Goldberg. Ces théorèmes se basent sur des hypothèses précises. De fait, la portée de ces théorèmes est limitée, notamment pour le critère de performance. Ils partent notamment du principe que l'ordinateur utilise la segmentation pour la mémoire virtuelle, et non la pagination. Il part aussi du principe que les interruptions ont un cout assez faible, qu'elles sont assez rares. Mais laissons ces détails de côté, le cœur de ces théorèmes repose sur une hypothèse simple : la présence de différents types d'instructions machines.
Pour rappel, il faut distinguer les instructions privilégiées de celles qui ne le sont pas. Les instructions privilégiées ne peuvent s'exécuter que en mode noyau, les programmes en mode utilisateur ne peuvent pas les exécuter. Parmi les instructions privilégiées on peut distinguer un sous-groupe appelé les '''instructions systèmes'''. Le premier type regroupe les '''instructions d'accès aux entrées-sorties''', aussi appelées instructions sensibles à la configuration. Le second type est celui des '''instructions de configuration du processeur''', qui agissent sur les registres de contrôle du processeur, aussi appelées instructions sensibles au comportement.
La théorie de Popek et Goldberg dit qu'il est possible de virtualiser un O.S à une condition : que les instructions systèmes soient toutes des instructions privilégiées, c’est-à-dire exécutables seulement en mode noyau. Virtualiser un O.S demande simplement de le démarrer en mode utilisateur. Quand l'O.S fait un accès au matériel, il le fait via une instruction privilégiée. Vu que l'OS est en mode utilisateur, cela déclenche une exception matérielle, qui émule l'instruction privilégiée.
L'hyperviseur n'est ni plus ni moins qu'un ensemble de routines d'interruptions, chaque routine simulant le fonctionnement du matériel émulé. Par exemple, un accès au disque dur sera émulé par une routine d'interruption, qui utilisera les appels systèmes fournit par l'OS pour accéder au disque dur réellement présent dans l'ordinateur. Cette méthode est souvent appelée la méthode ''trap and emulate''.
[[File:Virtualisation avec la méthode trap-and-emulate.png|centre|vignette|upright=2.0|Virtualisation avec la méthode trap-and-emulate]]
La méthode ''trap and emulate'' ne fonctionne que si certaines contraintes sont respectées. Déjà, il faut que l'ordinateur utilise la mémoire virtuelle, sans quoi plusieurs OS ne peuvent pas se partager la même mémoire physique. De plus, il ne faut pas que la mémoire physique, non-virtuelle, puisse être adressée directement.
Et cette contrainte est violée, par exemple sur les architectures MIPS qui exposent des portions de la mémoire physique dans certaines zones fixées à l'avance de la mémoire virtuelle. L'OS est compilé pour utiliser ces zones de mémoire pour accéder aux entrées-sorties mappées en mémoire, entre autres. En théorie, on peut passer outre le problème en marquant ces zones de mémoire comme inaccessibles, toute lecture/écriture à ces adresses déclenche alors une exception traitée par l'hyperviseur. Mais le cout en performance est alors trop important.
Quelques hyperviseurs ont été conçus pour les architectures MIPS, dont le projet de recherche DISCO, mais ils ne fonctionnaient qu'avec des systèmes d'exploitation recompilés, de manière à passer outre ce problème. Les OS étaient recompilés afin de ne pas utiliser les zones mémoire problématiques. De plus, les OS étaient modifiés pour améliorer les performances en virtualisation. Les OS disposaient notamment d'appels systèmes spéciaux, appelés des ''hypercalls'', qui exécutaient des routines de l'hyperviseur directement.
Un autre problème est que beaucoup de jeux d'instructions anciens ne respectent pas la règle "les instructions systèmes sont toutes privilégiées". Par exemple, ce n'est pas le cas sur les processeurs x86 32 bits. Sur ces CPU, les instructions qui manipulent les drapeaux d'interruption ne sont pas toutes des instructions privilégiées, idem pour les instructions qui manipulent les registres de segmentation, celles liées aux ''call gates'', etc. A cause de cela, il est impossible d'utiliser la méthode du ''trap and emulate''. La seule solution qui ne requiert pas de techniques matérielles est de traduire à la volée les instructions systèmes problématiques en appels systèmes équivalents, grâce à des techniques de '''réécriture de code'''.
Enfin, certaines instructions dites '''sensibles au contexte''' ont un comportement différent entre le mode noyau et le mode utilisateur. En présence de telles instructions, la méthode ''trap and emulate'' ne fonctionne tout simplement pas. Grâce à ces instructions, le système d’exploitation ou un programme applicatif peut savoir s'il s'exécute en mode utilisateur ou noyau, ou hyperviseur, ou autre.
==La virtualisation du CPU : le mode hyperviseur==
Sur certains CPU modernes, il existe un niveau de privilège appelé le '''mode hyperviseur''' qui est utilisé pour les techniques de virtualisation. Le mode hyperviseur est réservé à l’hyperviseur et il a des droits d'accès spécifiques. Il n'est cependant pas toujours activé. Par exemple, si aucun hyperviseur n'est installé sur la machine, le processeur dispose seulement d'un mode noyau et d'un mode utilisateur normaux, le mode noyau n'ayant alors aucune limitation précise. Mais quand le mode hyperviseur est activé, une partie des manipulations est bloquée en mode noyau et n'est possible qu'en mode hyperviseur.
Le fonctionnement se base sur la différence entre instruction privilégiée et instruction système. Les instructions privilégiées peuvent s'exécuter en mode noyau, alors que les instructions systèmes ne peuvent s'exécuter qu'en mode hyperviseur. L'idée est que quand le noyau d'un OS exécute une instruction système, une exception matérielle est levée. L'exception bascule en mode hyperviseur et laisse la main à une routine de l'hyperviseur. L'hyperviseur fait alors des manipulations précise pour que l'instruction système donne le même résultat que si elle avait été exécutée par l'ordinateur simulé par la machine virtuelle.
[[File:Virtualisation avec un mode hyperviseur.png|centre|vignette|upright=2|Virtualisation avec un mode hyperviseur.]]
Il est ainsi possible d'émuler des entrées-sorties avec un cout en performance assez léger. Précisément, ce mode hyperviseur améliore les performances de la méthode du ''trap-and-emulate''. La méthode ''trap-and-emulate'' basique exécute une exception matérielle pour toute instruction privilégiées, qu'elle soit une instruction système ou non. Mais avec le mode hyperviseur, seules les instructions systèmes déclenchent une exception, pas les instructions privilégiées non-système. Les performances sont donc un peu meilleures, pour un résultat identique. Après tout, les entrées-sorties et la configuration du processeur suffisent à émuler une machine virtuelle, les autres instructions noyau ne le sont pas.
Sur les processeurs ARM, il est possible de configurer quelles instructions sont détournées vers le mode hyperviseur et celles qui restent en mode noyau. En clair, on peut configurer quelles sont les instructions systèmes et celles qui sont simplement privilégiées. Et il en est de même pour les interruptions : on peut configurer si elles exécutent la routine de l'OS normal en mode noyau, ou si elles déclenchent une exception matérielle qui redirige vers une routine de l’hyperviseur. En l'absence d'hyperviseur, toutes les interruptions redirigent vers la routine de l'OS normale, vers le mode noyau.
Les processeurs ARM de version v8 et plus incorporent un mode hyperviseur, mais pas les processeurs x86. A la place, ils incorporent des technologies alternatives nommées Intel Vtx ou l'AMD-V. Elles fonctionnent sur un principe totalement différent.
==La virtualisation de la mémoire RAM : l'extension des tables des pages emboitées==
Avec la virtualisation, les différentes machines virtuelles, les différents OS doivent se partager la mémoire physique. Et ce partage doit isoler les différents OS les uns des autres. Il est possible de comparer cette isolation avec l'isolation des processus : chaque OS doit avoir sa propre mémoire physique rien qu'à lui. L'idée est d'utiliser la mémoire virtuelle pour cela.
L'espace d'adressage physique vu par chaque OS est en réalité virtualisé, c’est-à-dire que c'est un espace d'adressage fictif, qui ne correspond pas à la mémoire virtuelle. Les adresses physiques vues par l'OS sont en réalité des adresses intermédiaires entre les adresses physiques liées à la RAM, et les adresses virtuelles vues par les processus. Pour les distinguer, nous parlerons d'adresses physiques de l'hôte pour parler des adresses de la RAM, et des adresses physiques invitées pour parler des adresses manipulées par les OS virtualisés. La raison est que les OS sont appelés des OS invités, alors que l'hyperviseur est parfois appelé l'OS hôte.
Sans accélération matérielle, la traduction des adresses physiques invitées en adresses hôte est réalisée par une seconde table des pages, appelée la ''shadow page table'', ce qui donnerait '''table des pages cachée''' en français. La table des pages cachée est prise en charge par l'hyperviseur. Toute modification de la table des pages cachée est réalisée par l'hyperviseur, les OS ne savent même pas qu'elle existe.
[[File:Shadowpagetables.png|centre|vignette|upright=2|Table des pages cachée.]]
Une autre solution demande un support matériel des tables des pages emboitées, à savoir qu'il y a un arbre de table des pages, chaque consultation de la première table des pages renvoie vers une seconde, qui renvoie vers une troisième, et ainsi de suite jusqu'à tomber sur la table des pages finale qui renvoie l'adresse physique réelle.
L'idée est l'utiliser une seule table des pages, mais d'ajouter un ou deux niveaux supplémentaires. Pour l'exemple, prenons le cas des processeurs x86. Sans virtualisation, l'OS utilise une table des pages de 4 niveaux. Avec, la table des pages a un niveau en plus, qui sont ajoutés à la fin de la dernière table des pages normale. Les niveaux ajoutés s'occupent de la traduction des adresses physiques invitées en adresses physiques hôte. Il faut que le processeur soit modifié de manière à parcourir automatiquement les niveaux ajoutés, ce qui demande quelques modifications de la TLB et du ''page table walker''.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les sections critiques et le modèle mémoire
| prevText=Les sections critiques et le modèle mémoire
| next=Le matériel réseau
| nextText=Le matériel réseau
}}
</noinclude>
23nnivj524t8nr87o98h0ekz5bpa0nq
744320
744319
2025-06-08T16:04:17Z
Mewtow
31375
/* La méthode trap and emulate basique */
744320
wikitext
text/x-wiki
La virtualisation est l'ensemble des techniques qui permettent de faire tourner plusieurs systèmes d'exploitation en même temps. Le terme est polysémique, mais c'est la définition que nous allons utiliser pour ce qui nous intéresse. La virtualisation demande d'utiliser un logiciel dit '''hyperviseur''', qui permet de faire tourner plusieurs OS en même temps. Les hyperviseurs sont en quelque sorte situés sous le système d'exploitation et on peut les voir comme une sorte de sous-système d'exploitation, de système d'exploitation pour les systèmes d'exploitation.
[[File:Diagramme ArchiHyperviseur.png|centre|vignette|upright=2|Différence entre système d'exploitation et hyperviseur.]]
Les processeurs modernes intègrent des techniques pour accélérer matériellement la virtualisation. Les techniques en question sont assez variées, allant d'un niveau de privilège en plus des modes noyau/utilisateur à des techniques de duplication de ces mêmes modes. Les techniques de virtualisation demandent de détourner des interruptions, ce qui fait que ces techniques d'accélération demandent de modifier la manière dont le processeur gère les interruptions. Mais pour comprendre tout cela, il va falloir faire quelques explications sur la virtualisation elle-même.
==La virtualisation : généralités==
Pour faire tourner plusieurs OS en même temps, l'hyperviseur recourt à de nombreux stratagèmes. Il doit partager le processeur, la RAM et les entrées-sorties entre plusieurs OS. Les trois demandent des techniques différentes. Le partage de la RAM demande concrètement des modifications au niveau de la mémoire virtuelle. Le partage du processeur est assez simple : les OS s'exécutent à tour de rôle sur le processeur, chacun pendant un temps défini, fixe. Une fois leur temps d'exécution passé, ils laissent la main à l'OS suivant. C'est l’hyperviseur qui s'occupe de tout cela, grâce à une interruption commandée à un ''timer''. Ce système de partage est une forme de '''multiplexage'''.
La gestion des entrées-sorties demande d'utiliser des techniques d''''émulation''', plus complexes à expliquer. Un hyperviseur peut parfaitement simuler du matériel qui n'est pas installé sur l'ordinateur. Par exemple, il peut faire croire à un OS qu'une carte réseau obsolète, datant d'il y a 20 ans, est installée sur l'ordinateur, alors que ce n'est pas le cas. Les commandes envoyées par l'OS à cette carte réseau fictive sont en réalité traitées par une vraie carte réseau par l’hyperviseur. Pour cela, l’hyperviseur intercepte les commandes envoyées aux entrées-sorties, et les traduit en commandes compatibles avec les entrées-sorties réellement installées sur l'ordinateur.
===Les machines virtuelles===
L'exemple avec la carte réseau est un cas particulier, l'hyperviseur faisant beaucoup de choses dans le genre. L'hyperviseur peut faire croire à l'ordinateur qu'il a plus ou moins de RAM que ce qui est réellement installé, par exemple. L'hyperviseur implémente ce qu'on appelle des '''machines virtuelles'''. Il s'agit d'une sorte de faux matériel, simulé par un logiciel. Un logiciel qui s’exécute dans une machine virtuelle aura l'impression de s’exécuter sur un matériel et/ou un O.S différent du matériel sur lequel il est en train de s’exécuter.
: Dans ce qui suit, nous parlerons de V.M (virtual machine), pour parler des machines virtuelles.
[[File:VM-monitor-french.png|centre|vignette|upright=2|Machines virtuelles avec la virtualisation.]]
L'hyperviseur crée plusieurs machines virtuelles, chacune étant réservée à un système d'exploitation. Il s'agit là d'une des utilisations possibles, mais il y en a d'autres. La plus intéressante est celle des émulateurs. Ces derniers sont des logiciels qui permettent de simuler le fonctionnement d'anciens ordinateurs ou consoles de jeux. L'émulateur crée une machine virtuelle qui est réservée à un programme, à savoir le jeu à émuler.
Il y a une différence de taille entre un émulateur et un hyperviseur. L'émulation émule une machine virtuelle totalement différente, alors que la virtualisation doit émuler les entrées-sorties mais pas le processeur. Avec un hyperviseur, le système d'exploitation s'exécute sur le processeur lui-même. Le code de l'OS est compatible avec le processeur de la machine, dans le sens où il est compilé pour le jeu d'instruction du processeur de la machine réelle. Les instructions de l'OS s'exécutent directement. Par contre, un émulateur exécute un jeu qui est programmé pour une machine dont le processeur est totalement différent. Le jeu d'instruction de la machine virtuelle et celui du vrai processeur n'est pas le même. L'émulation implique donc de traduire les instructions à exécuter dans la V.M par des instructions exécutables par le processeur. Ce n'est pas le cas avec la virtualisation, le jeu d'instruction étant le même.
[[File:Diagramme ArchiEmulateurNonNatif.png|centre|vignette|upright=2|Emulateur]]
===La méthode ''trap and emulate'' basique===
Pour être considéré comme un logiciel de virtualisation, un logiciel doit remplir trois critères :
* L'équivalence : l'O.S virtualisé et les applications qui s’exécutent doivent se comporter comme s'ils étaient exécutés sur le matériel de base, sans virtualisation.
* Le contrôle des ressources : tout accès au matériel par l'O.S virtualisé doit être intercepté par la machine virtuelle et intégralement pris en charge par l'hyperviseur.
* L'efficacité : La grande partie des instructions machines doit s’exécuter directement sur le processeur, afin de garder des performances correctes. Ce critère n'est pas respecté par les émulateurs matériels, qui doivent simuler le jeu d'instruction du processeur émulé.
Remplir ces trois critères est possible sous certaines conditions, établies par les théorèmes de Popek et Goldberg. Ces théorèmes se basent sur des hypothèses précises. De fait, la portée de ces théorèmes est limitée, notamment pour le critère de performance. Ils partent notamment du principe que l'ordinateur utilise la segmentation pour la mémoire virtuelle, et non la pagination. Il part aussi du principe que les interruptions ont un cout assez faible, qu'elles sont assez rares. Mais laissons ces détails de côté, le cœur de ces théorèmes repose sur une hypothèse simple : la présence de différents types d'instructions machines.
Pour rappel, il faut distinguer les instructions privilégiées de celles qui ne le sont pas. Les instructions privilégiées ne peuvent s'exécuter que en mode noyau, les programmes en mode utilisateur ne peuvent pas les exécuter. Parmi les instructions privilégiées on peut distinguer un sous-groupe appelé les '''instructions systèmes'''. Le premier type regroupe les '''instructions d'accès aux entrées-sorties''', aussi appelées instructions sensibles à la configuration. Le second type est celui des '''instructions de configuration du processeur''', qui agissent sur les registres de contrôle du processeur, aussi appelées instructions sensibles au comportement.
La théorie de Popek et Goldberg dit qu'il est possible de virtualiser un O.S à une condition : que les instructions systèmes soient toutes des instructions privilégiées, c’est-à-dire exécutables seulement en mode noyau. Virtualiser un O.S demande simplement de le démarrer en mode utilisateur. Quand l'O.S fait un accès au matériel, il le fait via une instruction privilégiée. Vu que l'OS est en mode utilisateur, cela déclenche une exception matérielle, qui émule l'instruction privilégiée.
L'hyperviseur n'est ni plus ni moins qu'un ensemble de routines d'interruptions, chaque routine simulant le fonctionnement du matériel émulé. Par exemple, un accès au disque dur sera émulé par une routine d'interruption, qui utilisera les appels systèmes fournit par l'OS pour accéder au disque dur réellement présent dans l'ordinateur. Cette méthode est souvent appelée la méthode ''trap and emulate''.
[[File:Virtualisation avec la méthode trap-and-emulate.png|centre|vignette|upright=2.0|Virtualisation avec la méthode trap-and-emulate]]
La méthode ''trap and emulate'' ne fonctionne que si certaines contraintes sont respectées. Déjà, il faut que l'ordinateur utilise la mémoire virtuelle, sans quoi plusieurs OS ne peuvent pas se partager la même mémoire physique. De plus, il ne faut pas que la mémoire physique, non-virtuelle, puisse être adressée directement.
Et cette contrainte est violée, par exemple sur les architectures MIPS qui exposent des portions de la mémoire physique dans certaines zones fixées à l'avance de la mémoire virtuelle. L'OS est compilé pour utiliser ces zones de mémoire pour accéder aux entrées-sorties mappées en mémoire, entre autres. En théorie, on peut passer outre le problème en marquant ces zones de mémoire comme inaccessibles, toute lecture/écriture à ces adresses déclenche alors une exception traitée par l'hyperviseur. Mais le cout en performance est alors trop important.
Quelques hyperviseurs ont été conçus pour les architectures MIPS, dont le projet de recherche DISCO, mais ils ne fonctionnaient qu'avec des systèmes d'exploitation recompilés, de manière à passer outre ce problème. Les OS étaient recompilés afin de ne pas utiliser les zones mémoire problématiques. De plus, les OS étaient modifiés pour améliorer les performances en virtualisation. Les OS disposaient notamment d'appels systèmes spéciaux, appelés des ''hypercalls'', qui exécutaient des routines de l'hyperviseur directement.
Un autre problème est que beaucoup de jeux d'instructions anciens ne respectent pas la règle "les instructions systèmes sont toutes privilégiées". Par exemple, ce n'est pas le cas sur les processeurs x86 32 bits. Sur ces CPU, les instructions qui manipulent les drapeaux d'interruption ne sont pas toutes des instructions privilégiées, idem pour les instructions qui manipulent les registres de segmentation, celles liées aux ''call gates'', etc. A cause de cela, il est impossible d'utiliser la méthode du ''trap and emulate''. La seule solution qui ne requiert pas de techniques matérielles est de traduire à la volée les instructions systèmes problématiques en appels systèmes équivalents, grâce à des techniques de '''réécriture de code'''.
Enfin, certaines instructions dites '''sensibles au contexte''' ont un comportement différent entre le mode noyau et le mode utilisateur. En présence de telles instructions, la méthode ''trap and emulate'' ne fonctionne tout simplement pas. Grâce à ces instructions, le système d’exploitation ou un programme applicatif peut savoir s'il s'exécute en mode utilisateur ou noyau, ou hyperviseur, ou autre.
==La virtualisation du CPU : le mode hyperviseur==
Sur certains CPU modernes, il existe un niveau de privilège appelé le '''mode hyperviseur''' qui est utilisé pour les techniques de virtualisation. Le mode hyperviseur est réservé à l’hyperviseur et il a des droits d'accès spécifiques. Il n'est cependant pas toujours activé. Par exemple, si aucun hyperviseur n'est installé sur la machine, le processeur dispose seulement d'un mode noyau et d'un mode utilisateur normaux, le mode noyau n'ayant alors aucune limitation précise. Mais quand le mode hyperviseur est activé, une partie des manipulations est bloquée en mode noyau et n'est possible qu'en mode hyperviseur.
Le fonctionnement se base sur la différence entre instruction privilégiée et instruction système. Les instructions privilégiées peuvent s'exécuter en mode noyau, alors que les instructions systèmes ne peuvent s'exécuter qu'en mode hyperviseur. L'idée est que quand le noyau d'un OS exécute une instruction système, une exception matérielle est levée. L'exception bascule en mode hyperviseur et laisse la main à une routine de l'hyperviseur. L'hyperviseur fait alors des manipulations précise pour que l'instruction système donne le même résultat que si elle avait été exécutée par l'ordinateur simulé par la machine virtuelle.
[[File:Virtualisation avec un mode hyperviseur.png|centre|vignette|upright=2|Virtualisation avec un mode hyperviseur.]]
Il est ainsi possible d'émuler des entrées-sorties avec un cout en performance assez léger. Précisément, ce mode hyperviseur améliore les performances de la méthode du ''trap-and-emulate''. La méthode ''trap-and-emulate'' basique exécute une exception matérielle pour toute instruction privilégiées, qu'elle soit une instruction système ou non. Mais avec le mode hyperviseur, seules les instructions systèmes déclenchent une exception, pas les instructions privilégiées non-système. Les performances sont donc un peu meilleures, pour un résultat identique. Après tout, les entrées-sorties et la configuration du processeur suffisent à émuler une machine virtuelle, les autres instructions noyau ne le sont pas.
Sur les processeurs ARM, il est possible de configurer quelles instructions sont détournées vers le mode hyperviseur et celles qui restent en mode noyau. En clair, on peut configurer quelles sont les instructions systèmes et celles qui sont simplement privilégiées. Et il en est de même pour les interruptions : on peut configurer si elles exécutent la routine de l'OS normal en mode noyau, ou si elles déclenchent une exception matérielle qui redirige vers une routine de l’hyperviseur. En l'absence d'hyperviseur, toutes les interruptions redirigent vers la routine de l'OS normale, vers le mode noyau.
Les processeurs ARM de version v8 et plus incorporent un mode hyperviseur, mais pas les processeurs x86. A la place, ils incorporent des technologies alternatives nommées Intel Vtx ou l'AMD-V. Elles fonctionnent sur un principe totalement différent.
==La virtualisation de la mémoire RAM : l'extension des tables des pages emboitées==
Avec la virtualisation, les différentes machines virtuelles, les différents OS doivent se partager la mémoire physique. Et ce partage doit isoler les différents OS les uns des autres. Il est possible de comparer cette isolation avec l'isolation des processus : chaque OS doit avoir sa propre mémoire physique rien qu'à lui. L'idée est d'utiliser la mémoire virtuelle pour cela.
L'espace d'adressage physique vu par chaque OS est en réalité virtualisé, c’est-à-dire que c'est un espace d'adressage fictif, qui ne correspond pas à la mémoire virtuelle. Les adresses physiques vues par l'OS sont en réalité des adresses intermédiaires entre les adresses physiques liées à la RAM, et les adresses virtuelles vues par les processus. Pour les distinguer, nous parlerons d'adresses physiques de l'hôte pour parler des adresses de la RAM, et des adresses physiques invitées pour parler des adresses manipulées par les OS virtualisés. La raison est que les OS sont appelés des OS invités, alors que l'hyperviseur est parfois appelé l'OS hôte.
Sans accélération matérielle, la traduction des adresses physiques invitées en adresses hôte est réalisée par une seconde table des pages, appelée la ''shadow page table'', ce qui donnerait '''table des pages cachée''' en français. La table des pages cachée est prise en charge par l'hyperviseur. Toute modification de la table des pages cachée est réalisée par l'hyperviseur, les OS ne savent même pas qu'elle existe.
[[File:Shadowpagetables.png|centre|vignette|upright=2|Table des pages cachée.]]
Une autre solution demande un support matériel des tables des pages emboitées, à savoir qu'il y a un arbre de table des pages, chaque consultation de la première table des pages renvoie vers une seconde, qui renvoie vers une troisième, et ainsi de suite jusqu'à tomber sur la table des pages finale qui renvoie l'adresse physique réelle.
L'idée est l'utiliser une seule table des pages, mais d'ajouter un ou deux niveaux supplémentaires. Pour l'exemple, prenons le cas des processeurs x86. Sans virtualisation, l'OS utilise une table des pages de 4 niveaux. Avec, la table des pages a un niveau en plus, qui sont ajoutés à la fin de la dernière table des pages normale. Les niveaux ajoutés s'occupent de la traduction des adresses physiques invitées en adresses physiques hôte. Il faut que le processeur soit modifié de manière à parcourir automatiquement les niveaux ajoutés, ce qui demande quelques modifications de la TLB et du ''page table walker''.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les sections critiques et le modèle mémoire
| prevText=Les sections critiques et le modèle mémoire
| next=Le matériel réseau
| nextText=Le matériel réseau
}}
</noinclude>
7ydp8e69yk9u1feooj00nlj3yq94xzb
744321
744320
2025-06-08T16:20:09Z
Mewtow
31375
/* La méthode trap and emulate basique */
744321
wikitext
text/x-wiki
La virtualisation est l'ensemble des techniques qui permettent de faire tourner plusieurs systèmes d'exploitation en même temps. Le terme est polysémique, mais c'est la définition que nous allons utiliser pour ce qui nous intéresse. La virtualisation demande d'utiliser un logiciel dit '''hyperviseur''', qui permet de faire tourner plusieurs OS en même temps. Les hyperviseurs sont en quelque sorte situés sous le système d'exploitation et on peut les voir comme une sorte de sous-système d'exploitation, de système d'exploitation pour les systèmes d'exploitation.
[[File:Diagramme ArchiHyperviseur.png|centre|vignette|upright=2|Différence entre système d'exploitation et hyperviseur.]]
Les processeurs modernes intègrent des techniques pour accélérer matériellement la virtualisation. Les techniques en question sont assez variées, allant d'un niveau de privilège en plus des modes noyau/utilisateur à des techniques de duplication de ces mêmes modes. Les techniques de virtualisation demandent de détourner des interruptions, ce qui fait que ces techniques d'accélération demandent de modifier la manière dont le processeur gère les interruptions. Mais pour comprendre tout cela, il va falloir faire quelques explications sur la virtualisation elle-même.
==La virtualisation : généralités==
Pour faire tourner plusieurs OS en même temps, l'hyperviseur recourt à de nombreux stratagèmes. Il doit partager le processeur, la RAM et les entrées-sorties entre plusieurs OS. Les trois demandent des techniques différentes. Le partage de la RAM demande concrètement des modifications au niveau de la mémoire virtuelle. Le partage du processeur est assez simple : les OS s'exécutent à tour de rôle sur le processeur, chacun pendant un temps défini, fixe. Une fois leur temps d'exécution passé, ils laissent la main à l'OS suivant. C'est l’hyperviseur qui s'occupe de tout cela, grâce à une interruption commandée à un ''timer''. Ce système de partage est une forme de '''multiplexage'''.
La gestion des entrées-sorties demande d'utiliser des techniques d''''émulation''', plus complexes à expliquer. Un hyperviseur peut parfaitement simuler du matériel qui n'est pas installé sur l'ordinateur. Par exemple, il peut faire croire à un OS qu'une carte réseau obsolète, datant d'il y a 20 ans, est installée sur l'ordinateur, alors que ce n'est pas le cas. Les commandes envoyées par l'OS à cette carte réseau fictive sont en réalité traitées par une vraie carte réseau par l’hyperviseur. Pour cela, l’hyperviseur intercepte les commandes envoyées aux entrées-sorties, et les traduit en commandes compatibles avec les entrées-sorties réellement installées sur l'ordinateur.
===Les machines virtuelles===
L'exemple avec la carte réseau est un cas particulier, l'hyperviseur faisant beaucoup de choses dans le genre. L'hyperviseur peut faire croire à l'ordinateur qu'il a plus ou moins de RAM que ce qui est réellement installé, par exemple. L'hyperviseur implémente ce qu'on appelle des '''machines virtuelles'''. Il s'agit d'une sorte de faux matériel, simulé par un logiciel. Un logiciel qui s’exécute dans une machine virtuelle aura l'impression de s’exécuter sur un matériel et/ou un O.S différent du matériel sur lequel il est en train de s’exécuter.
: Dans ce qui suit, nous parlerons de V.M (virtual machine), pour parler des machines virtuelles.
[[File:VM-monitor-french.png|centre|vignette|upright=2|Machines virtuelles avec la virtualisation.]]
L'hyperviseur crée plusieurs machines virtuelles, chacune étant réservée à un système d'exploitation. Il s'agit là d'une des utilisations possibles, mais il y en a d'autres. La plus intéressante est celle des émulateurs. Ces derniers sont des logiciels qui permettent de simuler le fonctionnement d'anciens ordinateurs ou consoles de jeux. L'émulateur crée une machine virtuelle qui est réservée à un programme, à savoir le jeu à émuler.
Il y a une différence de taille entre un émulateur et un hyperviseur. L'émulation émule une machine virtuelle totalement différente, alors que la virtualisation doit émuler les entrées-sorties mais pas le processeur. Avec un hyperviseur, le système d'exploitation s'exécute sur le processeur lui-même. Le code de l'OS est compatible avec le processeur de la machine, dans le sens où il est compilé pour le jeu d'instruction du processeur de la machine réelle. Les instructions de l'OS s'exécutent directement. Par contre, un émulateur exécute un jeu qui est programmé pour une machine dont le processeur est totalement différent. Le jeu d'instruction de la machine virtuelle et celui du vrai processeur n'est pas le même. L'émulation implique donc de traduire les instructions à exécuter dans la V.M par des instructions exécutables par le processeur. Ce n'est pas le cas avec la virtualisation, le jeu d'instruction étant le même.
[[File:Diagramme ArchiEmulateurNonNatif.png|centre|vignette|upright=2|Emulateur]]
===La méthode ''trap and emulate'' basique===
Pour être considéré comme un logiciel de virtualisation, un logiciel doit remplir trois critères :
* L'équivalence : l'O.S virtualisé et les applications qui s’exécutent doivent se comporter comme s'ils étaient exécutés sur le matériel de base, sans virtualisation.
* Le contrôle des ressources : tout accès au matériel par l'O.S virtualisé doit être intercepté par la machine virtuelle et intégralement pris en charge par l'hyperviseur.
* L'efficacité : La grande partie des instructions machines doit s’exécuter directement sur le processeur, afin de garder des performances correctes. Ce critère n'est pas respecté par les émulateurs matériels, qui doivent simuler le jeu d'instruction du processeur émulé.
Remplir ces trois critères est possible sous certaines conditions, établies par les théorèmes de Popek et Goldberg. Ces théorèmes se basent sur des hypothèses précises. De fait, la portée de ces théorèmes est limitée, notamment pour le critère de performance. Ils partent notamment du principe que l'ordinateur utilise la segmentation pour la mémoire virtuelle, et non la pagination. Il part aussi du principe que les interruptions ont un cout assez faible, qu'elles sont assez rares. Mais laissons ces détails de côté, le cœur de ces théorèmes repose sur une hypothèse simple : la présence de différents types d'instructions machines.
Pour rappel, il faut distinguer les instructions privilégiées de celles qui ne le sont pas. Les instructions privilégiées ne peuvent s'exécuter que en mode noyau, les programmes en mode utilisateur ne peuvent pas les exécuter. Parmi les instructions privilégiées on peut distinguer un sous-groupe appelé les '''instructions systèmes'''. Le premier type regroupe les '''instructions d'accès aux entrées-sorties''', aussi appelées instructions sensibles à la configuration. Le second type est celui des '''instructions de configuration du processeur''', qui agissent sur les registres de contrôle du processeur, aussi appelées instructions sensibles au comportement.
La théorie de Popek et Goldberg dit qu'il est possible de virtualiser un O.S à une condition : que les instructions systèmes soient toutes des instructions privilégiées, c’est-à-dire exécutables seulement en mode noyau. Virtualiser un O.S demande simplement de le démarrer en mode utilisateur. Quand l'O.S fait un accès au matériel, il le fait via une instruction privilégiée. Vu que l'OS est en mode utilisateur, cela déclenche une exception matérielle, qui émule l'instruction privilégiée.
L'hyperviseur n'est ni plus ni moins qu'un ensemble de routines d'interruptions, chaque routine simulant le fonctionnement du matériel émulé. Par exemple, un accès au disque dur sera émulé par une routine d'interruption, qui utilisera les appels systèmes fournit par l'OS pour accéder au disque dur réellement présent dans l'ordinateur. Cette méthode est souvent appelée la méthode ''trap and emulate''.
[[File:Virtualisation avec la méthode trap-and-emulate.png|centre|vignette|upright=2.0|Virtualisation avec la méthode trap-and-emulate]]
La méthode ''trap and emulate'' ne fonctionne que si certaines contraintes sont respectées. Un premier problème est que beaucoup de jeux d'instructions anciens ne respectent pas la règle "les instructions systèmes sont toutes privilégiées". Par exemple, ce n'est pas le cas sur les processeurs x86 32 bits. Sur ces CPU, les instructions qui manipulent les drapeaux d'interruption ne sont pas toutes des instructions privilégiées, idem pour les instructions qui manipulent les registres de segmentation, celles liées aux ''call gates'', etc. A cause de cela, il est impossible d'utiliser la méthode du ''trap and emulate''. La seule solution qui ne requiert pas de techniques matérielles est de traduire à la volée les instructions systèmes problématiques en appels systèmes équivalents, grâce à des techniques de '''réécriture de code'''.
Enfin, certaines instructions dites '''sensibles au contexte''' ont un comportement différent entre le mode noyau et le mode utilisateur. En présence de telles instructions, la méthode ''trap and emulate'' ne fonctionne tout simplement pas. Grâce à ces instructions, le système d’exploitation ou un programme applicatif peut savoir s'il s'exécute en mode utilisateur ou noyau, ou hyperviseur, ou autre.
La virtualisation impose l'usage de la mémoire virtuelle, sans quoi plusieurs OS ne peuvent pas se partager la même mémoire physique. De plus, il ne faut pas que la mémoire physique, non-virtuelle, puisse être adressée directement. Et cette contrainte est violée, par exemple sur les architectures MIPS qui exposent des portions de la mémoire physique dans certaines zones fixées à l'avance de la mémoire virtuelle. L'OS est compilé pour utiliser ces zones de mémoire pour accéder aux entrées-sorties mappées en mémoire, entre autres. En théorie, on peut passer outre le problème en marquant ces zones de mémoire comme inaccessibles, toute lecture/écriture à ces adresses déclenche alors une exception traitée par l'hyperviseur. Mais le cout en performance est alors trop important.
Quelques hyperviseurs ont été conçus pour les architectures MIPS, dont le projet de recherche DISCO, mais ils ne fonctionnaient qu'avec des systèmes d'exploitation recompilés, de manière à passer outre ce problème. Les OS étaient recompilés afin de ne pas utiliser les zones mémoire problématiques. De plus, les OS étaient modifiés pour améliorer les performances en virtualisation. Les OS disposaient notamment d'appels systèmes spéciaux, appelés des ''hypercalls'', qui exécutaient des routines de l'hyperviseur directement. Les appels systèmes faisant appel à des instructions systèmes étaient ainsi remplacé par des appels système appelant directement l'hyperviseur. Le fait de modifier l'OS pour qu'il communique avec un hyperviseur, dont il a connaissance de l'existence, s'appelle la '''para-virtualisation'''.
[[File:Virtualization - Para vs Full.png|centre|vignette|upright=2|Virtualization - Para vs Full]]
==La virtualisation du CPU : le mode hyperviseur==
Sur certains CPU modernes, il existe un niveau de privilège appelé le '''mode hyperviseur''' qui est utilisé pour les techniques de virtualisation. Le mode hyperviseur est réservé à l’hyperviseur et il a des droits d'accès spécifiques. Il n'est cependant pas toujours activé. Par exemple, si aucun hyperviseur n'est installé sur la machine, le processeur dispose seulement d'un mode noyau et d'un mode utilisateur normaux, le mode noyau n'ayant alors aucune limitation précise. Mais quand le mode hyperviseur est activé, une partie des manipulations est bloquée en mode noyau et n'est possible qu'en mode hyperviseur.
Le fonctionnement se base sur la différence entre instruction privilégiée et instruction système. Les instructions privilégiées peuvent s'exécuter en mode noyau, alors que les instructions systèmes ne peuvent s'exécuter qu'en mode hyperviseur. L'idée est que quand le noyau d'un OS exécute une instruction système, une exception matérielle est levée. L'exception bascule en mode hyperviseur et laisse la main à une routine de l'hyperviseur. L'hyperviseur fait alors des manipulations précise pour que l'instruction système donne le même résultat que si elle avait été exécutée par l'ordinateur simulé par la machine virtuelle.
[[File:Virtualisation avec un mode hyperviseur.png|centre|vignette|upright=2|Virtualisation avec un mode hyperviseur.]]
Il est ainsi possible d'émuler des entrées-sorties avec un cout en performance assez léger. Précisément, ce mode hyperviseur améliore les performances de la méthode du ''trap-and-emulate''. La méthode ''trap-and-emulate'' basique exécute une exception matérielle pour toute instruction privilégiées, qu'elle soit une instruction système ou non. Mais avec le mode hyperviseur, seules les instructions systèmes déclenchent une exception, pas les instructions privilégiées non-système. Les performances sont donc un peu meilleures, pour un résultat identique. Après tout, les entrées-sorties et la configuration du processeur suffisent à émuler une machine virtuelle, les autres instructions noyau ne le sont pas.
Sur les processeurs ARM, il est possible de configurer quelles instructions sont détournées vers le mode hyperviseur et celles qui restent en mode noyau. En clair, on peut configurer quelles sont les instructions systèmes et celles qui sont simplement privilégiées. Et il en est de même pour les interruptions : on peut configurer si elles exécutent la routine de l'OS normal en mode noyau, ou si elles déclenchent une exception matérielle qui redirige vers une routine de l’hyperviseur. En l'absence d'hyperviseur, toutes les interruptions redirigent vers la routine de l'OS normale, vers le mode noyau.
Les processeurs ARM de version v8 et plus incorporent un mode hyperviseur, mais pas les processeurs x86. A la place, ils incorporent des technologies alternatives nommées Intel Vtx ou l'AMD-V. Elles fonctionnent sur un principe totalement différent.
==La virtualisation de la mémoire RAM : l'extension des tables des pages emboitées==
Avec la virtualisation, les différentes machines virtuelles, les différents OS doivent se partager la mémoire physique. Et ce partage doit isoler les différents OS les uns des autres. Il est possible de comparer cette isolation avec l'isolation des processus : chaque OS doit avoir sa propre mémoire physique rien qu'à lui. L'idée est d'utiliser la mémoire virtuelle pour cela.
L'espace d'adressage physique vu par chaque OS est en réalité virtualisé, c’est-à-dire que c'est un espace d'adressage fictif, qui ne correspond pas à la mémoire virtuelle. Les adresses physiques vues par l'OS sont en réalité des adresses intermédiaires entre les adresses physiques liées à la RAM, et les adresses virtuelles vues par les processus. Pour les distinguer, nous parlerons d'adresses physiques de l'hôte pour parler des adresses de la RAM, et des adresses physiques invitées pour parler des adresses manipulées par les OS virtualisés. La raison est que les OS sont appelés des OS invités, alors que l'hyperviseur est parfois appelé l'OS hôte.
Sans accélération matérielle, la traduction des adresses physiques invitées en adresses hôte est réalisée par une seconde table des pages, appelée la ''shadow page table'', ce qui donnerait '''table des pages cachée''' en français. La table des pages cachée est prise en charge par l'hyperviseur. Toute modification de la table des pages cachée est réalisée par l'hyperviseur, les OS ne savent même pas qu'elle existe.
[[File:Shadowpagetables.png|centre|vignette|upright=2|Table des pages cachée.]]
Une autre solution demande un support matériel des tables des pages emboitées, à savoir qu'il y a un arbre de table des pages, chaque consultation de la première table des pages renvoie vers une seconde, qui renvoie vers une troisième, et ainsi de suite jusqu'à tomber sur la table des pages finale qui renvoie l'adresse physique réelle.
L'idée est l'utiliser une seule table des pages, mais d'ajouter un ou deux niveaux supplémentaires. Pour l'exemple, prenons le cas des processeurs x86. Sans virtualisation, l'OS utilise une table des pages de 4 niveaux. Avec, la table des pages a un niveau en plus, qui sont ajoutés à la fin de la dernière table des pages normale. Les niveaux ajoutés s'occupent de la traduction des adresses physiques invitées en adresses physiques hôte. Il faut que le processeur soit modifié de manière à parcourir automatiquement les niveaux ajoutés, ce qui demande quelques modifications de la TLB et du ''page table walker''.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les sections critiques et le modèle mémoire
| prevText=Les sections critiques et le modèle mémoire
| next=Le matériel réseau
| nextText=Le matériel réseau
}}
</noinclude>
l628e0tifxzz1pzokdkr51mi9c098z5
744322
744321
2025-06-08T16:20:22Z
Mewtow
31375
/* La méthode trap and emulate basique */
744322
wikitext
text/x-wiki
La virtualisation est l'ensemble des techniques qui permettent de faire tourner plusieurs systèmes d'exploitation en même temps. Le terme est polysémique, mais c'est la définition que nous allons utiliser pour ce qui nous intéresse. La virtualisation demande d'utiliser un logiciel dit '''hyperviseur''', qui permet de faire tourner plusieurs OS en même temps. Les hyperviseurs sont en quelque sorte situés sous le système d'exploitation et on peut les voir comme une sorte de sous-système d'exploitation, de système d'exploitation pour les systèmes d'exploitation.
[[File:Diagramme ArchiHyperviseur.png|centre|vignette|upright=2|Différence entre système d'exploitation et hyperviseur.]]
Les processeurs modernes intègrent des techniques pour accélérer matériellement la virtualisation. Les techniques en question sont assez variées, allant d'un niveau de privilège en plus des modes noyau/utilisateur à des techniques de duplication de ces mêmes modes. Les techniques de virtualisation demandent de détourner des interruptions, ce qui fait que ces techniques d'accélération demandent de modifier la manière dont le processeur gère les interruptions. Mais pour comprendre tout cela, il va falloir faire quelques explications sur la virtualisation elle-même.
==La virtualisation : généralités==
Pour faire tourner plusieurs OS en même temps, l'hyperviseur recourt à de nombreux stratagèmes. Il doit partager le processeur, la RAM et les entrées-sorties entre plusieurs OS. Les trois demandent des techniques différentes. Le partage de la RAM demande concrètement des modifications au niveau de la mémoire virtuelle. Le partage du processeur est assez simple : les OS s'exécutent à tour de rôle sur le processeur, chacun pendant un temps défini, fixe. Une fois leur temps d'exécution passé, ils laissent la main à l'OS suivant. C'est l’hyperviseur qui s'occupe de tout cela, grâce à une interruption commandée à un ''timer''. Ce système de partage est une forme de '''multiplexage'''.
La gestion des entrées-sorties demande d'utiliser des techniques d''''émulation''', plus complexes à expliquer. Un hyperviseur peut parfaitement simuler du matériel qui n'est pas installé sur l'ordinateur. Par exemple, il peut faire croire à un OS qu'une carte réseau obsolète, datant d'il y a 20 ans, est installée sur l'ordinateur, alors que ce n'est pas le cas. Les commandes envoyées par l'OS à cette carte réseau fictive sont en réalité traitées par une vraie carte réseau par l’hyperviseur. Pour cela, l’hyperviseur intercepte les commandes envoyées aux entrées-sorties, et les traduit en commandes compatibles avec les entrées-sorties réellement installées sur l'ordinateur.
===Les machines virtuelles===
L'exemple avec la carte réseau est un cas particulier, l'hyperviseur faisant beaucoup de choses dans le genre. L'hyperviseur peut faire croire à l'ordinateur qu'il a plus ou moins de RAM que ce qui est réellement installé, par exemple. L'hyperviseur implémente ce qu'on appelle des '''machines virtuelles'''. Il s'agit d'une sorte de faux matériel, simulé par un logiciel. Un logiciel qui s’exécute dans une machine virtuelle aura l'impression de s’exécuter sur un matériel et/ou un O.S différent du matériel sur lequel il est en train de s’exécuter.
: Dans ce qui suit, nous parlerons de V.M (virtual machine), pour parler des machines virtuelles.
[[File:VM-monitor-french.png|centre|vignette|upright=2|Machines virtuelles avec la virtualisation.]]
L'hyperviseur crée plusieurs machines virtuelles, chacune étant réservée à un système d'exploitation. Il s'agit là d'une des utilisations possibles, mais il y en a d'autres. La plus intéressante est celle des émulateurs. Ces derniers sont des logiciels qui permettent de simuler le fonctionnement d'anciens ordinateurs ou consoles de jeux. L'émulateur crée une machine virtuelle qui est réservée à un programme, à savoir le jeu à émuler.
Il y a une différence de taille entre un émulateur et un hyperviseur. L'émulation émule une machine virtuelle totalement différente, alors que la virtualisation doit émuler les entrées-sorties mais pas le processeur. Avec un hyperviseur, le système d'exploitation s'exécute sur le processeur lui-même. Le code de l'OS est compatible avec le processeur de la machine, dans le sens où il est compilé pour le jeu d'instruction du processeur de la machine réelle. Les instructions de l'OS s'exécutent directement. Par contre, un émulateur exécute un jeu qui est programmé pour une machine dont le processeur est totalement différent. Le jeu d'instruction de la machine virtuelle et celui du vrai processeur n'est pas le même. L'émulation implique donc de traduire les instructions à exécuter dans la V.M par des instructions exécutables par le processeur. Ce n'est pas le cas avec la virtualisation, le jeu d'instruction étant le même.
[[File:Diagramme ArchiEmulateurNonNatif.png|centre|vignette|upright=2|Emulateur]]
===La méthode ''trap and emulate'' basique===
Pour être considéré comme un logiciel de virtualisation, un logiciel doit remplir trois critères :
* L'équivalence : l'O.S virtualisé et les applications qui s’exécutent doivent se comporter comme s'ils étaient exécutés sur le matériel de base, sans virtualisation.
* Le contrôle des ressources : tout accès au matériel par l'O.S virtualisé doit être intercepté par la machine virtuelle et intégralement pris en charge par l'hyperviseur.
* L'efficacité : La grande partie des instructions machines doit s’exécuter directement sur le processeur, afin de garder des performances correctes. Ce critère n'est pas respecté par les émulateurs matériels, qui doivent simuler le jeu d'instruction du processeur émulé.
Remplir ces trois critères est possible sous certaines conditions, établies par les théorèmes de Popek et Goldberg. Ces théorèmes se basent sur des hypothèses précises. De fait, la portée de ces théorèmes est limitée, notamment pour le critère de performance. Ils partent notamment du principe que l'ordinateur utilise la segmentation pour la mémoire virtuelle, et non la pagination. Il part aussi du principe que les interruptions ont un cout assez faible, qu'elles sont assez rares. Mais laissons ces détails de côté, le cœur de ces théorèmes repose sur une hypothèse simple : la présence de différents types d'instructions machines.
Pour rappel, il faut distinguer les instructions privilégiées de celles qui ne le sont pas. Les instructions privilégiées ne peuvent s'exécuter que en mode noyau, les programmes en mode utilisateur ne peuvent pas les exécuter. Parmi les instructions privilégiées on peut distinguer un sous-groupe appelé les '''instructions systèmes'''. Le premier type regroupe les '''instructions d'accès aux entrées-sorties''', aussi appelées instructions sensibles à la configuration. Le second type est celui des '''instructions de configuration du processeur''', qui agissent sur les registres de contrôle du processeur, aussi appelées instructions sensibles au comportement.
La théorie de Popek et Goldberg dit qu'il est possible de virtualiser un O.S à une condition : que les instructions systèmes soient toutes des instructions privilégiées, c’est-à-dire exécutables seulement en mode noyau. Virtualiser un O.S demande simplement de le démarrer en mode utilisateur. Quand l'O.S fait un accès au matériel, il le fait via une instruction privilégiée. Vu que l'OS est en mode utilisateur, cela déclenche une exception matérielle, qui émule l'instruction privilégiée.
L'hyperviseur n'est ni plus ni moins qu'un ensemble de routines d'interruptions, chaque routine simulant le fonctionnement du matériel émulé. Par exemple, un accès au disque dur sera émulé par une routine d'interruption, qui utilisera les appels systèmes fournit par l'OS pour accéder au disque dur réellement présent dans l'ordinateur. Cette méthode est souvent appelée la méthode ''trap and emulate''.
[[File:Virtualisation avec la méthode trap-and-emulate.png|centre|vignette|upright=2.0|Virtualisation avec la méthode trap-and-emulate]]
La méthode ''trap and emulate'' ne fonctionne que si certaines contraintes sont respectées. Un premier problème est que beaucoup de jeux d'instructions anciens ne respectent pas la règle "les instructions systèmes sont toutes privilégiées". Par exemple, ce n'est pas le cas sur les processeurs x86 32 bits. Sur ces CPU, les instructions qui manipulent les drapeaux d'interruption ne sont pas toutes des instructions privilégiées, idem pour les instructions qui manipulent les registres de segmentation, celles liées aux ''call gates'', etc. A cause de cela, il est impossible d'utiliser la méthode du ''trap and emulate''. La seule solution qui ne requiert pas de techniques matérielles est de traduire à la volée les instructions systèmes problématiques en appels systèmes équivalents, grâce à des techniques de '''réécriture de code'''.
Enfin, certaines instructions dites '''sensibles au contexte''' ont un comportement différent entre le mode noyau et le mode utilisateur. En présence de telles instructions, la méthode ''trap and emulate'' ne fonctionne tout simplement pas. Grâce à ces instructions, le système d’exploitation ou un programme applicatif peut savoir s'il s'exécute en mode utilisateur ou noyau, ou hyperviseur, ou autre.
La virtualisation impose l'usage de la mémoire virtuelle, sans quoi plusieurs OS ne peuvent pas se partager la même mémoire physique. De plus, il ne faut pas que la mémoire physique, non-virtuelle, puisse être adressée directement. Et cette contrainte est violée, par exemple sur les architectures MIPS qui exposent des portions de la mémoire physique dans certaines zones fixées à l'avance de la mémoire virtuelle. L'OS est compilé pour utiliser ces zones de mémoire pour accéder aux entrées-sorties mappées en mémoire, entre autres. En théorie, on peut passer outre le problème en marquant ces zones de mémoire comme inaccessibles, toute lecture/écriture à ces adresses déclenche alors une exception traitée par l'hyperviseur. Mais le cout en performance est alors trop important.
Quelques hyperviseurs ont été conçus pour les architectures MIPS, dont le projet de recherche DISCO, mais ils ne fonctionnaient qu'avec des systèmes d'exploitation recompilés, de manière à passer outre ce problème. Les OS étaient recompilés afin de ne pas utiliser les zones mémoire problématiques. De plus, les OS étaient modifiés pour améliorer les performances en virtualisation. Les OS disposaient notamment d'appels systèmes spéciaux, appelés des ''hypercalls'', qui exécutaient des routines de l'hyperviseur directement. Les appels systèmes faisant appel à des instructions systèmes étaient ainsi remplacé par des appels système appelant directement l'hyperviseur. Le fait de modifier l'OS pour qu'il communique avec un hyperviseur, dont il a connaissance de l'existence, s'appelle la '''para-virtualisation'''.
[[File:Virtualization - Para vs Full.png|centre|vignette|upright=2.5|Virtualization - Para vs Full]]
==La virtualisation du CPU : le mode hyperviseur==
Sur certains CPU modernes, il existe un niveau de privilège appelé le '''mode hyperviseur''' qui est utilisé pour les techniques de virtualisation. Le mode hyperviseur est réservé à l’hyperviseur et il a des droits d'accès spécifiques. Il n'est cependant pas toujours activé. Par exemple, si aucun hyperviseur n'est installé sur la machine, le processeur dispose seulement d'un mode noyau et d'un mode utilisateur normaux, le mode noyau n'ayant alors aucune limitation précise. Mais quand le mode hyperviseur est activé, une partie des manipulations est bloquée en mode noyau et n'est possible qu'en mode hyperviseur.
Le fonctionnement se base sur la différence entre instruction privilégiée et instruction système. Les instructions privilégiées peuvent s'exécuter en mode noyau, alors que les instructions systèmes ne peuvent s'exécuter qu'en mode hyperviseur. L'idée est que quand le noyau d'un OS exécute une instruction système, une exception matérielle est levée. L'exception bascule en mode hyperviseur et laisse la main à une routine de l'hyperviseur. L'hyperviseur fait alors des manipulations précise pour que l'instruction système donne le même résultat que si elle avait été exécutée par l'ordinateur simulé par la machine virtuelle.
[[File:Virtualisation avec un mode hyperviseur.png|centre|vignette|upright=2|Virtualisation avec un mode hyperviseur.]]
Il est ainsi possible d'émuler des entrées-sorties avec un cout en performance assez léger. Précisément, ce mode hyperviseur améliore les performances de la méthode du ''trap-and-emulate''. La méthode ''trap-and-emulate'' basique exécute une exception matérielle pour toute instruction privilégiées, qu'elle soit une instruction système ou non. Mais avec le mode hyperviseur, seules les instructions systèmes déclenchent une exception, pas les instructions privilégiées non-système. Les performances sont donc un peu meilleures, pour un résultat identique. Après tout, les entrées-sorties et la configuration du processeur suffisent à émuler une machine virtuelle, les autres instructions noyau ne le sont pas.
Sur les processeurs ARM, il est possible de configurer quelles instructions sont détournées vers le mode hyperviseur et celles qui restent en mode noyau. En clair, on peut configurer quelles sont les instructions systèmes et celles qui sont simplement privilégiées. Et il en est de même pour les interruptions : on peut configurer si elles exécutent la routine de l'OS normal en mode noyau, ou si elles déclenchent une exception matérielle qui redirige vers une routine de l’hyperviseur. En l'absence d'hyperviseur, toutes les interruptions redirigent vers la routine de l'OS normale, vers le mode noyau.
Les processeurs ARM de version v8 et plus incorporent un mode hyperviseur, mais pas les processeurs x86. A la place, ils incorporent des technologies alternatives nommées Intel Vtx ou l'AMD-V. Elles fonctionnent sur un principe totalement différent.
==La virtualisation de la mémoire RAM : l'extension des tables des pages emboitées==
Avec la virtualisation, les différentes machines virtuelles, les différents OS doivent se partager la mémoire physique. Et ce partage doit isoler les différents OS les uns des autres. Il est possible de comparer cette isolation avec l'isolation des processus : chaque OS doit avoir sa propre mémoire physique rien qu'à lui. L'idée est d'utiliser la mémoire virtuelle pour cela.
L'espace d'adressage physique vu par chaque OS est en réalité virtualisé, c’est-à-dire que c'est un espace d'adressage fictif, qui ne correspond pas à la mémoire virtuelle. Les adresses physiques vues par l'OS sont en réalité des adresses intermédiaires entre les adresses physiques liées à la RAM, et les adresses virtuelles vues par les processus. Pour les distinguer, nous parlerons d'adresses physiques de l'hôte pour parler des adresses de la RAM, et des adresses physiques invitées pour parler des adresses manipulées par les OS virtualisés. La raison est que les OS sont appelés des OS invités, alors que l'hyperviseur est parfois appelé l'OS hôte.
Sans accélération matérielle, la traduction des adresses physiques invitées en adresses hôte est réalisée par une seconde table des pages, appelée la ''shadow page table'', ce qui donnerait '''table des pages cachée''' en français. La table des pages cachée est prise en charge par l'hyperviseur. Toute modification de la table des pages cachée est réalisée par l'hyperviseur, les OS ne savent même pas qu'elle existe.
[[File:Shadowpagetables.png|centre|vignette|upright=2|Table des pages cachée.]]
Une autre solution demande un support matériel des tables des pages emboitées, à savoir qu'il y a un arbre de table des pages, chaque consultation de la première table des pages renvoie vers une seconde, qui renvoie vers une troisième, et ainsi de suite jusqu'à tomber sur la table des pages finale qui renvoie l'adresse physique réelle.
L'idée est l'utiliser une seule table des pages, mais d'ajouter un ou deux niveaux supplémentaires. Pour l'exemple, prenons le cas des processeurs x86. Sans virtualisation, l'OS utilise une table des pages de 4 niveaux. Avec, la table des pages a un niveau en plus, qui sont ajoutés à la fin de la dernière table des pages normale. Les niveaux ajoutés s'occupent de la traduction des adresses physiques invitées en adresses physiques hôte. Il faut que le processeur soit modifié de manière à parcourir automatiquement les niveaux ajoutés, ce qui demande quelques modifications de la TLB et du ''page table walker''.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les sections critiques et le modèle mémoire
| prevText=Les sections critiques et le modèle mémoire
| next=Le matériel réseau
| nextText=Le matériel réseau
}}
</noinclude>
sjs58hij5ci2tkuptgp4esglg0f2liw
744323
744322
2025-06-08T16:25:08Z
Mewtow
31375
744323
wikitext
text/x-wiki
La virtualisation est l'ensemble des techniques qui permettent de faire tourner plusieurs systèmes d'exploitation en même temps. Le terme est polysémique, mais c'est la définition que nous allons utiliser pour ce qui nous intéresse. La virtualisation demande d'utiliser un logiciel dit '''hyperviseur''', qui permet de faire tourner plusieurs OS en même temps. Les hyperviseurs sont en quelque sorte situés sous le système d'exploitation et on peut les voir comme une sorte de sous-système d'exploitation, de système d'exploitation pour les systèmes d'exploitation.
[[File:Diagramme ArchiHyperviseur.png|centre|vignette|upright=2|Différence entre système d'exploitation et hyperviseur.]]
Les processeurs modernes intègrent des techniques pour accélérer matériellement la virtualisation. Les techniques en question sont assez variées, allant d'un niveau de privilège en plus des modes noyau/utilisateur à des techniques de duplication de ces mêmes modes. Les techniques de virtualisation demandent de détourner des interruptions, ce qui fait que ces techniques d'accélération demandent de modifier la manière dont le processeur gère les interruptions. Mais pour comprendre tout cela, il va falloir faire quelques explications sur la virtualisation elle-même.
==La virtualisation : généralités==
Pour faire tourner plusieurs OS en même temps, l'hyperviseur recourt à de nombreux stratagèmes. Il doit partager le processeur, la RAM et les entrées-sorties entre plusieurs OS. Les trois demandent des techniques différentes. Le partage de la RAM demande concrètement des modifications au niveau de la mémoire virtuelle. Le partage du processeur est assez simple : les OS s'exécutent à tour de rôle sur le processeur, chacun pendant un temps défini, fixe. Une fois leur temps d'exécution passé, ils laissent la main à l'OS suivant. C'est l’hyperviseur qui s'occupe de tout cela, grâce à une interruption commandée à un ''timer''. Ce système de partage est une forme de '''multiplexage'''.
La gestion des entrées-sorties demande d'utiliser des techniques d''''émulation''', plus complexes à expliquer. Un hyperviseur peut parfaitement simuler du matériel qui n'est pas installé sur l'ordinateur. Par exemple, il peut faire croire à un OS qu'une carte réseau obsolète, datant d'il y a 20 ans, est installée sur l'ordinateur, alors que ce n'est pas le cas. Les commandes envoyées par l'OS à cette carte réseau fictive sont en réalité traitées par une vraie carte réseau par l’hyperviseur. Pour cela, l’hyperviseur intercepte les commandes envoyées aux entrées-sorties, et les traduit en commandes compatibles avec les entrées-sorties réellement installées sur l'ordinateur.
===Les machines virtuelles===
L'exemple avec la carte réseau est un cas particulier, l'hyperviseur faisant beaucoup de choses dans le genre. L'hyperviseur peut faire croire à l'ordinateur qu'il a plus ou moins de RAM que ce qui est réellement installé, par exemple. L'hyperviseur implémente ce qu'on appelle des '''machines virtuelles'''. Il s'agit d'une sorte de faux matériel, simulé par un logiciel. Un logiciel qui s’exécute dans une machine virtuelle aura l'impression de s’exécuter sur un matériel et/ou un O.S différent du matériel sur lequel il est en train de s’exécuter.
: Dans ce qui suit, nous parlerons de V.M (virtual machine), pour parler des machines virtuelles.
[[File:VM-monitor-french.png|centre|vignette|upright=2|Machines virtuelles avec la virtualisation.]]
Avec la virtualisation, plusieurs machines virtuelles sont gérées par l'hyperviseur, chacune étant réservée à un système d'exploitation. D'ailleurs, hyperviseurs sont parfois appelés des ''Virtual Machine Manager''. Nous utiliserons d'ailleurs l'abréviation VMM dans les schémas qui suivent. Il existe deux types d'hyperviseurs, qui sont nommés type 1 et type 2. Le premier type s'exécute directement sur le matériel, alors que le second est un logiciel qui s’exécute sur un OS normal. Pour ce qui nous concerne, la distinction n'est pas très importante.
[[File:Ansatz der Systemvirtualisierung zur Schaffung virtueller Betriebsumgebungen.png|centre|vignette|upright=2|Comparaison des différentes tecxhniques de virtualisation : sans virtualisation, virtualisation de type 1 et de type 2.]]
La virtualisation est une des utilisations possibles, mais il y en a d'autres. La plus intéressante est celle des émulateurs. Ces derniers sont des logiciels qui permettent de simuler le fonctionnement d'anciens ordinateurs ou consoles de jeux. L'émulateur crée une machine virtuelle qui est réservée à un programme, à savoir le jeu à émuler.
Il y a une différence de taille entre un émulateur et un hyperviseur. L'émulation émule une machine virtuelle totalement différente, alors que la virtualisation doit émuler les entrées-sorties mais pas le processeur. Avec un hyperviseur, le système d'exploitation s'exécute sur le processeur lui-même. Le code de l'OS est compatible avec le processeur de la machine, dans le sens où il est compilé pour le jeu d'instruction du processeur de la machine réelle. Les instructions de l'OS s'exécutent directement. Par contre, un émulateur exécute un jeu qui est programmé pour une machine dont le processeur est totalement différent. Le jeu d'instruction de la machine virtuelle et celui du vrai processeur n'est pas le même. L'émulation implique donc de traduire les instructions à exécuter dans la V.M par des instructions exécutables par le processeur. Ce n'est pas le cas avec la virtualisation, le jeu d'instruction étant le même.
[[File:Diagramme ArchiEmulateurNonNatif.png|centre|vignette|upright=2|Emulateur]]
===La méthode ''trap and emulate'' basique===
Pour être considéré comme un logiciel de virtualisation, un logiciel doit remplir trois critères :
* L'équivalence : l'O.S virtualisé et les applications qui s’exécutent doivent se comporter comme s'ils étaient exécutés sur le matériel de base, sans virtualisation.
* Le contrôle des ressources : tout accès au matériel par l'O.S virtualisé doit être intercepté par la machine virtuelle et intégralement pris en charge par l'hyperviseur.
* L'efficacité : La grande partie des instructions machines doit s’exécuter directement sur le processeur, afin de garder des performances correctes. Ce critère n'est pas respecté par les émulateurs matériels, qui doivent simuler le jeu d'instruction du processeur émulé.
Remplir ces trois critères est possible sous certaines conditions, établies par les théorèmes de Popek et Goldberg. Ces théorèmes se basent sur des hypothèses précises. De fait, la portée de ces théorèmes est limitée, notamment pour le critère de performance. Ils partent notamment du principe que l'ordinateur utilise la segmentation pour la mémoire virtuelle, et non la pagination. Il part aussi du principe que les interruptions ont un cout assez faible, qu'elles sont assez rares. Mais laissons ces détails de côté, le cœur de ces théorèmes repose sur une hypothèse simple : la présence de différents types d'instructions machines.
Pour rappel, il faut distinguer les instructions privilégiées de celles qui ne le sont pas. Les instructions privilégiées ne peuvent s'exécuter que en mode noyau, les programmes en mode utilisateur ne peuvent pas les exécuter. Parmi les instructions privilégiées on peut distinguer un sous-groupe appelé les '''instructions systèmes'''. Le premier type regroupe les '''instructions d'accès aux entrées-sorties''', aussi appelées instructions sensibles à la configuration. Le second type est celui des '''instructions de configuration du processeur''', qui agissent sur les registres de contrôle du processeur, aussi appelées instructions sensibles au comportement.
La théorie de Popek et Goldberg dit qu'il est possible de virtualiser un O.S à une condition : que les instructions systèmes soient toutes des instructions privilégiées, c’est-à-dire exécutables seulement en mode noyau. Virtualiser un O.S demande simplement de le démarrer en mode utilisateur. Quand l'O.S fait un accès au matériel, il le fait via une instruction privilégiée. Vu que l'OS est en mode utilisateur, cela déclenche une exception matérielle, qui émule l'instruction privilégiée.
L'hyperviseur n'est ni plus ni moins qu'un ensemble de routines d'interruptions, chaque routine simulant le fonctionnement du matériel émulé. Par exemple, un accès au disque dur sera émulé par une routine d'interruption, qui utilisera les appels systèmes fournit par l'OS pour accéder au disque dur réellement présent dans l'ordinateur. Cette méthode est souvent appelée la méthode ''trap and emulate''.
[[File:Virtualisation avec la méthode trap-and-emulate.png|centre|vignette|upright=2.0|Virtualisation avec la méthode trap-and-emulate]]
La méthode ''trap and emulate'' ne fonctionne que si certaines contraintes sont respectées. Un premier problème est que beaucoup de jeux d'instructions anciens ne respectent pas la règle "les instructions systèmes sont toutes privilégiées". Par exemple, ce n'est pas le cas sur les processeurs x86 32 bits. Sur ces CPU, les instructions qui manipulent les drapeaux d'interruption ne sont pas toutes des instructions privilégiées, idem pour les instructions qui manipulent les registres de segmentation, celles liées aux ''call gates'', etc. A cause de cela, il est impossible d'utiliser la méthode du ''trap and emulate''. La seule solution qui ne requiert pas de techniques matérielles est de traduire à la volée les instructions systèmes problématiques en appels systèmes équivalents, grâce à des techniques de '''réécriture de code'''.
Enfin, certaines instructions dites '''sensibles au contexte''' ont un comportement différent entre le mode noyau et le mode utilisateur. En présence de telles instructions, la méthode ''trap and emulate'' ne fonctionne tout simplement pas. Grâce à ces instructions, le système d’exploitation ou un programme applicatif peut savoir s'il s'exécute en mode utilisateur ou noyau, ou hyperviseur, ou autre.
La virtualisation impose l'usage de la mémoire virtuelle, sans quoi plusieurs OS ne peuvent pas se partager la même mémoire physique. De plus, il ne faut pas que la mémoire physique, non-virtuelle, puisse être adressée directement. Et cette contrainte est violée, par exemple sur les architectures MIPS qui exposent des portions de la mémoire physique dans certaines zones fixées à l'avance de la mémoire virtuelle. L'OS est compilé pour utiliser ces zones de mémoire pour accéder aux entrées-sorties mappées en mémoire, entre autres. En théorie, on peut passer outre le problème en marquant ces zones de mémoire comme inaccessibles, toute lecture/écriture à ces adresses déclenche alors une exception traitée par l'hyperviseur. Mais le cout en performance est alors trop important.
Quelques hyperviseurs ont été conçus pour les architectures MIPS, dont le projet de recherche DISCO, mais ils ne fonctionnaient qu'avec des systèmes d'exploitation recompilés, de manière à passer outre ce problème. Les OS étaient recompilés afin de ne pas utiliser les zones mémoire problématiques. De plus, les OS étaient modifiés pour améliorer les performances en virtualisation. Les OS disposaient notamment d'appels systèmes spéciaux, appelés des ''hypercalls'', qui exécutaient des routines de l'hyperviseur directement. Les appels systèmes faisant appel à des instructions systèmes étaient ainsi remplacé par des appels système appelant directement l'hyperviseur. Le fait de modifier l'OS pour qu'il communique avec un hyperviseur, dont il a connaissance de l'existence, s'appelle la '''para-virtualisation'''.
[[File:Virtualization - Para vs Full.png|centre|vignette|upright=2.5|Virtualization - Para vs Full]]
==La virtualisation du CPU : le mode hyperviseur==
Sur certains CPU modernes, il existe un niveau de privilège appelé le '''mode hyperviseur''' qui est utilisé pour les techniques de virtualisation. Le mode hyperviseur est réservé à l’hyperviseur et il a des droits d'accès spécifiques. Il n'est cependant pas toujours activé. Par exemple, si aucun hyperviseur n'est installé sur la machine, le processeur dispose seulement d'un mode noyau et d'un mode utilisateur normaux, le mode noyau n'ayant alors aucune limitation précise. Mais quand le mode hyperviseur est activé, une partie des manipulations est bloquée en mode noyau et n'est possible qu'en mode hyperviseur.
Le fonctionnement se base sur la différence entre instruction privilégiée et instruction système. Les instructions privilégiées peuvent s'exécuter en mode noyau, alors que les instructions systèmes ne peuvent s'exécuter qu'en mode hyperviseur. L'idée est que quand le noyau d'un OS exécute une instruction système, une exception matérielle est levée. L'exception bascule en mode hyperviseur et laisse la main à une routine de l'hyperviseur. L'hyperviseur fait alors des manipulations précise pour que l'instruction système donne le même résultat que si elle avait été exécutée par l'ordinateur simulé par la machine virtuelle.
[[File:Virtualisation avec un mode hyperviseur.png|centre|vignette|upright=2|Virtualisation avec un mode hyperviseur.]]
Il est ainsi possible d'émuler des entrées-sorties avec un cout en performance assez léger. Précisément, ce mode hyperviseur améliore les performances de la méthode du ''trap-and-emulate''. La méthode ''trap-and-emulate'' basique exécute une exception matérielle pour toute instruction privilégiées, qu'elle soit une instruction système ou non. Mais avec le mode hyperviseur, seules les instructions systèmes déclenchent une exception, pas les instructions privilégiées non-système. Les performances sont donc un peu meilleures, pour un résultat identique. Après tout, les entrées-sorties et la configuration du processeur suffisent à émuler une machine virtuelle, les autres instructions noyau ne le sont pas.
Sur les processeurs ARM, il est possible de configurer quelles instructions sont détournées vers le mode hyperviseur et celles qui restent en mode noyau. En clair, on peut configurer quelles sont les instructions systèmes et celles qui sont simplement privilégiées. Et il en est de même pour les interruptions : on peut configurer si elles exécutent la routine de l'OS normal en mode noyau, ou si elles déclenchent une exception matérielle qui redirige vers une routine de l’hyperviseur. En l'absence d'hyperviseur, toutes les interruptions redirigent vers la routine de l'OS normale, vers le mode noyau.
Les processeurs ARM de version v8 et plus incorporent un mode hyperviseur, mais pas les processeurs x86. A la place, ils incorporent des technologies alternatives nommées Intel Vtx ou l'AMD-V. Elles fonctionnent sur un principe totalement différent.
==La virtualisation de la mémoire RAM : l'extension des tables des pages emboitées==
Avec la virtualisation, les différentes machines virtuelles, les différents OS doivent se partager la mémoire physique. Et ce partage doit isoler les différents OS les uns des autres. Il est possible de comparer cette isolation avec l'isolation des processus : chaque OS doit avoir sa propre mémoire physique rien qu'à lui. L'idée est d'utiliser la mémoire virtuelle pour cela.
L'espace d'adressage physique vu par chaque OS est en réalité virtualisé, c’est-à-dire que c'est un espace d'adressage fictif, qui ne correspond pas à la mémoire virtuelle. Les adresses physiques vues par l'OS sont en réalité des adresses intermédiaires entre les adresses physiques liées à la RAM, et les adresses virtuelles vues par les processus. Pour les distinguer, nous parlerons d'adresses physiques de l'hôte pour parler des adresses de la RAM, et des adresses physiques invitées pour parler des adresses manipulées par les OS virtualisés. La raison est que les OS sont appelés des OS invités, alors que l'hyperviseur est parfois appelé l'OS hôte.
Sans accélération matérielle, la traduction des adresses physiques invitées en adresses hôte est réalisée par une seconde table des pages, appelée la ''shadow page table'', ce qui donnerait '''table des pages cachée''' en français. La table des pages cachée est prise en charge par l'hyperviseur. Toute modification de la table des pages cachée est réalisée par l'hyperviseur, les OS ne savent même pas qu'elle existe.
[[File:Shadowpagetables.png|centre|vignette|upright=2|Table des pages cachée.]]
Une autre solution demande un support matériel des tables des pages emboitées, à savoir qu'il y a un arbre de table des pages, chaque consultation de la première table des pages renvoie vers une seconde, qui renvoie vers une troisième, et ainsi de suite jusqu'à tomber sur la table des pages finale qui renvoie l'adresse physique réelle.
L'idée est l'utiliser une seule table des pages, mais d'ajouter un ou deux niveaux supplémentaires. Pour l'exemple, prenons le cas des processeurs x86. Sans virtualisation, l'OS utilise une table des pages de 4 niveaux. Avec, la table des pages a un niveau en plus, qui sont ajoutés à la fin de la dernière table des pages normale. Les niveaux ajoutés s'occupent de la traduction des adresses physiques invitées en adresses physiques hôte. Il faut que le processeur soit modifié de manière à parcourir automatiquement les niveaux ajoutés, ce qui demande quelques modifications de la TLB et du ''page table walker''.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les sections critiques et le modèle mémoire
| prevText=Les sections critiques et le modèle mémoire
| next=Le matériel réseau
| nextText=Le matériel réseau
}}
</noinclude>
nth5ge5qw5nczbv507vkcjdc1fgtm8y
744324
744323
2025-06-08T16:25:43Z
Mewtow
31375
/* Les machines virtuelles */
744324
wikitext
text/x-wiki
La virtualisation est l'ensemble des techniques qui permettent de faire tourner plusieurs systèmes d'exploitation en même temps. Le terme est polysémique, mais c'est la définition que nous allons utiliser pour ce qui nous intéresse. La virtualisation demande d'utiliser un logiciel dit '''hyperviseur''', qui permet de faire tourner plusieurs OS en même temps. Les hyperviseurs sont en quelque sorte situés sous le système d'exploitation et on peut les voir comme une sorte de sous-système d'exploitation, de système d'exploitation pour les systèmes d'exploitation.
[[File:Diagramme ArchiHyperviseur.png|centre|vignette|upright=2|Différence entre système d'exploitation et hyperviseur.]]
Les processeurs modernes intègrent des techniques pour accélérer matériellement la virtualisation. Les techniques en question sont assez variées, allant d'un niveau de privilège en plus des modes noyau/utilisateur à des techniques de duplication de ces mêmes modes. Les techniques de virtualisation demandent de détourner des interruptions, ce qui fait que ces techniques d'accélération demandent de modifier la manière dont le processeur gère les interruptions. Mais pour comprendre tout cela, il va falloir faire quelques explications sur la virtualisation elle-même.
==La virtualisation : généralités==
Pour faire tourner plusieurs OS en même temps, l'hyperviseur recourt à de nombreux stratagèmes. Il doit partager le processeur, la RAM et les entrées-sorties entre plusieurs OS. Les trois demandent des techniques différentes. Le partage de la RAM demande concrètement des modifications au niveau de la mémoire virtuelle. Le partage du processeur est assez simple : les OS s'exécutent à tour de rôle sur le processeur, chacun pendant un temps défini, fixe. Une fois leur temps d'exécution passé, ils laissent la main à l'OS suivant. C'est l’hyperviseur qui s'occupe de tout cela, grâce à une interruption commandée à un ''timer''. Ce système de partage est une forme de '''multiplexage'''.
La gestion des entrées-sorties demande d'utiliser des techniques d''''émulation''', plus complexes à expliquer. Un hyperviseur peut parfaitement simuler du matériel qui n'est pas installé sur l'ordinateur. Par exemple, il peut faire croire à un OS qu'une carte réseau obsolète, datant d'il y a 20 ans, est installée sur l'ordinateur, alors que ce n'est pas le cas. Les commandes envoyées par l'OS à cette carte réseau fictive sont en réalité traitées par une vraie carte réseau par l’hyperviseur. Pour cela, l’hyperviseur intercepte les commandes envoyées aux entrées-sorties, et les traduit en commandes compatibles avec les entrées-sorties réellement installées sur l'ordinateur.
===Les machines virtuelles===
L'exemple avec la carte réseau est un cas particulier, l'hyperviseur faisant beaucoup de choses dans le genre. L'hyperviseur peut faire croire à l'ordinateur qu'il a plus ou moins de RAM que ce qui est réellement installé, par exemple. L'hyperviseur implémente ce qu'on appelle des '''machines virtuelles'''. Il s'agit d'une sorte de faux matériel, simulé par un logiciel. Un logiciel qui s’exécute dans une machine virtuelle aura l'impression de s’exécuter sur un matériel et/ou un O.S différent du matériel sur lequel il est en train de s’exécuter.
: Dans ce qui suit, nous parlerons de V.M (virtual machine), pour parler des machines virtuelles.
[[File:VM-monitor-french.png|centre|vignette|upright=2|Machines virtuelles avec la virtualisation.]]
Avec la virtualisation, plusieurs machines virtuelles sont gérées par l'hyperviseur, chacune étant réservée à un système d'exploitation. D'ailleurs, hyperviseurs sont parfois appelés des ''Virtual Machine Manager''. Nous utiliserons d'ailleurs l'abréviation VMM dans les schémas qui suivent. Il existe deux types d'hyperviseurs, qui sont nommés type 1 et type 2. Le premier type s'exécute directement sur le matériel, alors que le second est un logiciel qui s’exécute sur un OS normal. Pour ce qui nous concerne, la distinction n'est pas très importante.
[[File:Ansatz der Systemvirtualisierung zur Schaffung virtueller Betriebsumgebungen.png|centre|vignette|upright=2.5|Comparaison des différentes techniques de virtualisation : sans virtualisation à gauche, virtualisation de type 1 au milieu, de type 2 à droite.]]
La virtualisation est une des utilisations possibles, mais il y en a d'autres. La plus intéressante est celle des émulateurs. Ces derniers sont des logiciels qui permettent de simuler le fonctionnement d'anciens ordinateurs ou consoles de jeux. L'émulateur crée une machine virtuelle qui est réservée à un programme, à savoir le jeu à émuler.
Il y a une différence de taille entre un émulateur et un hyperviseur. L'émulation émule une machine virtuelle totalement différente, alors que la virtualisation doit émuler les entrées-sorties mais pas le processeur. Avec un hyperviseur, le système d'exploitation s'exécute sur le processeur lui-même. Le code de l'OS est compatible avec le processeur de la machine, dans le sens où il est compilé pour le jeu d'instruction du processeur de la machine réelle. Les instructions de l'OS s'exécutent directement. Par contre, un émulateur exécute un jeu qui est programmé pour une machine dont le processeur est totalement différent. Le jeu d'instruction de la machine virtuelle et celui du vrai processeur n'est pas le même. L'émulation implique donc de traduire les instructions à exécuter dans la V.M par des instructions exécutables par le processeur. Ce n'est pas le cas avec la virtualisation, le jeu d'instruction étant le même.
[[File:Diagramme ArchiEmulateurNonNatif.png|centre|vignette|upright=2|Emulateur]]
===La méthode ''trap and emulate'' basique===
Pour être considéré comme un logiciel de virtualisation, un logiciel doit remplir trois critères :
* L'équivalence : l'O.S virtualisé et les applications qui s’exécutent doivent se comporter comme s'ils étaient exécutés sur le matériel de base, sans virtualisation.
* Le contrôle des ressources : tout accès au matériel par l'O.S virtualisé doit être intercepté par la machine virtuelle et intégralement pris en charge par l'hyperviseur.
* L'efficacité : La grande partie des instructions machines doit s’exécuter directement sur le processeur, afin de garder des performances correctes. Ce critère n'est pas respecté par les émulateurs matériels, qui doivent simuler le jeu d'instruction du processeur émulé.
Remplir ces trois critères est possible sous certaines conditions, établies par les théorèmes de Popek et Goldberg. Ces théorèmes se basent sur des hypothèses précises. De fait, la portée de ces théorèmes est limitée, notamment pour le critère de performance. Ils partent notamment du principe que l'ordinateur utilise la segmentation pour la mémoire virtuelle, et non la pagination. Il part aussi du principe que les interruptions ont un cout assez faible, qu'elles sont assez rares. Mais laissons ces détails de côté, le cœur de ces théorèmes repose sur une hypothèse simple : la présence de différents types d'instructions machines.
Pour rappel, il faut distinguer les instructions privilégiées de celles qui ne le sont pas. Les instructions privilégiées ne peuvent s'exécuter que en mode noyau, les programmes en mode utilisateur ne peuvent pas les exécuter. Parmi les instructions privilégiées on peut distinguer un sous-groupe appelé les '''instructions systèmes'''. Le premier type regroupe les '''instructions d'accès aux entrées-sorties''', aussi appelées instructions sensibles à la configuration. Le second type est celui des '''instructions de configuration du processeur''', qui agissent sur les registres de contrôle du processeur, aussi appelées instructions sensibles au comportement.
La théorie de Popek et Goldberg dit qu'il est possible de virtualiser un O.S à une condition : que les instructions systèmes soient toutes des instructions privilégiées, c’est-à-dire exécutables seulement en mode noyau. Virtualiser un O.S demande simplement de le démarrer en mode utilisateur. Quand l'O.S fait un accès au matériel, il le fait via une instruction privilégiée. Vu que l'OS est en mode utilisateur, cela déclenche une exception matérielle, qui émule l'instruction privilégiée.
L'hyperviseur n'est ni plus ni moins qu'un ensemble de routines d'interruptions, chaque routine simulant le fonctionnement du matériel émulé. Par exemple, un accès au disque dur sera émulé par une routine d'interruption, qui utilisera les appels systèmes fournit par l'OS pour accéder au disque dur réellement présent dans l'ordinateur. Cette méthode est souvent appelée la méthode ''trap and emulate''.
[[File:Virtualisation avec la méthode trap-and-emulate.png|centre|vignette|upright=2.0|Virtualisation avec la méthode trap-and-emulate]]
La méthode ''trap and emulate'' ne fonctionne que si certaines contraintes sont respectées. Un premier problème est que beaucoup de jeux d'instructions anciens ne respectent pas la règle "les instructions systèmes sont toutes privilégiées". Par exemple, ce n'est pas le cas sur les processeurs x86 32 bits. Sur ces CPU, les instructions qui manipulent les drapeaux d'interruption ne sont pas toutes des instructions privilégiées, idem pour les instructions qui manipulent les registres de segmentation, celles liées aux ''call gates'', etc. A cause de cela, il est impossible d'utiliser la méthode du ''trap and emulate''. La seule solution qui ne requiert pas de techniques matérielles est de traduire à la volée les instructions systèmes problématiques en appels systèmes équivalents, grâce à des techniques de '''réécriture de code'''.
Enfin, certaines instructions dites '''sensibles au contexte''' ont un comportement différent entre le mode noyau et le mode utilisateur. En présence de telles instructions, la méthode ''trap and emulate'' ne fonctionne tout simplement pas. Grâce à ces instructions, le système d’exploitation ou un programme applicatif peut savoir s'il s'exécute en mode utilisateur ou noyau, ou hyperviseur, ou autre.
La virtualisation impose l'usage de la mémoire virtuelle, sans quoi plusieurs OS ne peuvent pas se partager la même mémoire physique. De plus, il ne faut pas que la mémoire physique, non-virtuelle, puisse être adressée directement. Et cette contrainte est violée, par exemple sur les architectures MIPS qui exposent des portions de la mémoire physique dans certaines zones fixées à l'avance de la mémoire virtuelle. L'OS est compilé pour utiliser ces zones de mémoire pour accéder aux entrées-sorties mappées en mémoire, entre autres. En théorie, on peut passer outre le problème en marquant ces zones de mémoire comme inaccessibles, toute lecture/écriture à ces adresses déclenche alors une exception traitée par l'hyperviseur. Mais le cout en performance est alors trop important.
Quelques hyperviseurs ont été conçus pour les architectures MIPS, dont le projet de recherche DISCO, mais ils ne fonctionnaient qu'avec des systèmes d'exploitation recompilés, de manière à passer outre ce problème. Les OS étaient recompilés afin de ne pas utiliser les zones mémoire problématiques. De plus, les OS étaient modifiés pour améliorer les performances en virtualisation. Les OS disposaient notamment d'appels systèmes spéciaux, appelés des ''hypercalls'', qui exécutaient des routines de l'hyperviseur directement. Les appels systèmes faisant appel à des instructions systèmes étaient ainsi remplacé par des appels système appelant directement l'hyperviseur. Le fait de modifier l'OS pour qu'il communique avec un hyperviseur, dont il a connaissance de l'existence, s'appelle la '''para-virtualisation'''.
[[File:Virtualization - Para vs Full.png|centre|vignette|upright=2.5|Virtualization - Para vs Full]]
==La virtualisation du CPU : le mode hyperviseur==
Sur certains CPU modernes, il existe un niveau de privilège appelé le '''mode hyperviseur''' qui est utilisé pour les techniques de virtualisation. Le mode hyperviseur est réservé à l’hyperviseur et il a des droits d'accès spécifiques. Il n'est cependant pas toujours activé. Par exemple, si aucun hyperviseur n'est installé sur la machine, le processeur dispose seulement d'un mode noyau et d'un mode utilisateur normaux, le mode noyau n'ayant alors aucune limitation précise. Mais quand le mode hyperviseur est activé, une partie des manipulations est bloquée en mode noyau et n'est possible qu'en mode hyperviseur.
Le fonctionnement se base sur la différence entre instruction privilégiée et instruction système. Les instructions privilégiées peuvent s'exécuter en mode noyau, alors que les instructions systèmes ne peuvent s'exécuter qu'en mode hyperviseur. L'idée est que quand le noyau d'un OS exécute une instruction système, une exception matérielle est levée. L'exception bascule en mode hyperviseur et laisse la main à une routine de l'hyperviseur. L'hyperviseur fait alors des manipulations précise pour que l'instruction système donne le même résultat que si elle avait été exécutée par l'ordinateur simulé par la machine virtuelle.
[[File:Virtualisation avec un mode hyperviseur.png|centre|vignette|upright=2|Virtualisation avec un mode hyperviseur.]]
Il est ainsi possible d'émuler des entrées-sorties avec un cout en performance assez léger. Précisément, ce mode hyperviseur améliore les performances de la méthode du ''trap-and-emulate''. La méthode ''trap-and-emulate'' basique exécute une exception matérielle pour toute instruction privilégiées, qu'elle soit une instruction système ou non. Mais avec le mode hyperviseur, seules les instructions systèmes déclenchent une exception, pas les instructions privilégiées non-système. Les performances sont donc un peu meilleures, pour un résultat identique. Après tout, les entrées-sorties et la configuration du processeur suffisent à émuler une machine virtuelle, les autres instructions noyau ne le sont pas.
Sur les processeurs ARM, il est possible de configurer quelles instructions sont détournées vers le mode hyperviseur et celles qui restent en mode noyau. En clair, on peut configurer quelles sont les instructions systèmes et celles qui sont simplement privilégiées. Et il en est de même pour les interruptions : on peut configurer si elles exécutent la routine de l'OS normal en mode noyau, ou si elles déclenchent une exception matérielle qui redirige vers une routine de l’hyperviseur. En l'absence d'hyperviseur, toutes les interruptions redirigent vers la routine de l'OS normale, vers le mode noyau.
Les processeurs ARM de version v8 et plus incorporent un mode hyperviseur, mais pas les processeurs x86. A la place, ils incorporent des technologies alternatives nommées Intel Vtx ou l'AMD-V. Elles fonctionnent sur un principe totalement différent.
==La virtualisation de la mémoire RAM : l'extension des tables des pages emboitées==
Avec la virtualisation, les différentes machines virtuelles, les différents OS doivent se partager la mémoire physique. Et ce partage doit isoler les différents OS les uns des autres. Il est possible de comparer cette isolation avec l'isolation des processus : chaque OS doit avoir sa propre mémoire physique rien qu'à lui. L'idée est d'utiliser la mémoire virtuelle pour cela.
L'espace d'adressage physique vu par chaque OS est en réalité virtualisé, c’est-à-dire que c'est un espace d'adressage fictif, qui ne correspond pas à la mémoire virtuelle. Les adresses physiques vues par l'OS sont en réalité des adresses intermédiaires entre les adresses physiques liées à la RAM, et les adresses virtuelles vues par les processus. Pour les distinguer, nous parlerons d'adresses physiques de l'hôte pour parler des adresses de la RAM, et des adresses physiques invitées pour parler des adresses manipulées par les OS virtualisés. La raison est que les OS sont appelés des OS invités, alors que l'hyperviseur est parfois appelé l'OS hôte.
Sans accélération matérielle, la traduction des adresses physiques invitées en adresses hôte est réalisée par une seconde table des pages, appelée la ''shadow page table'', ce qui donnerait '''table des pages cachée''' en français. La table des pages cachée est prise en charge par l'hyperviseur. Toute modification de la table des pages cachée est réalisée par l'hyperviseur, les OS ne savent même pas qu'elle existe.
[[File:Shadowpagetables.png|centre|vignette|upright=2|Table des pages cachée.]]
Une autre solution demande un support matériel des tables des pages emboitées, à savoir qu'il y a un arbre de table des pages, chaque consultation de la première table des pages renvoie vers une seconde, qui renvoie vers une troisième, et ainsi de suite jusqu'à tomber sur la table des pages finale qui renvoie l'adresse physique réelle.
L'idée est l'utiliser une seule table des pages, mais d'ajouter un ou deux niveaux supplémentaires. Pour l'exemple, prenons le cas des processeurs x86. Sans virtualisation, l'OS utilise une table des pages de 4 niveaux. Avec, la table des pages a un niveau en plus, qui sont ajoutés à la fin de la dernière table des pages normale. Les niveaux ajoutés s'occupent de la traduction des adresses physiques invitées en adresses physiques hôte. Il faut que le processeur soit modifié de manière à parcourir automatiquement les niveaux ajoutés, ce qui demande quelques modifications de la TLB et du ''page table walker''.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les sections critiques et le modèle mémoire
| prevText=Les sections critiques et le modèle mémoire
| next=Le matériel réseau
| nextText=Le matériel réseau
}}
</noinclude>
hqmtanv1gkdrgtjrpe0as9qv8l25zwy
744325
744324
2025-06-08T16:26:51Z
Mewtow
31375
/* La virtualisation du CPU : le mode hyperviseur */
744325
wikitext
text/x-wiki
La virtualisation est l'ensemble des techniques qui permettent de faire tourner plusieurs systèmes d'exploitation en même temps. Le terme est polysémique, mais c'est la définition que nous allons utiliser pour ce qui nous intéresse. La virtualisation demande d'utiliser un logiciel dit '''hyperviseur''', qui permet de faire tourner plusieurs OS en même temps. Les hyperviseurs sont en quelque sorte situés sous le système d'exploitation et on peut les voir comme une sorte de sous-système d'exploitation, de système d'exploitation pour les systèmes d'exploitation.
[[File:Diagramme ArchiHyperviseur.png|centre|vignette|upright=2|Différence entre système d'exploitation et hyperviseur.]]
Les processeurs modernes intègrent des techniques pour accélérer matériellement la virtualisation. Les techniques en question sont assez variées, allant d'un niveau de privilège en plus des modes noyau/utilisateur à des techniques de duplication de ces mêmes modes. Les techniques de virtualisation demandent de détourner des interruptions, ce qui fait que ces techniques d'accélération demandent de modifier la manière dont le processeur gère les interruptions. Mais pour comprendre tout cela, il va falloir faire quelques explications sur la virtualisation elle-même.
==La virtualisation : généralités==
Pour faire tourner plusieurs OS en même temps, l'hyperviseur recourt à de nombreux stratagèmes. Il doit partager le processeur, la RAM et les entrées-sorties entre plusieurs OS. Les trois demandent des techniques différentes. Le partage de la RAM demande concrètement des modifications au niveau de la mémoire virtuelle. Le partage du processeur est assez simple : les OS s'exécutent à tour de rôle sur le processeur, chacun pendant un temps défini, fixe. Une fois leur temps d'exécution passé, ils laissent la main à l'OS suivant. C'est l’hyperviseur qui s'occupe de tout cela, grâce à une interruption commandée à un ''timer''. Ce système de partage est une forme de '''multiplexage'''.
La gestion des entrées-sorties demande d'utiliser des techniques d''''émulation''', plus complexes à expliquer. Un hyperviseur peut parfaitement simuler du matériel qui n'est pas installé sur l'ordinateur. Par exemple, il peut faire croire à un OS qu'une carte réseau obsolète, datant d'il y a 20 ans, est installée sur l'ordinateur, alors que ce n'est pas le cas. Les commandes envoyées par l'OS à cette carte réseau fictive sont en réalité traitées par une vraie carte réseau par l’hyperviseur. Pour cela, l’hyperviseur intercepte les commandes envoyées aux entrées-sorties, et les traduit en commandes compatibles avec les entrées-sorties réellement installées sur l'ordinateur.
===Les machines virtuelles===
L'exemple avec la carte réseau est un cas particulier, l'hyperviseur faisant beaucoup de choses dans le genre. L'hyperviseur peut faire croire à l'ordinateur qu'il a plus ou moins de RAM que ce qui est réellement installé, par exemple. L'hyperviseur implémente ce qu'on appelle des '''machines virtuelles'''. Il s'agit d'une sorte de faux matériel, simulé par un logiciel. Un logiciel qui s’exécute dans une machine virtuelle aura l'impression de s’exécuter sur un matériel et/ou un O.S différent du matériel sur lequel il est en train de s’exécuter.
: Dans ce qui suit, nous parlerons de V.M (virtual machine), pour parler des machines virtuelles.
[[File:VM-monitor-french.png|centre|vignette|upright=2|Machines virtuelles avec la virtualisation.]]
Avec la virtualisation, plusieurs machines virtuelles sont gérées par l'hyperviseur, chacune étant réservée à un système d'exploitation. D'ailleurs, hyperviseurs sont parfois appelés des ''Virtual Machine Manager''. Nous utiliserons d'ailleurs l'abréviation VMM dans les schémas qui suivent. Il existe deux types d'hyperviseurs, qui sont nommés type 1 et type 2. Le premier type s'exécute directement sur le matériel, alors que le second est un logiciel qui s’exécute sur un OS normal. Pour ce qui nous concerne, la distinction n'est pas très importante.
[[File:Ansatz der Systemvirtualisierung zur Schaffung virtueller Betriebsumgebungen.png|centre|vignette|upright=2.5|Comparaison des différentes techniques de virtualisation : sans virtualisation à gauche, virtualisation de type 1 au milieu, de type 2 à droite.]]
La virtualisation est une des utilisations possibles, mais il y en a d'autres. La plus intéressante est celle des émulateurs. Ces derniers sont des logiciels qui permettent de simuler le fonctionnement d'anciens ordinateurs ou consoles de jeux. L'émulateur crée une machine virtuelle qui est réservée à un programme, à savoir le jeu à émuler.
Il y a une différence de taille entre un émulateur et un hyperviseur. L'émulation émule une machine virtuelle totalement différente, alors que la virtualisation doit émuler les entrées-sorties mais pas le processeur. Avec un hyperviseur, le système d'exploitation s'exécute sur le processeur lui-même. Le code de l'OS est compatible avec le processeur de la machine, dans le sens où il est compilé pour le jeu d'instruction du processeur de la machine réelle. Les instructions de l'OS s'exécutent directement. Par contre, un émulateur exécute un jeu qui est programmé pour une machine dont le processeur est totalement différent. Le jeu d'instruction de la machine virtuelle et celui du vrai processeur n'est pas le même. L'émulation implique donc de traduire les instructions à exécuter dans la V.M par des instructions exécutables par le processeur. Ce n'est pas le cas avec la virtualisation, le jeu d'instruction étant le même.
[[File:Diagramme ArchiEmulateurNonNatif.png|centre|vignette|upright=2|Emulateur]]
===La méthode ''trap and emulate'' basique===
Pour être considéré comme un logiciel de virtualisation, un logiciel doit remplir trois critères :
* L'équivalence : l'O.S virtualisé et les applications qui s’exécutent doivent se comporter comme s'ils étaient exécutés sur le matériel de base, sans virtualisation.
* Le contrôle des ressources : tout accès au matériel par l'O.S virtualisé doit être intercepté par la machine virtuelle et intégralement pris en charge par l'hyperviseur.
* L'efficacité : La grande partie des instructions machines doit s’exécuter directement sur le processeur, afin de garder des performances correctes. Ce critère n'est pas respecté par les émulateurs matériels, qui doivent simuler le jeu d'instruction du processeur émulé.
Remplir ces trois critères est possible sous certaines conditions, établies par les théorèmes de Popek et Goldberg. Ces théorèmes se basent sur des hypothèses précises. De fait, la portée de ces théorèmes est limitée, notamment pour le critère de performance. Ils partent notamment du principe que l'ordinateur utilise la segmentation pour la mémoire virtuelle, et non la pagination. Il part aussi du principe que les interruptions ont un cout assez faible, qu'elles sont assez rares. Mais laissons ces détails de côté, le cœur de ces théorèmes repose sur une hypothèse simple : la présence de différents types d'instructions machines.
Pour rappel, il faut distinguer les instructions privilégiées de celles qui ne le sont pas. Les instructions privilégiées ne peuvent s'exécuter que en mode noyau, les programmes en mode utilisateur ne peuvent pas les exécuter. Parmi les instructions privilégiées on peut distinguer un sous-groupe appelé les '''instructions systèmes'''. Le premier type regroupe les '''instructions d'accès aux entrées-sorties''', aussi appelées instructions sensibles à la configuration. Le second type est celui des '''instructions de configuration du processeur''', qui agissent sur les registres de contrôle du processeur, aussi appelées instructions sensibles au comportement.
La théorie de Popek et Goldberg dit qu'il est possible de virtualiser un O.S à une condition : que les instructions systèmes soient toutes des instructions privilégiées, c’est-à-dire exécutables seulement en mode noyau. Virtualiser un O.S demande simplement de le démarrer en mode utilisateur. Quand l'O.S fait un accès au matériel, il le fait via une instruction privilégiée. Vu que l'OS est en mode utilisateur, cela déclenche une exception matérielle, qui émule l'instruction privilégiée.
L'hyperviseur n'est ni plus ni moins qu'un ensemble de routines d'interruptions, chaque routine simulant le fonctionnement du matériel émulé. Par exemple, un accès au disque dur sera émulé par une routine d'interruption, qui utilisera les appels systèmes fournit par l'OS pour accéder au disque dur réellement présent dans l'ordinateur. Cette méthode est souvent appelée la méthode ''trap and emulate''.
[[File:Virtualisation avec la méthode trap-and-emulate.png|centre|vignette|upright=2.0|Virtualisation avec la méthode trap-and-emulate]]
La méthode ''trap and emulate'' ne fonctionne que si certaines contraintes sont respectées. Un premier problème est que beaucoup de jeux d'instructions anciens ne respectent pas la règle "les instructions systèmes sont toutes privilégiées". Par exemple, ce n'est pas le cas sur les processeurs x86 32 bits. Sur ces CPU, les instructions qui manipulent les drapeaux d'interruption ne sont pas toutes des instructions privilégiées, idem pour les instructions qui manipulent les registres de segmentation, celles liées aux ''call gates'', etc. A cause de cela, il est impossible d'utiliser la méthode du ''trap and emulate''. La seule solution qui ne requiert pas de techniques matérielles est de traduire à la volée les instructions systèmes problématiques en appels systèmes équivalents, grâce à des techniques de '''réécriture de code'''.
Enfin, certaines instructions dites '''sensibles au contexte''' ont un comportement différent entre le mode noyau et le mode utilisateur. En présence de telles instructions, la méthode ''trap and emulate'' ne fonctionne tout simplement pas. Grâce à ces instructions, le système d’exploitation ou un programme applicatif peut savoir s'il s'exécute en mode utilisateur ou noyau, ou hyperviseur, ou autre.
La virtualisation impose l'usage de la mémoire virtuelle, sans quoi plusieurs OS ne peuvent pas se partager la même mémoire physique. De plus, il ne faut pas que la mémoire physique, non-virtuelle, puisse être adressée directement. Et cette contrainte est violée, par exemple sur les architectures MIPS qui exposent des portions de la mémoire physique dans certaines zones fixées à l'avance de la mémoire virtuelle. L'OS est compilé pour utiliser ces zones de mémoire pour accéder aux entrées-sorties mappées en mémoire, entre autres. En théorie, on peut passer outre le problème en marquant ces zones de mémoire comme inaccessibles, toute lecture/écriture à ces adresses déclenche alors une exception traitée par l'hyperviseur. Mais le cout en performance est alors trop important.
Quelques hyperviseurs ont été conçus pour les architectures MIPS, dont le projet de recherche DISCO, mais ils ne fonctionnaient qu'avec des systèmes d'exploitation recompilés, de manière à passer outre ce problème. Les OS étaient recompilés afin de ne pas utiliser les zones mémoire problématiques. De plus, les OS étaient modifiés pour améliorer les performances en virtualisation. Les OS disposaient notamment d'appels systèmes spéciaux, appelés des ''hypercalls'', qui exécutaient des routines de l'hyperviseur directement. Les appels systèmes faisant appel à des instructions systèmes étaient ainsi remplacé par des appels système appelant directement l'hyperviseur. Le fait de modifier l'OS pour qu'il communique avec un hyperviseur, dont il a connaissance de l'existence, s'appelle la '''para-virtualisation'''.
[[File:Virtualization - Para vs Full.png|centre|vignette|upright=2.5|Virtualization - Para vs Full]]
==La virtualisation du CPU : le mode hyperviseur==
Sur certains CPU modernes, il existe un niveau de privilège appelé le '''mode hyperviseur''' qui est utilisé pour les techniques de virtualisation. Le mode hyperviseur est réservé à l’hyperviseur et il a des droits d'accès spécifiques. Il n'est cependant pas toujours activé. Par exemple, si aucun hyperviseur n'est installé sur la machine, le processeur dispose seulement d'un mode noyau et d'un mode utilisateur normaux, le mode noyau n'ayant alors aucune limitation précise. Mais quand le mode hyperviseur est activé, une partie des manipulations est bloquée en mode noyau et n'est possible qu'en mode hyperviseur.
Le fonctionnement se base sur la différence entre instruction privilégiée et instruction système. Les instructions privilégiées peuvent s'exécuter en mode noyau, alors que les instructions systèmes ne peuvent s'exécuter qu'en mode hyperviseur. L'idée est que quand le noyau d'un OS exécute une instruction système, une exception matérielle est levée. L'exception bascule en mode hyperviseur et laisse la main à une routine de l'hyperviseur. L'hyperviseur fait alors des manipulations précise pour que l'instruction système donne le même résultat que si elle avait été exécutée par l'ordinateur simulé par la machine virtuelle.
[[File:Virtualisation avec un mode hyperviseur.png|centre|vignette|upright=2|Virtualisation avec un mode hyperviseur.]]
Il est ainsi possible d'émuler des entrées-sorties avec un cout en performance assez léger. Précisément, ce mode hyperviseur améliore les performances de la méthode du ''trap-and-emulate''. La méthode ''trap-and-emulate'' basique exécute une exception matérielle pour toute instruction privilégiées, qu'elle soit une instruction système ou non. Mais avec le mode hyperviseur, seules les instructions systèmes déclenchent une exception, pas les instructions privilégiées non-système. Les performances sont donc un peu meilleures, pour un résultat identique. Après tout, les entrées-sorties et la configuration du processeur suffisent à émuler une machine virtuelle, les autres instructions noyau ne le sont pas.
Sur les processeurs ARM, il est possible de configurer quelles instructions sont détournées vers le mode hyperviseur et celles qui restent en mode noyau. En clair, on peut configurer quelles sont les instructions systèmes et celles qui sont simplement privilégiées. Et il en est de même pour les interruptions : on peut configurer si elles exécutent la routine de l'OS normal en mode noyau, ou si elles déclenchent une exception matérielle qui redirige vers une routine de l’hyperviseur. En l'absence d'hyperviseur, toutes les interruptions redirigent vers la routine de l'OS normale, vers le mode noyau.
Il faut noter que le mode hyperviseur n'est compatible qu'avec les hyperviseurs de type 1, à savoir ceux qui s'exécutent directement sur le matériel. Par contre, elle n'est pas compatible avec les hyperviseurs de type 2, qui sont des logiciels qui s'exécutent comme tout autre logiciel, au-dessus d'un système d'exploitation sous-jacent.
Les processeurs ARM de version v8 et plus incorporent un mode hyperviseur, mais pas les processeurs x86. A la place, ils incorporent des technologies alternatives nommées Intel Vtx ou l'AMD-V. Elles fonctionnent sur un principe totalement différent.
==La virtualisation de la mémoire RAM : l'extension des tables des pages emboitées==
Avec la virtualisation, les différentes machines virtuelles, les différents OS doivent se partager la mémoire physique. Et ce partage doit isoler les différents OS les uns des autres. Il est possible de comparer cette isolation avec l'isolation des processus : chaque OS doit avoir sa propre mémoire physique rien qu'à lui. L'idée est d'utiliser la mémoire virtuelle pour cela.
L'espace d'adressage physique vu par chaque OS est en réalité virtualisé, c’est-à-dire que c'est un espace d'adressage fictif, qui ne correspond pas à la mémoire virtuelle. Les adresses physiques vues par l'OS sont en réalité des adresses intermédiaires entre les adresses physiques liées à la RAM, et les adresses virtuelles vues par les processus. Pour les distinguer, nous parlerons d'adresses physiques de l'hôte pour parler des adresses de la RAM, et des adresses physiques invitées pour parler des adresses manipulées par les OS virtualisés. La raison est que les OS sont appelés des OS invités, alors que l'hyperviseur est parfois appelé l'OS hôte.
Sans accélération matérielle, la traduction des adresses physiques invitées en adresses hôte est réalisée par une seconde table des pages, appelée la ''shadow page table'', ce qui donnerait '''table des pages cachée''' en français. La table des pages cachée est prise en charge par l'hyperviseur. Toute modification de la table des pages cachée est réalisée par l'hyperviseur, les OS ne savent même pas qu'elle existe.
[[File:Shadowpagetables.png|centre|vignette|upright=2|Table des pages cachée.]]
Une autre solution demande un support matériel des tables des pages emboitées, à savoir qu'il y a un arbre de table des pages, chaque consultation de la première table des pages renvoie vers une seconde, qui renvoie vers une troisième, et ainsi de suite jusqu'à tomber sur la table des pages finale qui renvoie l'adresse physique réelle.
L'idée est l'utiliser une seule table des pages, mais d'ajouter un ou deux niveaux supplémentaires. Pour l'exemple, prenons le cas des processeurs x86. Sans virtualisation, l'OS utilise une table des pages de 4 niveaux. Avec, la table des pages a un niveau en plus, qui sont ajoutés à la fin de la dernière table des pages normale. Les niveaux ajoutés s'occupent de la traduction des adresses physiques invitées en adresses physiques hôte. Il faut que le processeur soit modifié de manière à parcourir automatiquement les niveaux ajoutés, ce qui demande quelques modifications de la TLB et du ''page table walker''.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les sections critiques et le modèle mémoire
| prevText=Les sections critiques et le modèle mémoire
| next=Le matériel réseau
| nextText=Le matériel réseau
}}
</noinclude>
1y3e0g925om269fl3rv6xgb3fg4zeph
Le papillon bleu
0
82430
744316
2025-06-08T15:20:03Z
2A02:8429:83BC:A601:4069:8FC2:2F5F:8130
Le Papillon Bleu, le lieu événementiel à Lyon qui rend hommage à l'épopée des soyeux du 19ème siècle !
744316
wikitext
text/x-wiki
=== LE PAPILLON BLEU EST UN LIEU ÉVÉNEMENTIEL A LYON, QUI REND HOMMAGE A L’HISTOIRE ! ===
Le Papillon Bleu est né d’un coup de coeur pour l’un des quartiers les plus vivants et fascinants de Lyon, classé au '''Patrimoine Mondial de l'Unesco''' ! C'est un '''lieu de séminaire inédit à Lyon''', en hommage à cette fabuleuse épopée des soyeux du 19ème siècle qui a façonné tout un quartier et qui raconte au détour de chaque escalier et traboule, cet héritage secret, unique à '''Lyon.'''
Bienvenue dans le '''1er arrondissement de Lyon,''' dans l’univers secret d’un '''lieu événementiel''' magique, dans lequel tout est symbole ! …
Idéalement situé dans le quartier '''Terreaux-Opéra-Hôtel de Ville, en Presqu’île de Lyon,''' ce cocon intime, chic et inspirant, saura vous plonger dans l’énergie bohème d’un ancien Canut lyonnais, revisité avec charme et élégance, façon cabinet de curiosités.
Le Papillon Bleu est '''une salle de réunion à Lyon''' très facile d’accès car sa situation est très centrale, 3 parkings sont à moins de 7mn à pied (Terreaux, Hôtel de Ville et Opéra) et le métro (Croix Paquet Ligne C) est à 3mn à pied ou (Hôtel de Ville Ligne A) à 7mn à pied.
===== <u>4 espaces à votre disposition en privatisation exclusive et globale :</u> =====
- Une salle de réunion de 45m2
- Un espace salon en mode - Comme à la maison- de 70m2
- Une terrasse de 35m2
- En option en sus : Le Cocon (appartement cuisine/séjour 36m2) mise à disposition pour vos sous commissions
===== Organisez votre '''événement professionnel''' '''au Papillon Bleu en plein centre de Lyon''' dans un quartier historique emblématique, bohème et arty, à la beauté architecturale insolite, à 10 mn de la Gare Lyon Perrache et 20 mn de la Gare de Lyon Part-Dieu. =====
Et offrez à vos collaborateurs ou à vos clients, une expérience curieuse dans un lieu inédit et inspirant !
Pour vos journées d'études, réunions commerciales, formations, conférences, séminaires d’entreprise, lancements produit, workshops, incentives, team building, cocktails dînatoires, captations vidéo, petits-déjeuners, after-works...…
Capacité 20 personnes en format U, 30 personnes en format conférence, 40 personnes en format cocktail
Le Papillon Bleu, l'adresse confidentielle de Lyon 1er
Le Papillon Bleu : 28 rue burdeau - 69001 Lyon
75bkjwaipkbmdnad5m9zex8h7oh9v6x
744317
744316
2025-06-08T15:21:58Z
2A02:8429:83BC:A601:4069:8FC2:2F5F:8130
RAJOUT DES ACCES ET QUARTIER
744317
wikitext
text/x-wiki
=== LE PAPILLON BLEU EST UN LIEU ÉVÉNEMENTIEL A LYON, QUI REND HOMMAGE A L’HISTOIRE ! ===
Le Papillon Bleu est né d’un coup de coeur pour l’un des quartiers les plus vivants et fascinants de Lyon, classé au '''Patrimoine Mondial de l'Unesco''' ! C'est un '''lieu de séminaire inédit à Lyon''', en hommage à cette fabuleuse épopée des soyeux du 19ème siècle qui a façonné tout un quartier et qui raconte au détour de chaque escalier et traboule, cet héritage secret, unique à '''Lyon.'''
Bienvenue dans le '''1er arrondissement de Lyon,''' dans l’univers secret d’un '''lieu événementiel''' magique, dans lequel tout est symbole ! …
Idéalement situé dans le quartier '''Terreaux-Opéra-Hôtel de Ville, en Presqu’île de Lyon,''' ce cocon intime, chic et inspirant, saura vous plonger dans l’énergie bohème d’un ancien Canut lyonnais, revisité avec charme et élégance, façon cabinet de curiosités.
Le Papillon Bleu est '''une salle de réunion à Lyon''' très facile d’accès car sa situation est très centrale, 3 parkings sont à moins de 7mn à pied (Terreaux, Hôtel de Ville et Opéra) et le métro (Croix Paquet Ligne C) est à 3mn à pied ou (Hôtel de Ville Ligne A) à 7mn à pied.
===== <u>4 espaces à votre disposition en privatisation exclusive et globale :</u> =====
- Une salle de réunion de 45m2
- Un espace salon en mode - Comme à la maison- de 70m2
- Une terrasse de 35m2
- En option en sus : Le Cocon (appartement cuisine/séjour 36m2) mise à disposition pour vos sous commissions
===== Organisez votre '''événement professionnel''' '''au Papillon Bleu en plein centre de Lyon''' dans un quartier historique emblématique, bohème et arty, à la beauté architecturale insolite, à 10 mn de la Gare Lyon Perrache et 20 mn de la Gare de Lyon Part-Dieu. =====
Et offrez à vos collaborateurs ou à vos clients, une expérience curieuse dans un lieu inédit et inspirant !
Pour vos journées d'études, réunions commerciales, formations, conférences, séminaires d’entreprise, lancements produit, workshops, incentives, team building, cocktails dînatoires, captations vidéo, petits-déjeuners, after-works...…
Capacité 20 personnes en format U, 30 personnes en format conférence, 40 personnes en format cocktail
==== ACCÈS ET QUARTIER ====
Idéalement situé au coeur d’un quartier très vivant de la presqu’île de Lyon, classé au Patrimoine Mondial de l’Unesco, avec de nombreux commerçants,
restaurants et bars à proximité.
Depuis la Gare Part Dieu : Métro B (direction Charpennes) puis Métro A (direction Perrache) : arrêt Hôtel de Ville en 20mn, Bus C3,
C13 arrêt Mairie du 1er en 25mn, Taxi en 15-20 mn
Parkings : Terreaux , Hôtel de Ville et Opéra à moins de 7 mn à pied
Métro : Croix Paquet (ligne C ) à 3mn et Hôtel de Ville (ligne A) à 7mn
Bus : Hôtel de Ville – Louis Pradel C3, C5, C13, C14, C18, 9, 19
Station Vélo’v : Place Louis Pradel, Place Tolozan
Le Papillon Bleu, l'adresse confidentielle de Lyon 1er
Le Papillon Bleu : 28 rue burdeau - 69001 Lyon
e1s85v8r2cju8vi0dk5lvko781fxcrv