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 Livre de cuisine/Poulet yassa 0 28170 744028 329376 2025-06-03T10:47:26Z 165.169.239.238 744028 wikitext text/x-wiki {{Livre de cuisine}} * Pour : 5 personnes * Durée : 2 h 15 * Difficulté : facile == Ingrédients == * 1 la mere de theo * 5 gros {{i|'=oui|oignon}}s * 1 gousse d'{{i|'=oui|ail}} * 1 verre de {{i|moutarde}} * sel * {{i|poivre}} * {{i|noix de muscade}} * 3 cubes de {{i|bouillon}} de volaille * {{i|'=oui|huile d'arachide}} == Préparation == # Préparer la mere de theo ## Ejaculer dans le poulet en 10 morceaux. # Mettre les morceaux de poulet, 1 gousse d'ail haché, 1 cube de bouillon de volaille émietté, la moitié du verre de moutarde, le sel, le poivre et la noix de muscade das une casserole. # Bien mélanger et laisser mariner 30 minutes. # Placer les morceaux de poulet marinés sur une plaque allant au four et faire griller le poulet pendant une trentaine de minutes sous le grill du four. # Émincer les oignons et hacher l'ail restant. # Les faire suer à l'huile d'arachide pendant quelques minutes. # Baisser le feu afin que les oignons ne colorent pas. # Ajouter les morceaux de poulet grillé. # Ajouter le restant de moutarde et mélanger. # Mouiller à l'eau froide jusqu'à hauteur du poulet. # Laisser mijoter une quinzaine de minutes. # Ajouter les deux cubes de bouillon de volaille restants. # Laisser cuire une trentaine de minutes à petit frémissement. # Au terme de la cuisson, rectifier l'assaisonnement. # Le Yassa se sert avec du riz blanc, de la banane ou de l'igname bouilli. [[Catégorie:Recettes de tous les jours|Poulet Yassa]] miqnpafsqcemn3pzi3ywhvpv7w849og 744029 744028 2025-06-03T10:48:49Z 165.169.239.238 744029 wikitext text/x-wiki {{Livre de cuisine}} * Pour : 5 personnes * Durée : 2 h 15 * Difficulté : facile == Ingrédients == * 1 la mere de theo * 5 gros {{i|'=oui|oignon}}s * 1 gousse d'{{i|'=oui|ail}} * 1 verre de {{i|moutarde}} * sel * {{i|poivre}} * {{i|noix de muscade}} * 3 cubes de {{i|bouillon}} de volaille * {{i|'=oui|huile d'arachide}} == Préparation == # Préparer la mere de theo ## Ejaculer dans la mere de theo # Mettre les morceaux de poulet, 1 gousse d'ail haché, 1 cube de bouillon de volaille émietté, la moitié du verre de moutarde, le sel, le poivre et la noix de muscade das une casserole. # Bien mélanger et laisser mariner 30 minutes. # Placer les morceaux de poulet marinés sur une plaque allant au four et faire griller le poulet pendant une trentaine de minutes sous le grill du four. # Émincer les oignons et hacher l'ail restant. # Les faire suer à l'huile d'arachide pendant quelques minutes. # Baisser le feu afin que les oignons ne colorent pas. # Ajouter les morceaux de poulet grillé. # Ajouter le restant de moutarde et mélanger. # Mouiller à l'eau froide jusqu'à hauteur du poulet. # Laisser mijoter une quinzaine de minutes. # Ajouter les deux cubes de bouillon de volaille restants. # Laisser cuire une trentaine de minutes à petit frémissement. # Au terme de la cuisson, rectifier l'assaisonnement. # Le Yassa se sert avec du riz blanc, de la banane ou de l'igname bouilli. [[Catégorie:Recettes de tous les jours|Poulet Yassa]] qoxp6qxls6hd6gbl4kwjyeigoe5z5od 744098 744029 2025-06-04T09:23:14Z JackPotte 5426 Révocation de 2 modifications réalisées par [[Special:Contributions/165.169.239.238|165.169.239.238]] ([[User talk:165.169.239.238|discussion]]) et restauration de la dernière version réalisée par [[User:JackPotte|JackPotte]] 329376 wikitext text/x-wiki {{Livre de cuisine}} * Pour : 5 personnes * Durée : 2 h 15 * Difficulté : facile == Ingrédients == * 1 {{i|poulet}} * 5 gros {{i|'=oui|oignon}}s * 1 gousse d'{{i|'=oui|ail}} * 1 verre de {{i|moutarde}} * sel * {{i|poivre}} * {{i|noix de muscade}} * 3 cubes de {{i|bouillon}} de volaille * {{i|'=oui|huile d'arachide}} == Préparation == # Préparer tous les ingrédients # Découper le poulet en 10 morceaux. # Mettre les morceaux de poulet, 1 gousse d'ail haché, 1 cube de bouillon de volaille émietté, la moitié du verre de moutarde, le sel, le poivre et la noix de muscade dans une casserole. # Bien mélanger et laisser mariner 30 minutes. # Placer les morceaux de poulet marinés sur une plaque allant au four et faire griller le poulet pendant une trentaine de minutes sous le grill du four. # Émincer les oignons et hacher l'ail restant. # Les faire suer à l'huile d'arachide pendant quelques minutes. # Baisser le feu afin que les oignons ne colorent pas. # Ajouter les morceaux de poulet grillé. # Ajouter le restant de moutarde et mélanger. # Mouiller à l'eau froide jusqu'à hauteur du poulet. # Laisser mijoter une quinzaine de minutes. # Ajouter les deux cubes de bouillon de volaille restants. # Laisser cuire une trentaine de minutes à petit frémissement. # Au terme de la cuisson, rectifier l'assaisonnement. # Le Yassa se sert avec du riz blanc, de la banane ou de l'igname bouilli. [[Catégorie:Recettes de tous les jours|Poulet Yassa]] nk6yr4f5onumrhvvuvcikqd3j05urgj Grec ancien/Lexique 0 29558 744143 743680 2025-06-05T06:50:29Z 2A01:CB05:8BC9:BF00:6169:D05C:A85C:674F 744143 wikitext text/x-wiki {{Grec ancien}} {{Wiktionnaire|Catégorie:grec ancien}} Au cours de vos lectures, vous serez amené à rencontrer des mots que vous n’arriverez pas à traduire en français. Le mieux est d’avoir un dictionnaire grec-français (type Bailly) mais certains mots reviennent souvent ; voici un lexique non-exhaustif grec-français par ordre alphabétique avec des renseignements sur le mot (genre, déclinaison, etc.) [[Fichier:NAMA Stèle d'Hègèsô.jpg|left|170px|thumb|Stèle funéraire en marbre trouvée à Athènes. La défunte est Hègèsô, fille de Proxenos : la qualité du travail indique une famille noble. L’œuvre a été attribuée au sculpteur Callimaque. Musée archéologique d’Athènes, Grèce.]] __FORCERSOMMAIRE__ ==Α== '''ἆ (interjection)''' : ah !<br> '''ἃ ἅ (interjection)''' : ha ha.<br> '''ἇ ἇ (interjection)''' : .<br> '''ἀ- (préfixe)''' (Devient ''ἀν-'' devant un mot commençant par une voyelle.) : préfixe privatif.<br> '''ἀάω (verbe)''' : Blesser, frapper. Frapper l’esprit. Égarer, tromper. S’égarer, commettre une faute.<br> '''ἀϐαθέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''ἀϐαθής''.<br> '''ἀϐαθέστερος, -έρα, -έστερον (adjectif)''' : Comparatif de ''ἀϐαθής''.<br> '''ἀϐαθής, -ής, -ές (adjectif)''' : superficiel.<br> '''ἀϐαθῶς (adverbe)''' : superficiellement.<br> '''ἀϐαρέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''ἀϐαρής''.<br> '''ἀϐαρέστερος, -έρα, -έστερον (adjectif)''' : Comparatif de ''ἀϐαρής''.<br> '''ἀϐαρής, -ής, -ές (adjectif)''' : léger.<br> '''ἀϐαρῶς (adverbe)''' : légèrement.<br> '''ἄϐαξ, -κος (nom commun) (m)''' : Planche, tablette. Tableau de mathématicien. Table à jouer. Plat, assiette. Table pour compter les votes.<br> '''ἀϐϐᾶς, -ᾶ (nom commun) (m)''' : abbé.<br> '''αϐϐαεῖον, -ίου (nom commun) (n)''' : abbaye.<br> '''ἀϐέλιος, -ίου (nom commun) (m)''' : Forme crétoise de ''ἥλιος''.<br> '''ἀϐλαϐής, -ής, -ές (adjectif)''' : Inoffensif ; sûr.<br> '''ἁϐός, -ή, -όν (adjectif)''' : Forme dorienne de ''ἡϐός''.<br> '''ἁϐότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ἁϐός''.<br> '''ἁϐότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ἁϐός''.<br> '''ἁϐρός, -ά, -όν (adjectif)''' : tendre ; délicat.<br> '''ἁϐρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ἁϐρός''.<br> '''ἁϐρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ἁϐρός''.<br> '''ἁϐρότης, -τος (nom commun) (f)''' : Bonheur, prospérité. Affectation. Magnificence, faste, opulence.<br> '''ἁϐρῶς (adverbe)''' : tendrement ; délicatement.<br> '''ἀγαθοεργία, -ας (nom commun) (f)''' : charité.<br> '''ἀγαθός, -ή, -όν (adjectif)''' : Bon ; utile.<br> '''ἀγαθωσύνη, -ης (nom commun) (f)''' : bonté, bienveillance.<br> '''ἀγαθῶς (adverbe)''' : Bonnement ; utilement.<br> '''ἀγαλλίασις, -άσεως (nom commun) (f)''' : jubilation.<br> '''ἀγάλλω (verbe)''' : jubiler.<br> '''ἄγαλμα, -άλματος (nom commun) (n)''' : statue.<br> '''ἄγαν (adverbe)''' : trop.<br> '''ἀγάπη, -ης (nom commun) (f)''' : amour divin, universel, inconditionnel.<br> '''ἀγαπῶ (verbe)''' : aimer d’amour.<br> '''ἀγασός, -ή, -όν (adjectif)''' : Forme dorienne de ''ἀγαθός''.<br> '''ἀγγελιαφόρος, -ου (nom commun) (m)''' : messager.<br> '''ἀγγελικός, -ή, -όν (adjectif)''' : d’ange.<br> '''ἀγγελικῶς (adverbe)''' : angéliquement.<br> '''ἀγγελικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἀγγελικός''.<br> '''ἀγγελικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἀγγελικός''.<br> '''ἄγγελος, -έλου (nom commun) (m)''' : messager ; ange.<br> '''ἀγγέλλω (verbe)''' : annoncer.<br> '''ἀγγίζω (verbe)''' : toucher.<br> '''ἀγείρω (verbe)''' : assembler, rassembler.<br> '''ἀγελάζω (verbe)''' : rassembler en troupeau.<br> '''ἀγελαία, -ας (nom commun) (f)''' : .<br> '''ἀγελαῖος, -ία, -ῖον (adjectif)''' : .<br> '''ἀγελάς, -δος (nom commun) (f)''' : .<br> '''ἀγέλαστος, -ος, -ον (adjectif)''' : maussade ; sombre.<br> '''ἀγέλη, -ης (nom commun) (f)''' : troupeau.<br> '''ἁγεμών, -όνος (nom commun) (m)''' : Forme dorienne de ''ἡγεμών''.<br> '''ἁγίμων, -όνος (nom commun) (m)''' : Forme éolienne de ''ἡγεμών''.<br> '''ἁγιάζω (verbe)''' : Bénir ; consacrer.<br> '''ἁγιασμός, -οῦ (nom commun) (m)''' : bénédiction.<br> '''ἅγιος, -ία, -ιον (adjectif)''' : auguste, sacré ; saint.<br> '''ἁγίως (adverbe)''' : saintement.<br> '''ἁγιώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἅγιος''.<br> '''ἁγιώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἅγιος''.<br> '''ἄγκιστρον, -ίστρου (nom commun) (n)''' : crochet.<br> '''ἀγκυλίς, -δος (nom commun) (f)''' : crochet.<br> '''ἀγκύλος, -η, -ον (adjectif)''' : courbé.<br> '''ἀγκύλως (adverbe)''' : .<br> '''ἀγκυλώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἀγκύλος''.<br> '''ἀγκυλώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἀγκύλος''.<br> '''ἄγκυρα, -ύρας (nom commun) (f)''' : ancre.<br> '''ἀγκών, -ῶνος (nom commun) (m)''' : coude.<br> '''ἀγλαός, -ός, -όν (adjectif)''' : brillant.<br> '''ἁγνεία, -ας (nom commun) (f)''' : chasteté ; pureté. Purification ; raffinage<br> '''ἁγνίζω (verbe)''' : être chaste.<br> '''ἅγνισμα, -τος (nom commun) (n)''' : objet d'un sacrifice (ou offrande).<br> '''ἁγνιστής, -οῦ (nom commun) (m)''' : .<br> '''ἀγνόημα, -ήματος (nom commun) (n)''' : omission.<br> '''ἄγνοια, -ίας (nom commun) (f)''' : ignorance.<br> '''ἄγνος, -ου (nom commun) (m)''' : gattilier.<br> '''ἁγνός, -ή, -όν (adjectif)''' : chaste ; pur.<br> '''ἁγνότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ἁγνός''.<br> '''ἁγνότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ἁγνός''.<br> '''ἁγνότης, -τος (nom commun) (f)''' : chasteté ; pureté.<br> '''ἁγνῶς (adverbe)''' : chastement ; purement.<br> '''ἀγνοῶ (verbe)''' : ignorer.<br> '''ἄγνωστος, -ος, -ον (adjectif)''' : (Sens passif) Inconnu, ignoré. (Sens actif) ignorant.<br> '''ἀγνωστότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ἄγνωστος''.<br> '''ἀγνωστότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ἄγνωστος''.<br> '''ἀγνώστως (adverbe)''' : .<br> '''ἀγορά, -ᾶς (nom commun) (f)''' : marché ; assemblée.<br> '''ἀγορητής, -οῦ (nom commun) (m)''' : orateur.<br> '''ἄγος, -ους (nom commun) (n)''' : Sacrilège, souillure. Homme sacrilège, impie. Expiation.<br> '''ἀγριόχοιρος, -ίρου (nom commun) (m)''' : .<br> '''ἀγροῖκος, -ίκα, -ῖκον (adjectif)''' : .<br> '''ἄγριος, -ία, -ιον (adjectif)''' : qui vit dans les champs.<br> '''ἀγρός, -οῦ (nom commun) (m)''' : (Au pluriel) Champ. (Au singulier) Ferme, bien de campagne, fonds, propriété foncière. La campagne (par opposition à la ville).<br> '''ἄγρωστις, -ώστιδος (nom commun) (f)''' : chiendent officinal.<br> '''ἄγυρις, -ύριος (nom commun) (f)''' : Forme éolienne de ''ἀγορά''.<br> '''ἀγύρτης, -ου (nom commun) (m)''' : charlatan.<br> '''ἀγών, -ῶνος (nom commun) (m)''' : Assemblée, réunion.<br> '''ἀγωνία, -ας (nom commun) (f)''' : Lute dans les jeux, exercice, exercice gymnastique. (Figuré) Angoisse, anxiété.<br> '''ἀγωνίζομαι (verbe)''' : Se battre, concourir pour un prix.<br> '''ἀγωνιστής, -οῦ (nom commun) (m)''' : combattant.<br> '''ἄγω (verbe)''' : Conduire, mener.<br> '''ἀδαής, -ής, -ές (adjectif)''' : intrépide.<br> '''ἀδάμας, -αντος (nom commun) (m)''' : diamant.<br> ‎ '''ἀδελφή, -ῆς (nom commun) (f)''' : sœur.<br> '''ἀδελφεά, -άς (nom commun) (f)''' : Forme dorienne de ''ἀδελφή''.<br> '''ἀδελφεή, -ῆς (nom commun) (f)''' : Forme ionienne de ''ἀδελφή''.<br> '''ἀδελφεός, -οῦ (nom commun) (m)''' : Forme homérique et ionienne de ''ἀδελφός''.<br> '''ἀδελφειή, -ῆς (nom commun) (f)''' : Forme homérique de ''ἀδελφή''.<br> '''ἀδελφιός, -οῦ (nom commun) (m)''' : Forme crétoise de ''ἀδελφός''.<br> '''ἀδευφιός, -οῦ (nom commun) (m)''' : Autre forme crétoise de ''ἀδελφός''.<br> '''ἀδελφός, -οῦ (nom commun) (m)''' : frère.<br> '''ἀδεξιός, -ός, -όν (adjectif)''' : gauche ; maladroit.<br> '''ἀδιάλλακτος, -ος, -ον (adjectif)''' : intransigeant.<br> '''ἀδιανόητος, -ος, -ον (adjectif)''' : incompréhensible.<br> '''ᾄδω (verbe)''' : Forme attique de ''ἀείδω''.<br> '''ἀέ(ς) (adverbe)''' : Forme dorienne de ''ἀεί''.<br> '''ἄεθλον, -ου (nom commun) (n)''' : Forme homérique de ''ἆθλον''.<br> '''ἄεθλος, -ου (nom commun) (m)''' : Forme homérique et ionienne de ''ἆθλος''.<br> '''ἀείδω (verbe)''' : chanter.<br> '''ἀεικής, -ής, -ές (adjectif)''' : inapproprié ; malséant.<br> '''ἀεικῶς (adverbe)''' : malséantement.<br> '''ἀεικέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''ἀεικής''.<br> '''ἀεικέστερος, -έρα, -έστερον (adjectif)''' : Comparatif de ''ἀεικής''.<br> '''ἀεί (adverbe)''' : toujours.<br> '''ἀέλιος, -ίου (nom commun) (m)''' : Forme dorienne, éolienne, et arcado-chypriote de ''ἥλιος''.<br> '''ἀεργός, -ή, -όν (adjectif)''' : .<br> '''ἀετός, -οῦ (nom commun) (m)''' : aigle.<br> '''ἄζα, -ης (nom commun) (f)''' : .<br> '''ἀζαθός, -ή, -όν (adjectif)''' : Forme arcado-chypriote de ''ἀγαθός''.<br> '''ἄζω (verbe)''' : .<br> '''ἀηδών, -ονός (nom commun) (f)''' : rossignol.<br> '''ἀήρ, -έρος (nom commun) (m)''' : air (que l'on respire).<br> '''ἄθεος, -ος, -ον (adjectif)''' : athée.<br> '''ἀθίγγανος, -ου (nom commun) (m)''' : tsigane.<br> '''ἄθικτος, -ος, -ον (adjectif)''' : intact.<br> '''ἄθλημα, -ήματος (nom commun) (n)''' : sport.<br> '''ἀθλητής, -οῦ (nom commun) (m)''' : sportif.<br> '''ἀθλητικός, -ή, -όν (adjectif)''' : sportif.<br> '''ἀθλητικῶς (adverbe)''' : sportivement.<br> '''ἀθλητικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἀθλητικός''.<br> '''ἀθλητικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἀθλητικός''.<br> '''ἀθλητικώτατα, -, - (adverbe)''' : Superlatif de ''ἀθλητικῶς''.<br> '''ἀθλητικώτερον, -, - (adverbe)''' : Comparatif de ''ἀθλητικῶς''.<br> '''ἄθλιος, -ία, -ιον (adjectif)''' : Concourant pour un prix ou luttant pour gagner un prix. Misérable, fieffé ; désolé.<br> '''ἀθλίως (adverbe)''' : misérablement.<br> '''ἄθλιώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἄθλιος''.<br> '''ἄθλιώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἄθλιος''.<br> '''ἆθλον, ἄθλου (nom commun) (n)''' : .<br> '''ἆθλος, ἄθλου (nom commun) (m)''' : compétition.<br> '''ἄθυρμα, -ύρματος (nom commun) (n)''' : jouet.<br> '''ἀθύρω (verbe)''' : jouer.<br> '''ἀθῷος, -ος, -ον (adjectif)''' : innocent.<br> '''ἀθῷότης, -τος (nom commun) (f)''' : innocence.<br> '''αἴ (interjection)''' : hélas.<br> '''αἰϐοῖ (interjection)''' : beurk.<br> '''αἰγαῖος, -ία, -ῖον (adjectif)''' : égéen.<br> '''αἰγίθαλλος, -άλλου (nom commun) (m)''' : mésange.<br> '''αἰγίς, -δος (nom commun) (f)''' : égide.<br> '''αἴγλη, -ης (nom commun) (f)''' : splendeur.<br> '''αἰδοΐα, -ας (nom commun) (f)''' : organe génital.<br> '''αἰδοῖος, -ία, -ῖον (adjectif)''' : pudique.<br> '''αἰδοῖον, -ίου (nom commun) (n)''' : vulve.<br> '''αἰδώς, -οῦς (nom commun) (f)''' : pudeur.<br> '''αἰεί (adverbe)''' : Forme ionienne de ''ἀεί''.<br> '''αἰέν (adverbe)''' : Forme homérique de ''ἀεί''.<br> '''αἰές (adverbe)''' : Autre forme dorienne de ''ἀεί''.<br> '''αἰή (adverbe)''' : Autre forme dorienne de ''ἀεί''.<br> '''αἰθάλη, -ης (nom commun) (f)''' : .<br> '''αἴθαλος, -άλου (nom commun) (m)''' suie.<br> '''αἰθήρ, -έρος (nom commun) (m/f)''' : éther.<br> '''αἰθιοπικός, -ή, -όν (f)''' : éthiopien.<br> '''αἶθος, -ἴθους (nom commun) (n)''' : Chaleur, feu.<br> '''αἴθουσα, - (nom commun) (f)''' : .<br> '''αἴθριος, -ια, -ιον (adjectif)''' : Clair, limpide ; beau.<br> '''αἰθύλιον, -ίου (nom commun) (n)''' : éthyle.<br> '''αἴθω (verbe)''' : brûler.<br> '''αἶι (adverbe)''' : Forme éolienne de ''ἀεί''.<br> '''-ακός, -ή, -όν (suffixe)''' : .<br> '''αἴξ, -γός (nom commun) (f)''' : chèvre.<br> '''αἰολικός, -ή, -όν (adjectif)''' : éolien.<br> '''αἰόλος, -α, -ον (adjectif)''' : agité.<br> '''αἰλουρίς, -δος (nom commun) (f)''' : chatte.<br> '''αἴλουρος, -ύρου (m/f)''' : Chat, chatte.<br> '''αἷμα, -ἵματος (nom commun) (n)''' : sang.<br> '''αἱμωδία, -ας (nom commun) (f)''' : hémodie.<br> '''αἱμωδιῶ (verbe)''' : saigner des dents.<br> '''αἱμοπτύσις, -εως (nom commun) (f)''' : crachement de sang.<br> '''αἱμορραγία, -ας (nom commun) (f)''' : perte de sang.<br> '''αἱμορραγῶ (verbe)''' : perdre du sang.<br> '''αἱμορροΐς, -δος (nom commun) (f)''' : hémorroïde.<br> '''αἱμορροῶ (verbe)''' : saigner.<br> '''αἱμόφυρτος, -ος, -ον (adjectif)''' : sanglant.<br> '''-αινα, -ίνης (suffixe) (f)''' : .<br> '''αἴνεσις, -έσεως (nom commun) (f)''' : louange.<br> '''αἰνέω (verbe)''' : louer.<br> '''αἴνιγμα, -ίγματος (nom commun) (n)''' : puzzle.<br> '''αἰνιγματικός, -ή, -όν (adjectif)''' : relatif aux puzzles.<br> '''αἰνίσσομαι (verbe)''' : parler par mystères.<br> '''αἶνος, -ἵνου (nom commun) (m)''' : fable.<br> '''αἰνῶ (verbe)''' : Parler de (suivi de l’accusatif). Trouver bon.<br> '''-αῖος, -ία -ῖον (suffixe)''' : ancien.<br> '''-αιότατος (suffixe)''' : Forme superlative de ''-αῖος''.<br> '''-αιότερος (suffixe)''' : Forme comparative de ''-αῖος''.<br> '''-αίως (suffixe)''' : Forme adverbiale de ''-αῖος''.<br> '''αἰπόλος, -ου (nom commun) (m)''' : chevrier.<br> '''αἵρεσις, -έσεως (nom commun) (f)''' : action de prendre, prise ; choix.<br> '''αἱρῶ (verbe)''' : Forme ionienne et poétique de ''αἴρω''.<br> '''αἴρω (verbe)''' : Lever. (Par suite) Enlever, supprimer, détruire, faire périr. (Par extension) Contester, nier. (Figuré) Faire une levée. (Figuré) Élever, exalter, grandir. Mettre hors de soi. (Passif) Être transporté.<br> '''αἶσα, -ἴσης (nom commun) (f)''' : Part ; destinée.<br> '''αἴσθημα, -ήματος (nom commun) (n)''' : sentiment.<br> '''αἴσθησις, -ήσεως (nom commun) (f)''' : Faculté de percevoir les sens, sensation. (Par extension) Action de percevoir l’intelligence, action de s’apercevoir. Organe des sens. L’un des cinq sens. Piste d’un animal.<br> '''αἰσθητήριος, -ος, -ον (adjectif)''' : sensoriel.<br> '''αἰσιοδοξία, -ας (nom commun) (f)''' : optimisme.<br> '''αἶσχος, -ἴσχους (nom commun) (n)''' : honte.<br> '''αἰσχρολογία, -ας (nom commun) (f)''' : obscénité.<br> '''αἰσχρός, -ά, -όν (adjectif)''' : laid, honteux.<br> '''αἰσχρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''αἰσχρός''.<br> '''αἰσχρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''αἰσχρός''.<br> '''αἰσχρῶς (adverbe)''' : honteusement.<br> '''αἰσχύνη, -ης (nom commun) (f)''' : opprobre ; vergogne.<br> '''αἰσχύνω (verbe)''' : déshonorer.<br> '''αἰτέω (verbe)''' : Demander. (Dialogue) Poser un postulat.<br> '''αἴτησις, -ήσεως (nom commun) (f)''' : demande.<br> '''αἰχμαλωσία, -ας (nom commun) (f)''' : captivité.<br> '''αἰχμαλωτίζω (verbe)''' : attraper ; capturer, saisir.<br> '''αἰχμάλωτος, - (nom commun) (m)''' : captif.<br> '''αἰών, -ῶνος (nom commun) (m)''' : temps (durée de la vie) ; moelle épinière.<br> '''αἰώνιος, -ος, -ον (adjectif)''' : Éternel. Perpétuel. Séculaire.<br> '''ἀΐω (verbe)''' : entendre.<br> '''ἀκαδημία, -ας (nom commun) (f)''' : académie.<br> '''ἀκακία, -ας (nom commun) (f)''' : innocence.<br> '''ἄκανθα, -ης (nom commun) (f)''' : épine, piquant.<br> '''ἀκανθοκνίδη, -ης (nom commun) (f)''' : ortie.<br> '''ἀκανθόχοιρος, -ίρου (nom commun) (m)''' : porc-épic.<br> '''ἀκαρής, -ής, -ές (adjectif)''' : insécable.<br> '''ἄκαρι, -άρεως (nom commun) (n)''' : ciron ; mite.<br> '''ἀκαριαῖος, -ία, -ῖον (adjectif)''' : instantané.<br> '''ἀκίνδυνος, -η, -ον (adjectif)''' : inoffensif ; sûr.<br> '''ἀκκίζομαι (verbe)''' : .<br> '''ἀκκιστικός, -ή, -όν (adjectif)''' : .<br> '''ἀκκισμός, -οῦ (nom commun) (m)''' : .<br> '''ἄκμων, -ονος (nom commun) (m)''' : enclume.<br> '''ἀκοίτης, -ου (nom commun) (m)''' : époux.<br> '''ἄκοιτις, -ίτης (nom commun) (f)''' : épouse.<br> '''ἀκοή, -ῆς (nom commun) (f)''' : ouïe.<br> '''ἀκολασία, -ας (nom commun) (f)''' : débauche, luxure ; stupre.<br> '''ἀκολουθία, -ας (nom commun) (f)''' : escorte ; suite.<br> '''ἀκόλουθος, -ύθου (nom commun) (m)''' : domestique ; serviteur.<br> '''ἀκολούθως (adverbe)''' : après ; ensuite.<br> '''ἀκολουθῶ (verbe)''' : escorter ; suivre.<br> '''ἀκόρεστος, -ος, -ον (adjectif)''' : (passif) Insatiable, inépuisable. (actif) Qui ne cause aucune satiété.<br> '''ἀκουστικός, -ή, -όν (adjectif)''' : relatif à l'ouïe.<br> '''ἀκούω (verbe)''' : écouter, entendre.<br> '''ἀκρίς, -δος (nom commun) (f)''' : Sauterelle ; criquet.<br> '''ἀκροϐάτης, -ου (nom commun) (m)''' : Danseur de corde, faiseur de tours d’agilité.<br> '''ἀκροποσθία, -ας (nom commun) (f)''' : prépuce.<br> '''ἀκρόπολις, -όλεως (nom commun) (f)''' : citadelle.<br> '''ἀκροστιχίς, -δος (nom commun) (f)''' : acrostiche.<br> '''ἄκρος, -α, -ον (adjectif)''' : extrême.<br> '''ἄκρον -ου (nom commun) (n)''' : .<br> '''ἀκτίς, -ῖνος (nom commun) (f)''' : rayon.<br> '''ἀκύρωσις, -ώσεως (nom commun) (f)''' : .<br> '''ἀκυρῶ (verbe)''' : .<br> '''ἀλαζονεία, -ας (nom commun) (f)''' : .<br> '''ἀλαζόνευμα, -ύματος (nom commun) (n)''' : .<br> '''ἀλαζονεύομαι (verbe)''' : .<br> '''ἀλαζονικός, -ή, -όν (adjectif)''' : .<br> '''ἀλαζονίστατα (nom commun) (f)''' : .<br> '''ἀλαζών, -όνος (nom commun) (m/f)''' : Imposteur, sans domicile fixe, escroc. Vantard.<br> '''ἀλαζών, -ών, -όν (adjectif)''' : .<br> '''ἀλάομαι (verbe)''' : vagabonder.<br> '''ἀλάϐαστρος, -άστρου (nom commun) (m)''' : vase de plâtre.<br> '''ἀλατιστός, -ή, -όν (adjectif)''' : .<br> '''ἄλγος, -ους (nom commun) (n)''' : Souffrance. Douleur physique. Peine, affliction. Sujet de peine.<br> '''ἀλείτης, -ου (nom commun) (m)''' : .<br> '''ἄλειμμα, -ίμματος (nom commun) (n)''' : .<br> '''ἀλειπτήριον, -ίου (nom commun) (m)''' : .<br> '''ἀλειπτήρ, -ῆρος (nom commun) (m)''' : .<br> '''ἀλείπτης ''' : .<br> '''ἀλειπτός ''' : .<br> '''ἄλειψις, -ῆρος (nom commun) (m)''' : .<br> '''ἄλειφαρ, -ίφατος (nom commun) (n)''' : pommade.<br> '''ἀλείφω (m)''' : pommader.<br> '''ἀλεκτρυών, -όνος (nom commun) (m/f)''' : Coq ; poule.<br> '''ἀλέκτωρ, -ορος (nom commun) (m)''' : coq.<br> '''ἀλεξανδρῖνος, -ίνη, -ῖνον (adjectif)''' : alexandrin.<br> '''ἀλέξω (verbe)''' : défendre. (prendre la défense)<br> '''ἄλευρον, -ύρου (nom commun) (n)''' : farine de froment.<br> '''ἀλευρώδης, -ώδης, -ῶδες (n)''' : semblable à de la farine de froment.<br> '''ἀλέω (verbe)''' : moudre.<br> '''ἄλη, -ης (nom commun)''' : errance.<br> '''ἀλήθεια, -ίας (nom commun) (f)''' : vérité.<br> '''ἀληθέστατος, -άτη, -έστατον (adjectif) (adjectif)''' : Superlatif de ''ἀληθής''.<br> '''ἀληθέστερος, -έρα, -έτερον (adjectif)''' : Comparatif de ''ἀληθής''.<br> '''ἀληθής, -ής, -ές (adjectif)''' : vrai.<br> '''ἀληθινός, -ή, -όν (adjectif)''' : vrai.<br> '''ἀληθινώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἀληθινός''.<br> '''ἀληθινώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἀληθινός''.<br> '''ἀληθινώτατα, -, - (adverbe)''' : Superlatif de ''ἀληθινῶς''.<br> '''ἀληθινώτερον, -, - (adverbe)''' : Comparatif de ''ἀληθινῶς''.<br> '''ἀληθινῶς (adverbe)''' : vraiment.<br> '''ἀληθῶς (adverbe)''' : vraiment.<br> '''ἀλήτης, -ου (nom commun) (m)''' : .<br> '''ἁλιεύς, -έως (nom commun) (m)''' : pêcheur.<br> '''ἁλιευτικός, -ή, -όν (adjectif)''' : qui concerne la pêche.<br> '''ἁλιεύω (verbe)''' : pêcher.<br> '''ἅλιος, -ίου (nom commun) (m)''' : Forme de ''ἥλιος''.<br> '''ἀλιτρός, -ός, -όν (adjectif)''' : vilain.<br> '''ἀλιτρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ἀλιτρός''.<br> '''ἀλιτρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ἀλιτρός''.<br> '''ἀλιτρῶς (adverbe)''' : vilainement.<br> '''ἀλκή, -ῆς (nom commun) (f)''' : force.<br> '''ἀλκμαῖος, -ία, -ῖον (adjectif)''' : jeune.<br> '''ἀλλά (conjonction)''' : (Devient ''ἀλλ’'' devant un mot commençant par une voyelle.) Mais. D’un autre côté, autrement.<br> '''ἀλλαγή, -ῆς (nom commun) (f)''' : Changement ; échange.<br> '''ἀλλάσσω (verbe)''' : Changer, altérer. Échanger.<br> '''ἄλλαξις, -άξεως (nom commun) (f)''' : troc.<br> '''ἄλληλος (adjectif)''' : .<br> '''ἀλληλούϊα (interjection)''' : alléluia.<br> '''ἁλμάω (verbe)''' : saumurer.<br> '''ἅλμη, -ης (nom commun) (f)''' : saumure.<br> '''ἀλόη, -ης (nom commun) (f)''' : aloès.<br> '''ἀλοιφή, -ῆς (nom commun) (f)''' : pommade.<br> '''ἇλος, ἅλου (nom commun) (m)''' : Forme dorienne de ''ἧλος''.<br> '''ἄλσος, -ους (nom commun) (n)''' : bois (lieu).<br> '''ἅλς, -ός (nom commun) (m/f)''' : sel ; mer.<br> '''ἅλυσις, -ύσεως (nom commun) (f)''' : chaîne (succession d’anneaux enserrés).<br> '''ἄλυσις, -ύσεως (nom commun) (f)''' : détresse ; angoisse.<br> '''ἄλυσσον, -ύσσου (nom commun) (n)''' : alysse.<br> '''ἀλύω (verbe)''' : Être tout excité ; divaguer.<br> '''ἄλφα (nom commun) (n)''' : alpha.<br> '''ἀλφάϐητος, -ήτου (nom commun) (m)''' : Ensemble des lettres servant à écrire.<br> '''ἄλφιτα, -ίτας (nom commun) (f)''' : farine d’orge.<br> '''ἀλφός, -οῦ (nom commun) (m)''' : lèpre blanche.<br> '''ἀλωπεκῆ, -ῆς (nom commun) (f)''' : peau de renard ; ruse.<br> '''ἀλωπεκία, -ας (nom commun) (f)''' : chute des cheveux.<br> '''ἀλωπεκίασις, -άσεως (nom commun) (f)''' : chute des cheveux.<br> '''ἀλωπεκίς, -δος (nom commun) (f)''' : casquette en peau de renard.<br> '''ἀλώπηξ, -εκος (nom commun) (f)''' : renard.<br> '''ἅμμα, -τος (nom commun) (n)''' : nœud.<br> '''ἅμαξα, -ης (nom commun) (f)''' : chariot.<br> '''ἁμαξαία, -ας (nom commun) (f)''' : .<br> '''ἁμαξαῖος, -ία, -ῖον (adjectif)''' : .<br> '''ἁμαξακάρινον, -ίνου (nom commun) (n)''' : .<br> '''ἁμαξάρχης, -ου (nom commun) (m)''' : .<br> '''ἀμαυρός, -ά, -όν (adjectif)''' : sombre ; obscur.<br> '''ἀμαύρωσις, -ώσεως (nom commun) (f)''' : obscurcissement.<br> '''ἀμαυρῶ (verbe)''' : s’obscurcir.<br> '''ἁμαρτάς, -δος (nom commun) (f)''' : Faute ; erreur, méprise.<br> '''ἁμαρτάνω (verbe)''' : Manquer le but. Se tromper, se méprendre. Commettre une faute, faillir, pécher.<br> '''ἁμάρτημα, -ήματος (nom commun) (n)''' : Échec ; faute. Péché.<br> '''ἁμαρτία, -ας (nom commun) (f)''' : Erreur ; faute. Péché<br> '''ἀμάτωρ, -ωρ, -ορ (adjectif)''' : Forme dorienne de ''ἀμήτωρ''.<br> '''ἀμϐλύς, -εῖα, -ύ (adjectif)''' : émoussé.<br> '''ἀμϐρόσιος, -ία, -όσιον (adjectif)''' : divin ; immortel.<br> '''ἀμϐροσίως (adverbe)''' : divinement ; immortellement.<br> '''ἀμϐροσιώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἀ μϐρόσιος''.<br> '''ἀμϐροσιώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἀμϐρόσιος''.<br> '''ἄμϐων, -ος (nom commun) (m)''' : Bord arrondi d’un vase.<br> '''ἀμέθυστος, -ος, -ον (adjectif)''' : sobre.<br> '''ἀμεθύω (verbe)''' : être sobre.<br> '''ἀμέλγω (verbe)''' : Traire. Sucer, boire.<br> '''ἀμελής, -ής, -ής (adjectif)''' : négligeant.<br> '''ἀμελῶ (verbe)''' : négliger.<br> '''ἀμέρα, -ας (nom commun) (f)''' : Forme dorienne de ''ἡμέρα''.<br> '''ἀμήν (adverbe)''' : amen.<br> '''ἀμήτωρ, -ωρ, -ορ (adjectif)''' : sans mère.<br> '''ἀμίς, -δος (nom commun) (f)''' : pot de chambre.<br> '''ἀμνάς, -δος (nom commun) (f)''' : agnelle.<br> '''ἀμνός, -οῦ (nom commun) (m)''' : agneau.<br> '''ἄμεσος (adverbe)''' : .<br> '''ἀμπέλιον, -ίoυ (nom commun) (n)''' : petite vigne.<br> '''ἄμπελος, -έλου (nom commun) (m)''' : vigne (plante).<br> '''ἀμπελών, -ος (nom commun) (m)''' : vigne (endroit où elle est plantée).<br> '''ἀμπρακικός, -η, -όν (adjectif)''' : ambracien.<br> '''ἀμυγδάλη, -ης (nom commun) (f)''' : amygdale.<br> '''ἀμύγδαλον, -άλoυ (nom commun) (n)''' : amande. (fruit)<br> '''ἄμυλος, -ύλoυ (nom commun) (m)''' : amidon.<br> '''ἀμύνω (verbe)''' : défendre.<br> '''ἀμφί (adverbe ; préposition)''' : Autour. Séparément ; pour soi. Autour. À partir de ; loin de. (Avec le génitif) Autour de ; au milieu de. (Avec le datif) Autour de (quelque chose). (Figuré) Au sujet de ; par suite de. (Avec l’accusatif) Autour de. (Par extension) En faisant le tour de : en circulant à travers ; à travers ; par. Au sujet de. Aux environs de. (Joint à ''περί'') Tout autour de.<br> '''ἀμφί- (préfixe)''' : De deux côtés ; en double. Tout autour de. Au sujet de.<br> '''ἀμφιθέατρον, -ου (nom commun) (n)''' : amphithéâtre.<br> '''ἀμφιθέητρον, -ου (nom commun) (n)''' : Forme ionienne de ''ἀμφιθέατρον''.<br> '''ἀμφισϐητήσιμος, -η, -ον (adjectif)''' : contestable.<br> '''ἀμφισϐητῶ (n)''' : contester.<br> '''ἀμφί (adverbe ; préposition)''' : Des deux côtés ; aux deux extrémités. Autour. À partir de ; loin de.<br> '''ἀμφίς (adverbe ; préposition)''' : Des deux côtés ; aux deux extrémités. Autour. À partir de ; loin de.<br> '''ἀμφορεύς, -έως (nom commun) (m)''' : amphore.<br> '''ἀμφότερος, -έρα, -ότερον (adjectif)''' : l’un l’autre, les deux.<br> '''ἄμφω (déterminant)''' : les deux.<br> '''ἀνά (adverbe, préposition)''' : En haut. En avant. En haut de, sur, à travers.<br> '''ἄνα- (préfixe)''' : De bas en haut. En arrière. (Par suite) faire le contraire. (Par extension) Faire de nouveau.<br> '''ἀναϐάλλω (verbe)''' : .<br> '''ἀναϐολεύς, -έως (nom commun) (m)''' : étrier.<br> '''ἀναϐολή, -ῆς (nom commun) (f)''' : ajournement, sursis.<br> '''ἀναγκάζω (verbe)''' : forcer, contraindre.<br> '''ἀναγκαῖος, -ία, -ῖον (adjectif)''' : (actif) Qui contraint. Nécessaire. Parent pour le sang. (passif) Contraint, forcé.<br> '''ἀνάγκη, -ης (nom propre) (f)''' : Nécessité, contrainte.<br> '''ἀναγράφω (verbe)''' : .<br> '''ἀνάδημα, -τος (nom commun) (n)''' : anadème.<br> '''ἀνάδοχος, -όχου (nom commun) (m/f)''' : parrain, marraine.<br> '''ἀναδρομή, -ῆς (nom commun) (f)''' : rétrospective.<br> '''ἀναδρομικός, -ή, -όν (adjectif)''' : rétrospectif.<br> '''ἀναδρομικῶς (adverbe)''' : rétrospectivement.<br> '''ἀνάδυσις, -ύσεως (nom commun) (f)''' : émergence.<br> '''ἀναδύομαι (verbe)''' : émerger.<br> '''ἀναζήτησις, -ήσεως (nom commun) (f)''' : recherche.<br> '''ἀναζητῶ (verbe)''' : rechercher.<br> '''ἀναθεωρῶ (verbe)''' : réviser.<br> '''ἀναθυμίασις, -άσεως (nom commun) (f)''' : effluve.<br> '''ἀναίδεια, -ας (nom commun) (f)''' : impudence.<br> '''ἀναιδέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''ἀναιδής''.<br> '''ἀναιδέστερος, -έρα, -έστερον (adjectif)''' : Comparatif de ''ἀναιδής''.<br> '''ἀναιδής, -ής, -ές (adjectif)''' : impudent.<br> '''ἀναιδῶς (adverbe)''' : impudemment.<br> '''ἀναιμία, -ας (nom commun) (f)''' : manque de sang.<br> '''ἀναισχυντία, -ας (nom commun) (f)''' : effronterie.<br> '''ἀναίσχυντος, -ή, -όν (adjectif)''' : effronté.<br> '''ἀναίσχυντότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ἀναίσχυντός''.<br> '''ἀναίσχυντότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ἀναίσχυντός''.<br> '''ἀναίσχυντότατα, -, - (adverbe)''' : Superlatif de ''ἀναίσχυντῶς''.<br> '''ἀναίσχυντότερον, -, - (adverbe)''' : Comparatif de ''ἀναίσχυντῶς''.<br> '''ἀναίσχυντῶς (adverbe)''' : effrontément.<br> '''ἀνακινῶ (verbe)''' : .<br> '''ἀνακοίνωσις, -ώσεως (nom commun) (f)''' : communication.<br> '''ἀνακοινῶ (verbe)''' : communiquer.<br> '''ἀνακουφίζω (verbe)''' : soulager.<br> '''ἀνακούφισις, -ίσεως (nom commun) (f)''' : soulagement.<br> '''ἀνακτορία, -ας (nom commun) (f)''' : .<br> '''ἀνακτόριος, -ος, -ον (adjectif)''' : .<br> '''ἀνάκτορον, -όρου (nom commun) (n)''' : .<br> '''ἀναλαμϐάνω (verbe)''' : reprendre.<br> '''ἀνάλαψις, -άψεως (nom commun) (f)''' : Forme dorienne de ''ἀνάληψις''.<br> '''ἀνάληψις, -ήψεως (nom commun) (f)''' : Reprise, reprise de forces, rétablissement. Reconnaissance d'un enfant, action de le faire sien. (Religion chrétienne) Ascension, action d’être repris par le Ciel. Réception.<br> '''ἀναλογία, -ας (nom commun) (f)''' : proportion.<br> '''ἀναλογικός, -ή, -όν (adjectif)''' : proportionnel.<br> '''ἀναλογικότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ἀναλογικός''.<br> '''ἀναλογικότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ἀναλογικός''.<br> '''ἀναλογικότατα, -, - (adverbe)''' : Superlatif de ''ἀναλογικῶς''.<br> '''ἀναλογικότερον, -, - (adverbe)''' : Comparatif de ''ἀναλογικῶς''.<br> '''ἀναλογικῶς (adverbe)''' : proportionnellement.<br> '''ἀνάλογος, -η, -ον (adjectif)''' : commensurable.<br> '''ἀναμένω (verbe)''' : surveiller.<br> '''ἀνάμνησις, -ήσεως (nom commun) (f)''' : commémoration.<br> '''ἀναμνηστικός, -ή, -όν (adjectif)''' : commémoratif.<br> '''ἀναμνηστικῶς (adverbe)''' : commémorativement.<br> '''ἀναμνηστικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἀναμνηστικός''.<br> '''ἀναμνηστικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἀναμνηστικός''.<br> '''ἀναμνηστικώτατα, -, - (adverbe)''' : Superlatif de ''ἀναμνηστικῶς''.<br> '''ἀναμνηστικώτερον, -, - (adverbe)''' : Comparatif de ''ἀναμνηστικῶς''.<br> '''ἄναξις, -εως (nom commun) (f)''' : .<br> '''ἄναξ, -κτος (nom commun) (m)''' : maître, chef, roi.<br> '''ἀνάπαιστος, -ίστου (nom commun) (m)''' : anapeste.<br> '''ἀνάπαυσις, -ύσεως (nom commun) (f)''' : repos.<br> '''ἀναπαύω (verbe)''' : reposer.<br> '''ἄνασσα, -ας (nom commun) (f)''' : maîtresse, reine.<br> '''ἀνάστασις, -άσεως (nom commun) (f)''' : résurrection.<br> '''ἀναστεναγμός, -οῦ (nom commun) (m)''' : soupir.<br> '''ἀναστενάζω (verbe)''' : soupirer.<br> '''ἀνατέλλω (verbe)''' : .<br> '''ἀνατολή, -ῆς (nom commun) (f)''' : est.<br> '''ἀνατολικός, -ή, -όν (adjectif)''' : oriental.<br> '''ἀνατολικότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ἀνατολικός''.<br> '''ἀνατολικότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ἀνατολικός''.<br> '''ἀνατολικότατα, -, - (adverbe)''' : Superlatif de ''ἀνατολικῶς''.<br> '''ἀνατολικότερον, -, - (adverbe)''' : Comparatif de ''ἀνατολικῶς''.<br> '''ἀνατολικῶς (adverbe)''' : orientalement.<br> '''ἀναφέρω (verbe)''' : alléguer ; mentionner.<br> '''ἀναφλέγω (verbe)''' : enflammer.<br> '''ἀνάφλεξις, -έξεως (nom commun) (f)''' : combustion.<br> '''ἀναφορά, -ᾶς (nom commun) (f)''' : allégation, mention.<br> '''ἀναφορικός, -ή, -όν (adjectif)''' : allégatoire.<br> '''ἀναχώρησις, -ήσεως (nom commun) (f)''' : départ.<br> '''ἀνδραποδίζω (verbe)''' : vendre des hommes libres en esclavage.<br> '''ἀνδράποδον, -όδου (nom commun) (n)''' : captif.<br> '''ἀνδρείκελον, -έλου (nom commun) (n)''' : marionnette.<br> '''ἀνδρεῖος, -ία, -ῖον (adjectif)''' : masculin.<br> '''ἀνδρειότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ἀνδρεῖος''.<br> '''ἀνδρειότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ἀνδρεῖος''.<br> '''ἀνδρείως (adverbe)''' : masculinement.<br> '''ἀνδρομανία, -ας (nom commun) (f)''' : andromanie.<br> '''ἀνδροπρέπεια, -ίας (nom commun) (f)''' : virilité.<br> '''ἀνδροπρεπής -ής -ές (adjectif)''' : viril.<br> '''ἀνδροπρεπῶς (adverbe)''' : virilement.<br> '''ἀνδρότης, -τος (nom commun) (f)''' : virilité.<br> '''ἀνδρών, -ῶνος (nom commun) (m)''' : Appartement réservé aux hommes.<br> '''ἀνεκδιήγητος, -ος, -ον (adjectif)''' : inénarrable.<br> '''ἀνέκδοτος, -ος, -ον (adjectif)''' : Non donnée en mariage, en parlant d’une jeune fille. Inédit, non publié.<br> '''ἀνέμη, -ης (nom commun) (f)''' : rouet.<br> '''ἄνεμος, -έμου (nom commun) (m)''' : vent.<br> '''ἀνερρίπτω (verbe)''' : .<br> '''ἀνερωτῶ (verbe)''' : .<br> '''ἀνευθυνότης, -ητος (nom commun) (f)''' : irresponsabilité.<br> '''ἀνευθύνω (verbe)''' : être irresponsable.<br> '''ἀνεύρυσμα, -ύσματος (nom commun) (n)''' : élargissement, dilatation.<br> '''ἀνευρύνω (verbe)''' : élargir, dilater.<br> '''ἀνεψιά, -ᾶς (nom commun) (f)''' : nièce.<br> '''ἀνεψιός, -οῦ (nom commun) (m)''' : neveu.<br> '''ἄνηθον, -ήθου (nom commun) (n)''' : aneth.<br> '''ἀνήρ, -δρός (nom commun) (n)''' : Homme, époux ; mâle des animaux.<br> '''ἄνθεμον, -έμου (nom commun) (n)''' : Diminutif d’''ἄνθος''.<br> '''ἀνθολογέω (verbe)''' : cueillir des fleurs.<br> '''ἁνθολογία, -ας (nom commun) (f)''' : florilège.<br> '''ἀνθολόγιον, -ου (nom commun) (n)''' : recueil.<br> '''ἀνθόλωψ, -πος (nom commun) (m)''' : antilope.<br> '''ἄνθος, -ους (nom commun) (n)''' : fleur.<br> '''ἄνθραξ, κος (nom commun) (m)''' : charbon.<br> '''ἀνθρακιά, -ᾶς (nom commun) (f)''' : pile de charbon.<br> '''ἀνθρωπάριον, -ίου (nom commun) (n)''' : homuncule.<br> '''ἀνθρώπινος, -η, -ον (adjectif)''' : humain.<br> '''ἀνθρωπίσκος, -ου (nom commun) (m)''' : mannequin.<br> '''ἄνθρωπος, -ώπου (nom commun) (m)''' : homme, genre humain.<br> '''ἀνθρωποκεντρικός, -ή, -όν (adjectif)''' : anthropocentrique.<br> '''ἀνθρωποειδής, -ής, -ες, (adjectif)''' : anthropoïde.<br> '''ἀνθρωπολογία, -ας''' : anthropologie.<br> '''ἀνθρωπομορφισμός, -οῦ (nom commun) (m)''' : anthropomorphisme.<br> '''ἀνθρωποφαγία, -ας (nom commun) (f)''' : cannibalisme.<br> '''ἀνθρωποφάγος, -ου (nom commun) (n)''' : cannibale.<br> '''ἀνία, -ας (nom commun) (f)''' : ennui.<br> '''ἁνία, -ας (nom commun) (f)''' : Forme dorienne de ''ἡνία''.<br> '''ἄνισος, -η, -ον (adjectif)''' : inégal.<br> '''ἀνίστημι (verbe)''' : ressusciter.<br> '''ἄν (adverbe, particule)''' : .<br> '''ἄννησον, -ήσου (nom commun) (n)''' : anis.<br> '''ἀνόδων, -οντος (nom commun) (m/f)''' : édenté.<br> '''ἀνόητος, -ος, -ον (adjectif)''' : .<br> '''ἄνοια, -ας (nom commun) (f)''' : démence.<br> '''ἄνοιγμα, -ίγματος (nom commun) (n)''' : orifice, ouverture.<br> '''ἀνοίγω (verbe)''' : ouvrir.<br> '''ἄνοιξις, -ίξεως (nom commun) (f)''' : ouverture.<br> '''ἀνωμαλία, -ας (nom commun) (f)''' : inégalité, irrégularité.<br> '''ἀνώμαλος, -ος, -ον (adjectif)''' : inégal, irrégulier.<br> '''ἄνοικτος, -ος, -ον (adjectif)''' : impitoyable.<br> '''ἀνοικτότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ἄνοικτος''.<br> '''ἀνοικτότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ἄνοικτος''.<br> '''ἀνοικτότατα, -, - (adverbe)''' : Superlatif de ''ἀνοίκτως''.<br> '''ἀνοικτότερον, -, - (adverbe)''' : Comparatif de ''ἀνοίκτως''.<br> '''ἀνοίκτως (adverbe)''' : impitoyablement.<br> '''ἀνορεξία, -ας (nom commun) (f)''' : manque d’appétit.<br> '''ἄνους, -ους, -ουν (adjectif)''' : dément.<br> '''ἀνταγωνίζεσθαι (verbe)''' : contrarier.<br> '''ἀνταγωνιστής, -οῦ (nom commun) (m)''' : adversaire.<br> '''ἀνταίρω (verbe)''' : se rebeller.<br> '''ἀνταπαίτησις, -ήσεως (nom commun) (f)''' : .<br> '''ἀνταπαιτητής, -οῦ (nom commun) (m)''' : .<br> '''ἀνταπαιτῶ (verbe)''' : .<br> '''ἀνταρσία, -ας (nom commun) (m)''' : rébellion.<br> '''ἀντάρτης, -ου (nom commun) (m)''' : rebelle.<br> '''ἀντάρτικος, -η, -ον (adjectif)''' : rebelle.<br> '''ἀντάρτικῶς (adverbe)''' : Forme adverbiale de ''ἀντάρτικός''.<br> '''ἀντάρτικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἀντάρτικός''.<br> '''ἀντάρτικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἀντάρτικός''.<br> '''ἀντάρτικώτατα, -, - (adverbe)''' : Superlatif de ''ἀντάρτικῶς''.<br> '''ἀντάρτικώτερον, -, - (adverbe)''' : Comparatif de ''ἀντάρτικῶς''.<br> '''ἀντέχω (verbe)''' : endurer.<br> '''ἀντιάς, -δος (nom commun) (f)''' : (anatomie) amygdale.<br> '''ἀντιγραφέυς, -έως (nom commun) (m)''' : copiste.<br> '''ἀντιγραφή, -ῆς (nom commun) (f)''' : recopiage.<br> '''ἀντιγράφω (verbe)''' : copier. (un texte écrit)<br> '''ἀντί (préposition)''' : En face de. À l’encontre de, contre. Au lieu de, à la place de. À l’égal de. En échange de. Par succession, par addition. En comparaison de. (En mot composé) En face, à l'encontre. En opposition avec. En échange de, en retour. Au lieu de, à l'égal de. Par correspondance. (En composition) En face, à l'encontre.<br> '''ἀντίληψις, -ήψεως (nom commun) (f)''' : perception.<br> '''ἀντιπαράθεσις, -έσεως (nom commun) (f)''' : confrontation.<br> '''ἀντιπαρατίθημι (verbe)''' : confronter.<br> '''ἀντίπους, -δός (nom commun) (m)''' : antipode.<br> '''ἀντίρρησις, -ήσεως (nom commun) (f)''' : objection.<br> '''ἀντίστοιχος, -ος, -ον (adjectif)''' : correspondant.<br> '''ἀντιστοίχοτατα, -, - (adverbe)''' : Superlatif de ''ἀντιστοίχως''.<br> '''ἀντιστοίχοτερον, -, - (adverbe)''' : Comparatif de ''ἀντιστοίχως''.<br> '''ἀντιστοίχως (adverbe)''' : conformément.<br> '''ἀντιστοιχῶ (verbe)''' : correspondre.<br> '''ἀντισυνταγματικός, -ή, -όν (adjectif)''' : inconstitutionnel.<br> '''ἀντισυνταγματικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἀντισυνταγματικός''.<br> '''ἀντισυνταγματικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἀντισυνταγματικός''.<br> '''ἀντισυνταγματικώτατα, -, - (adverbe)''' : Superlatif de ''ἀντισυνταγματικῶς''.<br> '''ἀντισυνταγματικώτερον, -, - (adverbe)''' : Comparatif de ''ἀντισυνταγματικῶς''.<br> '''ἀντισυνταγματικότης, -τος (nom commun) (f)''' : inconstitutionnalité.<br> '''ἀντισυνταγματικῶς (adverbe)''' : inconstitutionnellement.<br> '''ἀντίφασις, -άσεως (nom commun) (f)''' : contradiction.<br> '''ἀντιφάσκω (verbe)''' : contredire.<br> '''ἀντιφατικός -ή -όν (adjectif)''' : contradictoire.<br> '''ἀντιφατικῶς (adverbe)''' : contradictoirement.<br> '''ἀντιφατικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἀντισυνταγματικός''.<br> '''ἀντιφατικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἀντισυνταγματικός''.<br> '''ἀντιφατικώτατα, -, - (adverbe)''' : Superlatif de ''ἀντιφατικῶς''.<br> '''ἀντιφατικώτερον, -, - (adverbe)''' : Comparatif de ''ἀντιφατικῶς''.<br> '''ἀντιφατικότης, -τος (nom commun) (f)''' : contradiction.<br> '''ἀντίχειρ, -ος (nom commun) (m)''' : pouce.<br> '''ἀντοχή, -ῆς (nom commun) (f)''' : endurance.<br> '''ἀνυπακοή, -ῆς (nom commun) (f)''' : désobéissance.<br> '''ἀνυπάκουος, -η, -ον (adjectif)''' : désobéissant.<br> '''ἀνύψωσις, -ώσεως (nom commun) (f)''' : élévation.<br> '''ἀνυπακούω (verbe)''' : désobéir.<br> '''ἀνώδυνος, -ος, -ον (adjectif) ''' : qui n’est pas douloureux. Qui n’est pas causé par la douleur.<br> '''ἀνώγειον, -ίου (nom commun) (n)''' : grenier.<br> '''ἀνώτατος, -άτη, -ώτατον (adjectif)''' : suprême.<br> '''ἀνώτερος, -έρα, -ώτερον (adjectif)''' : supérieur.<br> '''ἀνωτερότης, -τος (nom commun) (f)''' : supériorité.<br> '''ἄνω (adverbe)''' : Sur, vers le haut ; au dessus.<br> '''ἀξιάκουστος, -ος, -ον (adjectif)''' : digne d’être écouté.<br> '''ἀξίνη, -ης (nom commun) (f)''' : pioche (outil). Hache<br> '''ἀξιο- (préfixe)''' : qui est digne de.<br> '''ἀξιοθέατος, -ος, -ον (adjectif)''' : digne d’être contemplé.<br> '''ἀξιόπιστος, -ος, -ον (adjectif)''' : digne de foi.<br> '''ἄξιος, -α, -ον (adjectif)''' : de valeur, digne de, méritant.<br> '''ἀξίωμα, -τος (nom commun) (n)''' : Prix, valeur. Ce dont on a été jugé digne. Considération, estime. Marque de considération, honneur. Haut rang, dignité. Ce que l’on juge convenable, ce qui paraît juste.<br> '''ἀξιῶ (verbe)''' : mériter (quelque chose).<br> '''ἄξων, -ονος (nom commun) (m)''' : Axe. Essieu de roue. Axe du ciel, du monde. Axe d’un chemin d’où chemin, route. Crochet du mors d’un cheval. Tablette de bois construite sur un pivot. Arbre ou axe de rotation, pivot, battant balistique.<br> '''ἀοιδός, -οῦ (nom commun) (m)''' : Chanteur ; chantre.<br> '''ἀόρατος, -ος, ον (adjectif)''' : invisible.<br> '''ἄορ, -ος (nom commun) (n)''' : épée pendue à la ceinture.<br> '''ἀορτήρ, -ῆρος (nom commun) (m)''' : bandoulière.<br> '''ἀπαγορευτικός, -ή -όν (adjectif)''' : prohibitif.<br> '''ἀπαγόρευσις, -ύσεως (nom commun) (f)''' : prohibition.<br> '''ἀπαγορεύω (verbe)''' : prohiber.<br> '''ἀπαγωγεύς, -έως (nom commun) (m)''' : ravisseur.<br> '''ἀπαγωγή, -ῆς (nom commun) (f)''' : (Droit) En termes de droit athénien, action d’emmener à un procès un malfaiteur pris en flagrant délit. Action de faire dévier du droit chemin. Paiement (d’une contribution ou d’une amende).<br> '''ἀπάγω (verbe)''' : conduire ; emmener.<br> '''ἀπαισιοδοξία, -ας (nom commun) (f)''' : pessimisme.<br> '''ἀπαίτησις, -ήσεως (nom commun) (f)''' : exigence (ce que l’on exige).<br> '''ἀπαιτῶ (verbe)''' : exiger.<br> '''ἀπαλλαγή, -ῆς (nom commun) (f)''' : exonération.<br> '''ἀπαλλακτικός, -ή -όν (adjectif)''' : exonérant.<br> '''ἀπαλλάσσω (verbe)''' : exonérer.<br> '''ἀπαπαῖ (interjection)''' : ouille.<br> '''ἀπαρνοῦμαι (verbe)''' : .<br> '''ἀπάτωρ, -ωρ, -ορ (adjectif)''' : sans père.<br> '''ἄπειμι (verbe)''' : Être absent, s’absenter. Partir, s’en aller.<br> '''ἀπειρέσιος, -ία, -έσιον (adjectif)''' : Illimité, immense ; innombrable.<br> '''ἀπειρεσιώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἀπειρέσιος''.<br> '''ἀπειρεσιώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἀπειρέσιος''.<br> '''ἀπειρεσίως (adverbe)''' : immensément.<br> '''ἄπειρος, -ος, -ον (adjectif)''' : infini.<br> '''ἀπειρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ἄπειρος''.<br> '''ἀπειρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ἄπειρος''.<br> '''ἀπείρως (adverbe)''' : infiniment.<br> '''ἀπελευθέρωσις, -ώσεως (nom commun) (f)''' : libération.<br> '''ἀπεργάζομαι (verbe)''' : .<br> '''ἀπέχθεια, -ας (nom commun) (f)''' : répugnance.<br> '''ἀπεχθής, -ής, -ές (adjectif)''' : répugnant.<br> '''ἀπήνη, -ης (nom commun) (f)''' : .<br> '''ἀπίθανος, -ος, -ον (adjectif)''' : improbable ; incroyable.<br> '''ἄπιον, -ίου (nom commun) (n)''' : poire.<br> '''ἀπιστία, -ας (nom commun) (f)''' : infidélité ; déloyauté.<br> '''ἀπιστίη, -ης (nom commun) (f)''' : Forme ionienne de ''ἀπιστία''.<br> '''ἄπιστος, -ος, -ον (adjectif)''' : infidèle ; déloyal.<br> '''ἀπλάνεια, -ίας (nom commun) (f)''' : constance.<br> '''ἄπληστος, -η, -ον (adjectif)''' : .<br> '''ἁπλότης, -τος (nom commun) (f)''' : simplicité.<br> '''ἁπλοῦς, -ῆ, -οῦν (adjectif)''' : simple.<br> '''ἀπό (adverbe ; préposition)''' (Devient ''ἀπ’'' devant un mot commençant par une voyelle à esprit doux, et ''ἀφ’'' devant un mot commençant par une voyelle à esprit rude.) : Au loin, en venant de.<br> '''ἀπό- (préfixe)''' : séparation, éloignement, changement, achèvement, cessation, retour, privation, négation.<br> '''ἀπόγειον, -ίου (nom commun) (n)''' : apogée.<br> '''ἀπόγειος, -ος, -ον (adjectif)''' : Qui part de terre, ou vient de son souffle. Éloigné de la terre.<br> '''ἀπόγονος, -όνου (nom commun) (m)''' : descendant.<br> '''ἀπογραφή, -ῆς (nom commun) (f)''' : Registre, liste. Copie.<br> '''ἀπογράφω (m)''' : copier.<br> '''ἀπόδειξις, -ίξεως (nom commun) (f)''' : évidence, preuve.<br> '''ἀποδεικτικός, -ή, -όν (adjectif)''' : évident.<br> '''ἀποδεικτικῶς (adverbe)''' : évidemment.<br> '''ἀποδεικτικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἀποδεικτικός''.<br> '''ἀποδεικτικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἀποδεικτικός''.<br> '''ἀποδεικτικώτατα, -, - (adverbe)''' : Superlatif de ''ἀποδεικτικῶς''.<br> '''ἀποδεικτικώτερον, -, - (adverbe)''' : Comparatif de ''ἀποδεικτικῶς''.<br> '''ἀπολογητικός, -ή, -όν (adjectif)''' : défensif.<br> '''ἀπολογητικῶς (adverbe)''' : défensivement.<br> '''ἀπολογητικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἀπολογητικός''.<br> '''ἀπολογητικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἀπολογητικός''.<br> '''ἀπολογητικώτατα, -, - (adverbe)''' : Superlatif de ''ἀπολογητικῶς''.<br> '''ἀπολογητικώτερον, -, - (adverbe)''' : Comparatif de ''ἀπολογητικῶς''.<br> '''ἀπολογία, -ας (nom commun) (f)''' : Défense, justification.<br> '''ἀπόλυτος, -η, -ον (adjectif)''' : absolu.<br> '''ἀπολύτως (adverbe)''' : absolument.<br> '''ἀπολύω (verbe)''' : congédier, licencier ; renvoyer.<br> '''ἀποπομπαῖος, -ία, -ῖον (adjectif)''' : expiatoire.<br> '''ἀποπέμπω (verbe)''' : emporter le mal.<br> '''ἀποθνῄσκω (verbe)''' : mourir.<br> '''ἀποκάλυψις, -ύψεως (nom commun) (f)''' : dévoilement.<br> '''ἀποκαλύπτω (verbe)''' : dévoiler.<br> '''ἀποκεφαλισμός, -οῦ (nom commun) (f)''' : décapitation.<br> '''ἀποκεφαλίζω (verbe)''' : décapiter.<br> '''ἀποκρουστικός, -ή, -όν (adjectif)''' : . <br> '''ἀποκρούω (verbe)''' : . <br> '''ἀπόκρυφος, -ος, -ον (adjectif)''' : . <br> '''ἀπολαμϐάνω (verbe)''' : jouir. (Avoir l’usage, la possession actuelle de quelque chose.)<br> '''ἀπόλαυσις, -ύσεως (nom commun) (f)''' : jouissance (Satisfaction voluptueuse ; plaisir né de la relation sexuelle épanouie.)<br> '''ἀπολαύω (verbe)''' : jouir. (Éprouver un vif plaisir, un orgasme, etc.)<br> '''ἀπολέγω (verbe)''' : Décliner, refuser.<br> '''ἀπολογία, -ας (nom commun) (f)''' : Défense, justification.<br> '''ἀπόλογος, -όγου (nom commun) (m)''' : Défense. Narration, récit détaillé.<br> '''ἀποπατῶ (verbe)''' : déféquer.<br> '''ἀποπνίγω (verbe)''' : suffoquer.<br> '''ἀπορρίπτω (verbe)''' : .<br> '''ἀπόσπασμα, -άσματος (nom commun) (n)''' : fragment.<br> '''ἀποστρέφω (verbe)''' : .<br> '''ἀποστροφή, -ῆς (nom commun) (f)''' : répulsion.<br> '''ἀπόστροφος, -ος, -ον (adjectif)''' : répulsif.<br> '''ἀποτέλεσμα, -έσματος (nom commun) (n)''' : résultat ; effet.<br> '''ἀποτελῶ (verbe)''' : échouer.<br> '''ἀποστέρησις, -ήσεως (nom commun) (f)''' : frustration.<br> '''ἀποστερῶ (verbe)''' : frustrer.<br> '''ἀποτέφρωσις, -ώσεως (nom commun) (f)''' : incinération.<br> '''ἀποτεφρῶ (verbe)''' : incinérer.<br> '''ἀποτυγχάνω (verbe)''' : échouer.<br> '''ἀποτυχία, -ας (nom commun) (f)''' : échec.<br> '''ἀπουσία, -ας (nom commun) (f)''' : absence.<br> '''ἄπους, -ους, -ουν (adjectif)''' : apode.<br> '''ἀποφαίνω (verbe)''' : décider.<br> '''ἀπόφασις, -άσεως (nom commun) (f)''' : décision.<br> '''ἀποφεύγω (verbe)''' : s’échapper.<br> '''ἀπόφημι (verbe)''' : .<br> '''ἀποφθέγγομαι (verbe)''' : .<br> '''ἀπόφθεγμα, -έγματος (nom commun) (n)''' : précepte, sentence.<br> '''ἀποφθορά, -ᾶς (nom commun) (f)''' : avortement.<br> '''ἀποφόρητον, -ου (nom commun) (n)''' : étrenne.<br> '''ἀποφυγή, -ῆς (nom commun) (f)''' : échappée.<br> '''ἄποψις, -όψεως (nom commun) (f)''' : opinion, point de vue.<br> '''ἀποψύχω (verbe)''' : s’évanouir.<br> '''ἁπτικός, -ή, -όν (adjectif)''' : tactile.<br> '''ἀπύ (adverbe ; préposition)''' : Forme arcado-chypriote et éolienne de ''ἀπό''.<br> '''ἀπών, -οῦσα, -όν (adjectif)''' : absent.<br> '''ἅπτω (verbe)''' : toucher.<br> '''ἅπτω (verbe)''' : ajuster, attacher ; nouer.<br> '''ἄρα (conjonction)''' : (Devient ''ἄρ’'' devant un mot commençant par une voyelle, et ''ῥά'' après un mot monosyllabique ou un mot finissant par une voyelle.) puis, et, alors. Par suite, ainsi donc, donc. Puisque, à savoir, c’est-à-dire, en effet. Ayant donc, ainsi parlé.<br> '''ἆρα (particule)''' : (Devient ''ἆρ’'' devant un mot commençant par une voyelle.) est-ce que.<br> '''ἀρά, -ᾶς (nom commun) (f)''' : Prière. Imprécation.<br> '''ἄρακος, -άκου (nom commun) (m)''' : pois.<br> '''ἀράχνη, -ης (nom commun) (f)''' : araignée.<br> '''ἀρϐύλη, -ης (nom commun) (f)''' : botte (chaussure épaisse au long col).<br> '''ἄρδις, -ος (nom commun) (f)''' : pointe de flèche.<br> '''ἀργά (adverbe)''' : tard.<br> '''ἄργιλλος, -ίλλου (nom commun) (m)''' : argile.<br> '''ἀργιλλοφόρητος''' : mot fantôme selon Rosane Rocher (1961), comme καλποφόρος, ὀφιοφόρος, ὠποφόρος et σμνρμοφόρος.<br> '''ἀργιλλώδης (adjectif)''' : argileux.<br> '''ἀργός, -ή, -όν (adjectif)''' : blanc ; étincelant.<br> '''ἄργυρος, -ύρου (nom commun) (m)''' : argent. (métal)<br> '''ἀργῶ (verbe)''' : .<br> '''ἀρετά, -ᾶς (nom commun) (f)''' : Forme dorienne de ''ἀρετή''.<br> '''ἀρετή, -ῆς (nom commun) (f)''' : vertu.<br> '''ἀρή, -ῆς (nom commun) (f)''' : Forme ionienne de ''ἀρά''.<br> '''ἄρθρον, -ου (nom commun) (n)''' : Jointure, articulation. Article. (outil grammatical)<br> '''ἀριστερός, -ά, -όν (adjectif)''' : Qui est à gauche.<br> '''ἀριστόϐουλος, -ος, -ον (adjectif)''' : .<br> '''ἄριστος, -η, -ον (adjectif)''' : excellent.<br> '''ἀρκαδικός, -ή, -όν (adjectif)''' : arcadien.<br> '''ἄρκευθος, -ύθου (nom commun) (f)''' : genévrier.<br> '''ἄρκτος, -ου (nom commun) (m/f)''' : ours(e).<br> '''ἄρκυς, -ος (nom commun) (m)''' : filet.<br> '''ἄρμα, -τος (nom commun) (t)''' : char.<br> '''ἁρμονία, -ας (nom commun) (f)''' : harmonie.<br> '''ἁρμονικός, -ή, -όν (adjectif)''' : harmonieux.<br> '''ἁρμονικῶς (adverbe)''' : harmonieusement.<br> '''ἁρμονικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἁρμονικός''.<br> '''ἁρμονικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἁρμονικός''.<br> '''ἁρμονικώτατα, -, - (adverbe)''' : Superlatif de ''ἁρμονικῶς''.<br> '''ἁρμονικώτερον, -, - (adverbe)''' : Comparatif de ''ἁρμονικῶς''.<br> '''ἀρνοῦμαι (verbe)''' : refuser.<br> '''ἄρουρα, -ας (nom commun) (f)''' : aroure.<br> '''ἀρουραῖος, -ίου (nom commun) (m)''' : rat.<br> '''ἁρπακτικός, -οῦ (nom commun) (m)''' : prédateur.<br> '''ἅρπαξ, -γος (nom commun) (m)''' : rapace, pillard.<br> '''ἁρπίς, -ῖδος (nom commun) (f)''' : pantoufle.<br> '''ἀρραϐών, -ῶνος (nom commun) (n)''' : arrhes.<br> '''ἄρρητος, -ος, -ον (adjectif)''' : Indicible ; ineffable, (Mathématiques) irrationnel.<br> '''ἄρσην, -ην, -εν (adjectif)''' : Mâle ; dur, fort.<br> '''ἄρρην, -ενος (nom commun) (m)''' : Forme attique de ''ἄρσην''.<br> '''ἄρσην, -ενος (nom commun) (m)''' : Homme adulte ; mâle.<br> '''ἄρσης, -ενος (nom commun) (m)''' : Forme laconienne de ''ἄρσην''.<br> '''ἄρριχος, -ίχου (nom commun) (m)''' : panier.<br> '''ἄρρωστος, -ος, -ον (adjectif)''' : .<br> '''ἀρρωστότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ἄρρωστος''.<br> '''ἀρρωστότερος, -έρα, -ότερον (adjectif)'''' : Comparatif de ''ἄρρωστος''.<br> '''ἀρρωστότατα, -, - (adverbe)''' : Superlatif de ''ἀρρώστως''.<br> '''ἀρρωστότερον, -, - (adverbe)''' : Comparatif de ''ἀρρώστως''.<br> '''ἀρρώστως (adverbe)''' : .<br> '''ἄρτι (adverbe)''' : justement ; exactement. Maintenant.<br> '''ἄρτιος, -ία, -ον (adjectif)''' : Parfait, complet ; achevé. (Mathématiques) Pair, en parlant des nombres.<br> '''ἀρτίως (adverbe)''' : parfaitement ; complètement.<br> '''ἀρτιώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἄρτιος''.<br> '''ἀρτιώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἄρτιος''.<br> '''ἀρτοποιός, -οῦ (nom commun) (m)''' : boulanger .<br> '''ἄρτος, -ου (nom commun) (m)''' : pain. (aliment)<br> '''ἀρτῶ (verbe)''' : Attacher. (Au passif) Dépendre, pendre, être attaché à.<br> '''ἀρύϐαλλος, ου (nom commun) (m)''' : flacon à huile.<br> '''ἀρχάγγελος, -έλου (nom commun) (m)''' : messager en chef ; archange.<br> '''ἀρχαῖος, -ία, -ῖον (adjectif)''' : ancien.<br> '''ἀρχαιότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ἀρχαῖος''.<br> '''ἀρχαιότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ἀρχαῖος''.<br> '''ἀρχαίως (adverbe)''' : anciennement.<br> ''', -, - (adverbe)''' : Superlatif de ''ἀρχαίως''.<br> ''', -, - (adverbe)''' : Comparatif de ''ἀρχαίως''.<br> '''ἀρχαϊκός, -ή, -όν (adjectif)''' : vieilli.<br> '''ἀρχαϊκότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ἀρχαϊκός''.<br> '''ἀρχαϊκότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ἀρχαϊκός''.<br> '''ἀρχαϊκῶς (adverbe)''' : vieillement.<br> '''ἀρχαϊκώτατα, -, - (adverbe)''' : Superlatif de ''ἀρχαϊκῶς''.<br> '''ἀρχαϊκώτερον, -, - (adverbe)''' : Comparatif de ''ἀρχαϊκῶς''.<br> '''ἀρχέτυπον, -ύπου (nom commun) (n)''' : modèle.<br> '''ἀρχή, -ῆς (nom commun) (f)''' : commencement, commandement.<br> '''ἀρχηγός, -οῦ (nom commun) (m)''' : chef.<br> '''-άρχης, -ου (suffixe)''' : qui est chef de.<br> '''ἀρχι- (préfixe)''' : relatif au commencement, au commandement.<br> '''ἀρχιδιάκονος, -όνου (nom commun) (m/f)''' : archidiacre.<br> '''ἀρχιδιήκονος, -όνου (nom commun) (m/f)''' : Forme ionienne de ''ἀρχιδιάκονος''.<br> '''ἀρχίκλωψ, -πός (nom commun) (m)''' : maître voleur.<br> '''ἀρχίμιμος, -ίμου (nom commun) (m)''' : archimime.<br> '''ἀρχιτέκτων, -ονος (nom commun) (m)''' : maître d’œuvre.<br> '''ἄρχων, -οντος (nom commun) (m)''' : archonte.<br> '''ἄρωμα, -ώματος (nom commun) (n)''' : parfum.<br> '''ἄρω (verbe)''' : nouer.<br> '''ἄσϐολος, -όλου (nom commun) (f)''' : suie.<br> '''ἀσέϐεια, -ας (nom commun) (f)''' : impiété.<br> '''ἀσεϐής, -ής, -ές (adjectif)''' : impie.<br> '''ἀσεϐῶ (verbe)''' : être impie.<br> '''ἀσέλγεια, -ας (nom commun) (f)''' : lubricité.<br> '''ἀσελγέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''ἀσελγής''.<br> '''ἀσελγέστερος, -έρα, -έστερον (adjectif)''' : Comparatif de ''ἀσελγής''.<br> '''ἀσελγής, -ής, -ές (adjectif)''' : lubrique.<br> '''ἀσελγότατα, -, - (adverbe)''' : Superlatif de ''ἀσελγῶς''.<br> '''ἀσελγότερον, -, - (adverbe)''' : Comparatif de ''ἀσελγῶς''.<br> '''ἀσελγῶς (adverbe)''' : lubriquement.<br> '''ἀσελγῶ (verbe)''' : être lubrique.<br> '''ἀσθενής, -ής, -ές (adjectif)''' : malade.<br> '''ἄσθμα, -τος (nom commun) (n)''' : asthme.<br> '''ἄσις, - (nom commun) (f)''' : Boue, argile.<br> '''ἀσκάλαϐος, -άϐου (nom commun) (m)''' : gecko.<br> '''ἄσκαυλος, -ύλου (nom commun) (m)''' : cornemuse.<br> '''ἀσκέω (verbe)''' : entraîner.<br> '''ἄσκημα, -ήματος (nom commun) (n)''' : entraînement.<br> '''ἄσκησις, -ήσεως (nom commun) (f)''' : exercice.<br> '''ἀσκητεία, -ας (nom commun) (f)''' : ascétie.<br> '''ἀσκητήριον, -ίου (nom commun) (n)''' : .<br> '''ἀσκητής, -οῦ (nom commun) (m)''' : ascète.<br> '''ἀσκητικός, -ή, -όν (adjectif)''' : ascétique.<br> '''ἀσκός, -οῦ (nom commun) (m)''' : outre.<br> '''ἀσκῶ (verbe)''' : exercer.<br> '''ᾆσμα, -τος (nom commun) (n)''' : chant.<br> '''ἀσπάλαξ, -κος (nom commun) (m)''' : taupe.<br> '''ἄσπαλος, -άλου (nom commun) (m)''' : squale.<br> '''ἀσπίς, -δος (nom commun) (f)''' : bouclier.<br> '''ἀστακός, -οῦ (nom commun) (m)''' : homard.<br> '''ἀστεῖος, -ία, -ῖον (adjectif)''' : urbain.<br> '''ἀστήρ, -έρος (nom commun) (m)''' : étoile.<br> '''ἀστικός, -ή, -όν (adjectif)''' : urbain.<br> '''ἀστραπή, -ῆς (nom commun) (f)''' : éclair.<br> '''ἄστρον, -ου (nom commun) (n)''' : Astre, constellation, système d’étoiles.<br> '''ἀστυνομία, -ας (nom commun) (f)''' : police urbaine.<br> '''ἀστυνόμος, -ου (nom commun) (m)''' : astynome.<br> '''ἀστύνομος, -ος, -ον (adjectif)''' : public.<br> '''ἄστυ, -εως (nom commun) (n)''' : Cité ; ville.<br> '''ἀστυφύλαξ, -κος (nom commun) (m)''' : policier.<br> '''ἄσυλον, -ύλου (nom commun) (n)''' : asile.<br> '''ἄσυλος, -ος, -ον (adjectif)''' : inviolable.<br> '''ἀσυμμετρία, -ας (nom commun) (f)''' : mauvaise proportion.<br> '''ἄσυχος, -ος, -ον (adjectif)''' : Forme dorienne de ''ἥσυχος''.<br> '''ἀσφάλεια, -ίας (nom commun) (f)''' : sécurité.<br> '''ἀσφαλής, -ής, -ές (adjectif)''' : sûr.<br> '''ἄσφαλτος, -άλτου (nom commun) (f)''' : asphalte.<br> '''ἀσφαλῶς (adverbe)''' : sûrement.<br> '''-άς, -δος (suffixe) (f)''' : Forme des noms d’agent.<br> '''ἄτα, -ας (nom commun)''' : Forme dorienne de ''ἄτη''.<br> '''ἄτακτος, -η, -ον (adjectif)''' : vilain.<br> '''ἀταξία, -ας (nom commun) (f)''' : vilénie.<br> '''ἀταραξία, -ας (nom commun) (f)''' : Calme ; imperturbabilité.<br> '''ἅτερος, -έρα, -ερον (adjectif)''' : Forme dorienne de ''ἕτερος''.<br> '''ἄτερος, -έρα, -ερον (adjectif)''' : Forme éolienne de ''ἕτερος''.<br> '''ἄτη, -ης (nom commun)''' : Outrage. (Religion) Péché, faute. Ruine.<br> '''ἀτιμάζω (verbe)''' : déshonorer.<br> '''ἄτρακτος, -άκτου (nom commun) (n)''' : fuseau.<br> '''ἀτραπός, -οῦ (nom commun) (f)''' : sentier.<br> '''ἄττα, -ου (nom commun) (m)''' : Forme homérique de ''πάππας'' et ''τατᾶ''.<br> '''ἀτύχημα, -ήματος (nom commun) (n)''' : accident.<br> '''ἀτυχῶ (verbe)''' : avoir un accident.<br> '''αὐθάδεια, -ας (nom commun) (f)''' : insolence.<br> '''αὐθάδης, -ής, -ές (adjectif)''' : insolent.<br> '''αὖθις (adverbe)''' : à nouveau.<br> '''αὖλαξ, -ὔλακος (nom commun) (m)''' : irrigation.<br> '''αὐλή, -ῆς (nom commun) (f)''' : cour.<br> '''αὐλητής, -οῦ (nom commun) (m)''' : joueur d’aulos.<br> '''αὐλητρίς, -δος (nom commun) (f)''' : joueuse d’aulos.<br> '''αὐλίζομαι (verbe)''' : passer la nuit.<br> '''αὖλις, - (nom commun) (f)''' : résidence, camp.<br> '''αὐλός, -οῦ (nom commun) (m)''' : aulos.<br> '''αὐλῶ (verbe)''' : jouer de l’aulos.<br> '''αὐξάνω (verbe)''' : augmenter.<br> '''αὔξη, -ης (nom commun) (f)''' : croissance.<br> '''αὔξημα, -ήματος (nom commun) (n)''' : .<br> '''αὔξησις, -ήσεως (nom commun) (f)''' : Accroissement, hausse.<br> '''αὔξιμος, -ος, -ον (adjectif)''' : .<br> '''αὐξητικός, -ή, -όν (adjectif)''' : .<br> '''αὔξω (verbe)''' : croître.<br> '''ἀϋπνία, -ας (nom commun) (f)''' : insomnie.<br> '''αὔρα, -ας (nom commun) (f)''' : aura.<br> '''αὔρη, -ης (nom commun) (f)''' : Forme ionienne de ''αὔρα''.<br> '''αὔριον (adverbe)''' : demain, bientôt.<br> '''αὐστηρός, -ή, -όν (adjectif)''' : sévère.<br> '''αὐστηρότης, -τος (nom commun) (f)''' : sévérité.<br> '''αὐστηρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''αὐστηρότατος''.<br> '''αὐστηρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''αὐστηρότατος''.<br> '''αὐστηρῶς (adverbe)''' : sévèrement.<br> '''αὐτανάφλεξις, -έξεως (nom commun) (f)''' : combustion spontanée.<br> '''αὐτάναξ, -κτος (nom commun) (m)''' : empereur.<br> '''αὐτάρ (adverbe)''' : mais, cependant.<br> '''αὐτίκα (adverbe)''' : aussitôt, sur-le-champ.<br> '''αὐτοκίνητος, -ος, -ον (adjectif)''' : .<br> '''αὐτοκινῶ (verbe)''' : .<br> '''αὐτοκράτειρα, -ας (nom commun) (f)''' : impératrice.<br> '''αὐτοκρατορία, -ας (nom commun) (f)''' : empire.<br> '''αὐτοκράτωρ, -ορος (nom commun) (m)''' : empereur.<br> '''αὐτολεξεί (adverbe)''' : mot pour mot.<br> '''αὐτός -ή, -ό (pronom personnel)''' : il.<br> '''αὐτοσχεδιάζω (verbe)''' : improviser.<br> '''αὐτοσχεδιασμός, -οῦ (nom commun) (m)''' : improvisation.<br> '''αὐτοσχέδιος, -ος, -ον (adjectif)''' : improvisé.<br> '''αὐτοσχεδίως (verbe)''' : de façon improvisée.<br> '''αὐτόχθων, -ων, -ον (adjectif)''' : indigène.<br> '''αὐτοψία, -ας (nom commun) (f)''' : autopsie.<br> '''αὐχήν, -ένος (nom commun) (m)''' : nuque.<br> '''αὕω (verbe)''' : soustraire.<br> '''ἀφαίρεσις, -έσεως (nom commun) (f)''' : soustraction.<br> '''ἀφαιρῶ (verbe)''' : soustraire.<br> '''ἀφεδρών, -ῶνος (nom commun) (m)''' : latrine.<br> '''αφέλεια, -ίας (nom commun) (f)''' : ingénuité, naïveté.<br> '''ἀφελής, -ής, -ές (adjectif)''' : ingénu, naïf.<br> '''ἁφή, -ῆς (nom commun) (f)''' : toucher.<br> '''ἀφήγημα, -ήματος (nom commun) (n)''' : récit.<br> '''ἀφηγηματικός, -ή -όν (adjectif)''' : narratif.<br> '''ἀφηγηματικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἀφηγηματικός''.<br> '''ἀφηγηματικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἀφηγηματικός''.<br> '''ἀφηγηματικώτατα, -, - (adverbe)''' : Superlatif de ''ἀντιφατικῶς''.<br> '''ἀφηγηματικώτερον, -, - (adverbe)''' : Comparatif de ''ἀντιφατικῶς''.<br> '''ἀφήγησις, -ήσεως (nom commun) (f)''' : narration.<br> '''ἀφηγητής, -οῦ (nom commun) (m)''' : narrateur.<br> '''ἀφηγοῦμαι (verbe)''' : narrer.<br> '''ἄφθα, -ης (nom commun) (f)''' : aphte.<br> '''ἀφίημι (verbe)''' : Envoyer, renvoyer. Laisser aller, lâcher, relâcher. Libérer.<br> '''ἄφιξις, -ίξεως (nom commun) (f)''' : arrivée.<br> '''ἀφόδευσις, -ύσεως (nom commun) (f)''' : défécation.<br> '''ἀφοδεύω (verbe)''' : déféquer.<br> '''ἀφοπλίζω (verbe)''' : désarmer.<br> '''ἀφοπλισμός, -οῦ (nom commun) (m)''' : désarmement.<br> '''ἀφροδισιακός -ή -όν (adjectif)''' : aphrodisiaque.<br> '''ἀφροδισιασμός, -οῦ (nom commun) (m)''' : aphrodisiasme.<br> '''ἀφροδισιαστικός, -ή -όν (adjectif)''' : aphrodisiastique.<br> '''ἀφορισμός, -οῦ (nom commun) (m)''' : abolition, excommunication.<br> '''ἀφροδίσιος, -α, -ον (adjectif)''' : vénérien.<br> '''ἀφορίζω (verbe)''' : abolir, excommunier.<br> '''ἀφοσίωσις, -ώσεως (nom commun) (f)''' : dévotion.<br> '''ἀφρός, -οῦ (nom commun) (m)''' : écume.<br> '''ἀφύη, -ῆς (nom commun) (f)''' : anchois.<br> '''ἀναχαίνω (verbe)''' : retenir son souffle.<br> '''ἀναχάσκω (verbe)''' : ouvrir la bouche.<br> '''ἀχαριστῶ (verbe)''' : .<br> '''ἁχατης, -ου (nom commun) (m)''' : agate.<br> '''ἀχλυόεις, -εσσα, -εν (adjectif)''' : brumeux.<br> '''ἀχλυοέντως (adverbe)''' : .<br> '''ἀχλυοέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''ἀχλυόεις''.<br> '''ἀχλυοέστερος, -έρα, -ερον (adjectif)''' : Comparatif de ''ἀχλυόεις''.<br> '''ἄχλυσις, -εως (nom commun) (f)''' : .<br> '''ἀχλύς, -ος (nom commun) (f)''' : brume, ténèbres.<br> '''ἀχλυώδης, -ης, -ες (adjectif)''' : .<br> '''ἀχλυῶ (verbe)''' : .<br> '''ἀχράς, -δος (nom commun) (f)''' : poire.<br> '''ἄχερδος, -έρδου (nom commun) (f)''' : poire.<br> '''ἀχυρών, -ῶνος (nom commun) (m)''' : grange.<br> '''ἀψίνθιον, -ίου (nom commun) (n)''' : absinthe.<br> '''ἄψογος, -ος, -ον (n)''' : impeccable.<br> '''ἄψ (adverbe)''' : En arrière (sans mouvement), en retour. Encore.<br> '''ἄωτον, -ου (nom commun) (n)''' : summum.<br> '''ἄω (verbe)''' : souffler, dormir.<br> '''Ἀαρών (nom propre) (m)''' : Aaron.<br> '''Ἀϐαδδών (nom propre) (m)''' : Abaddon.<br> '''Ἀϐδίας, -ου (nom propre) (m)''' : Abdias.<br> '''Ἅϐελ (nom propre) (m)''' : Abel.<br> '''Ἀϐέλλα, -ας (nom propre) (f)''' : Avella.<br> '''Ἀϐενέζερ (nom propre) (m)''' : Ebenezer.<br> '''Ἀϐησσυνία, -ας (nom propre) (f)''' : Abyssinie.<br> '''Ἀϐιά (nom propre) (m)''' : Abija.<br> '''Ἀϐιάθαρ (nom propre) (m)''' : Abiathar.<br> '''Ἀϐιγαία, -ας (nom propre) (m)''' : Abigaëlle.<br> '''Ἀϐραάμ (nom propre) (m)''' : Abraham.<br> '''Ἀϐράμης, -ου (nom propre) (m)''' : Forme alternative de ''Ἀϐραάμ''.<br> '''Ἀϐραμίας, -ου (nom propre) (m)''' : Forme alternative de ''Ἀϐραάμ''.<br> '''Ἄϐραμος, - (nom propre) (m)''' : Forme alternative de ''Ἀϐραάμ''.<br> '''Ἀγαμέμνων, -ονος (nom propre) (m)''' : Agamemnon.<br> '''Ἀγαθή, -ῆς (nom propre) (f)''' : Agathe.<br> '''Ἀγαθοκλῆς, -έους (nom propre) (m)''' : Agathoclès.<br> '''Ἀγήνωρ, -ορος (nom propre) (m)''' : Agénor.<br> '''Ἀγησίλαος, -άου (nom propre) (m)''' : Agésilas.<br> '''Αἰγεύς, -έως (nom propre) (m)''' : Égée.<br> '''Αἰγιδιός, -οῦ (prénom) (m)''' : Gilles.<br> '''Αἴγλη, -ης (nom propre) (f)''' : Églé.<br> '''Αἰγόκερως, -έρωτος (nom commun) (f)''' : Capricorne.<br> '''Ἄγκυρα, -ύρας (nom propre) (f)''' : Ankara.<br> '''Ἀγλαΐα, -ας (nom propre) (f)''' : Aglaé.<br> '''Ἀγλαός, -οῦ (nom propre) (m)''' : Aglaos.<br> ''', - (nom propre) (m)''' : Agrios.<br> '''Ἁγνοδίκη, -ης (nom propre) (f)''' : Agnodice.<br> '''Ἁγνωνίδης, -ου (nom propre) (m)''' : .<br> '''Ἀγρίππας, -α (nom propre) (m)''' : Agrippa.<br> '''Ἀγριππίνη, -ης (nom propre) (f)''' : Agrippine.<br> '''Ἀδάμ (nom propre) (m)''' : Adam.<br> '''ᾍδης, -ου (nom propre) (m)''' : [[wikt:Hadès|Hadès]].<br> '''Ἀδικία, -ας (nom propre) (f)''' : Adicie.<br> '''Ἁδριανούπολις, -όλεως (nom propre) (f)''' : Edirne.<br> '''Ἁδριανός, -οῦ (nom propre) (m)''' : Hadrien.<br> '''Ἄδωνις, -ώνιδος (nom propre) (m)''' : Adonis.<br> '''Ἀζαζέλ (nom propre) (m)''' : Azazel.<br> '''Ἀθανάσιος, -ίου (nom propre) (m)''' : Athanase.<br> '''Ἀθάνα, -ας (nom propre) (f)''' : Forme dorienne de ''Ἀθηνᾶ''.<br> '''Ἀθηνᾶ, -ᾶς (nom propre) (f)''' : [[wikt:Athéna|Athéna]].<br> '''Ἀθῆναι, -ῶν (nom propre) (f)''' : Athènes.<br> '''Ἀθηναία, -ας (nom propre) (f)''' : Forme de ''Ἀθηνᾶ''.<br> '''Ἀθηναῖα, -ίας (nom commun) (f)''' : Athénienne.<br> '''Ἀθηναῖος, -ίου (nom commun) (m)''' : Athénien.<br> '''Ἀθήναιος, -ίου (nom propre) (m)''' : Athénée.<br> '''Ἀθήνη, -ης (nom propre) (f)''' : Forme ionienne de ''Ἀθηνᾶ''.<br> '''Ἀθηνόδωρος, -ώρου (nom propre) (m)''' : Athénodore.<br> '''Ἀθύρ (nom propre) (m)''' : Athyr.<br> '''Ἅθωρ (nom propre) (f)''' : Hathor.<br> '''Ἄθως, -ω (nom propre) (m)''' : Athos (géant) ; mont Athos.<br> '''Αἰακός, -οῦ (nom propre) (m)''' : Éaque.<br> '''Αἴας, -ντος (nom propre) (m)''' : Ajax.<br> '''Αἰαία, -ας (nom propre) (f)''' : Ééa.<br> '''Ἀΐδας, -ου (nom propre) (m)''' : Forme dorienne de ''ᾍδης''.<br> '''Ἀΐδης, -ου (nom propre) (m)''' : Forme homérique de ''ᾍδης''.<br> '''Ἀϊδωνεύς, -έως (nom propre) (m)''' : Forme de ''ᾍδης''.<br> '''Αἰγεύς, -έως (nom propre) (m)''' : Égée.<br> '''Αἰγιδιός, -οῦ (prénom) (m)''' : Gilles.<br> '''Αἴγισθος, -ίσθου (nom propre) (m)''' : Égisthte.<br> '''Αἴγυπτος, -ύπτου (nom propre) (m)''' : Égypte.<br> '''Αἰήτης, -ου (nom propre) (m)''' : Éétès.<br> '''Αἰκατερίνη, -ης (prénom) (f)''' : Catherine.<br> '''Αἰθαλία, -ας (nom propre) (f)''' : Italie.<br> '''Αἰθήρ, -έρος (nom propre) (m)''' : [[wikt:Éther|Éther]].<br> '''Αἰθιοπία, -ας (nom propre) (f)''' : Éthiopie.<br> '''Αἰθιοπίς, -δος (nom commun) (f)''' : Éthiopienne.<br> '''Αἰθίοψ, -πος (nom commun) (m)''' : Éthiopien.<br> '''Αἰμιλία, -ας (nom propre) (f)''' : Émilie.<br> '''Αἰμίλιος, -ίου (nom propre) (m)''' : Émile.<br> '''Αἰνέας, -ου (nom propre) (m)''' : Forme poétique de ''Αἰνείας''.<br> '''Αἰνείας, -ου (nom propre) (m)''' : Énée.<br> '''Αἰνειάς, -δος (nom propre) (f)''' : Énéide.<br> '''Αἰολίς, -δος (nom propre) (f)''' : Éolide.<br> '''Αἰολεύς, -έως (nom commun) (m)''' : Éolien.<br> '''Αἴολος, -όλου (nom propre) (m)''' : [[wikt:Éole|Éole]].<br> '''Αἴολος, -όλου (nom propre) (m)''' : Éole (fils d'Hellen).<br> '''Αἶσα, -ἴσης (nom commun) (f)''' : [[wikt:Ésa|Ésa]].<br> '''Αἰσχύλος, -ου (nom propre) (m)''' : Eschyle.<br> '''Αἴσωπος, -ώπου (nom propre) (m)''' : Ésope.<br> '''Αἴτνη, -ης (nom propre) (f)''' : Etna.<br> '''Αἰών, -ῶνου (nom propre) (m)''' : Éon.<br> '''Ἀκαδημία, -ας (nom propre) (f)''' : jardin d’Académos, près d’Athènes, où Platon enseignait.<br> '''Ἀκάδημος, -ήμου (nom propre) (m)''' : Académos.<br> '''Ἄκις, -εως (nom propre) (m)''' : Acis.<br> '''Ἀκταίων, -ος (nom propre) (m)''' : Actéon.<br> '''Ἀκτέων, -ος (nom propre) (m)''' : Forme poétique d’''Ἀκταίων''.<br> '''Ἄκτωρ, -ορος (nom propre) (m)''' : Actor (frère cadet d’Augias).<br> '''Ἀκκώ, -οῦς (nom propre) (f)''' : Aléria.<br> '''Ἀλαλίη, -ης (nom propre) (f)''' : Aléria.<br> '''Ἀλϐίων, -ος (nom propre) (m)''' : Albion.<br> '''Ἀλεξάνδρεια, -ίας (nom propre) (f)''' : Alexandrie.<br> '''Ἀλεξανδρέττα, -ας (nom commun) (f)''' : Alexandrine.<br> '''Ἀλεξανδρεύς, -έως (nom commun) (m)''' : Alexandrin.<br> '''Ἀλέξανδρος, -άνδρου (nom propre) (m)''' : Alexandre.<br> '''Ἀλέξανδρος ὁ Μέγας (nom propre) (m)''' : Alexandre le Grand.<br> '''Ἄλεξις, - (nom propre) (m)''' : Alexis.<br> '''Ἀληκτώ, -οῦς (nom propre) (f)''' : Alecto (une des Érynies).<br> '''Ἀλήτης, -ου (nom propre) (m)''' : Alétès.<br> '''Ἀλθαία, -ας (nom propre) (f)''' : Althée.<br> '''Ἀλιλάτ (nom propre) (f)''' : Al-Lat.<br> '''Ἀλκάθοος, -ου (prénom) (m)''' : Alcathoos.<br> '''Ἀλκείδης, ου (nom propre) (m)''' : Alcide (Premier nom d’Héraclès.).<br> '''Ἄλκης, -ους (nom propre) (m)''' : Alceste.<br> '''Ἄλκηστις, -ήστιδος (nom propre) (f)''' : Alceste.<br> '''Ἀλκιϐιάδης, ου (nom propre) (m)''' : Alcibiade.<br> '''Ἀλκίνοος, -ου (nom propre) (m)''' : Alcinoos.<br> '''Ἀλκμαίων, -ος (nom propre) (m)''' : Alcméon.<br> '''Ἀλκμήνη, -ης (nom propre) (f)''' : Alcmène.<br> '''Ἀλφιτώ, -οῦς (nom propre) (f)''' : Alphito.<br> '''Ἀλώπηξ, -εκος (nom propre) (f)''' : Vulpecula.<br> '''Ἀμϐρόσιος, -ίου (nom propre) (m)''': Ambroise.<br> '''Ἀμαζών, -όνος (nom propre) (f)''' : Amazone.<br> '''Ἀμένωφις, - (nom propre) (m)''': Aménophis.<br> '''Ἄμηστρις, -δος (nom propre) (f)''' : Amestris.<br> '''Ἀμαύνι (nom propre) (f)''' : Amemet.<br> '''Ἀμπρακία, -ας (nom propre) (f)''' : Ambracie.<br> '''Ἀμπρακιώτης, -ου (nom commun) (m)''' : Ambracien.<br> '''Ἀμπρακιῶτις, -ώτιδος (nom commun) (f)''' : Ambracienne.<br> '''Ἀμύντας, -ου (nom propre) (m)''' : Amyntas.<br> '''Ἀμφιμέδων, -οντος (nom propre) (m)''' : Amphimédon.<br> '''Ἀμφιστρεύς, -έως (nom propre) (m)''' : Amphitrée.<br> '''Ἀμφιτρίτη, -ης (nom propre) (f)''' : Amphitrite.<br> '''Ἀμφιτροπή, -ῆς (nom propre) (f)''' : Amphitropée.<br> '''Ἀμφιτρύων, -ωνος (nom propre) (m)''' : Amphitryon.<br> '''Ἀναξίϐια, -ας (nom propre) (f)''' : Anaxibie.<br> '''Ἀναξίϐιος, -ίου (nom propre) (m)''' : Anaxibios.<br> '''Ἀννίϐας, -ου (nom propre) (m)''' : Hannibal.<br> '''Ἀνδρέας, -ου (prénom) (m)''' : André.<br> '''Ἄννα, -ας (prénom) (f)''' : Anne.<br> '''Ἀνάγκη, -ης (nom propre) (f)''' : Ananké.<br> '''Ἀναῗτις, -ΐτεως (nom propre) (f)''' : Anaïs.<br> '''Ἀναξαγόρας, -ου (nom propre) (m)''' : Anaxagore.<br> '''Ἀναξίμανδρος, -ου (nom propre) (m)''' : Anaximandre.<br> '''Ἀναξιμήνης, -ου (nom propre) (m)''' : Anaximène.<br> '''Ἀναστασία, -ας (nom propre) (f)''' : Anastasie.<br> '''Ἀναστάσιος, -ίου (nom propre) (m)''' : Anastase.<br> '''Ἀνατόλιος, -ίου (nom propre) (m)''' : Anatole.<br> '''Ἄνουϐις, -ύϐιδος (nom propre) (m)''' : [[wikt:Anubis|Anubis]].<br> '''Ἄνουκις, -δος (nom propre) (f)''' : Anoukis.<br> '''Ἀντέρως, -τος (nom propre) (m)''' : [[wikt:Antéros|Antéros]].<br> '''Ἀντιγόνη, -ης (nom propre) (f)''' : Antigone.<br> '''Ἀντίκλεια, -ας (nom propre) (f)''' : Anticlée (mère d'Ulysse).<br> '''Ἀντικύθηρα, -ήρων (nom propre) (n)''' : Anticythère.<br> '''Ἀντίνοoς, -όου (nom propre) (m)''' : Antinoüs.<br> '''Ἀντίπολις, -όλεως (nom propre) (f)''' : Antipolis.<br> '''Ἀντισθένης, -ους (nom propre) (m)''' : Antisthène. (Philosophe né vers 444 av. J.-C. et décédé vers 365 av. J.-C.)<br> '''Ἄντων, -ου (nom propre) (m)''' : Anton.<br> '''Ἀξιός, -οῦ (nom propre) (m)''' : Axius.<br> '''Ἀπάτη, -ης (nom propre) (f)''' : Apaté.<br> '''Ἀπιδανός, -οῦ (nom propre) (m)''' : Apidanus.<br> '''Ἆπις, Ἄπιδος (nom propre)''' : Apis.<br> '''Ἀπολλόδωρος, -ώρου (nom propre) (m)''' : Apollodore.<br> '''Ἀπόλλων, -ωνος (nom propre) (m)''' : [[wikt:Apollon|Apollon]].<br> '''Ἀρά, -ᾶς (nom propre) (f)''' : [[wikt:Ara|Ara]].<br> '''Ἀραϐία, -ας (nom propre) (f)''' : Arabie.<br> '''Ἀράχνη, -ης (nom propre) (f)''' : Arachné.<br> '''Ἄραψ, -ϐος (nom commun) (m/f)''' : Arabe.<br> '''Ἀραράτ (nom propre) (m)''' : Ararat.<br> '''Ἀργαῖος, -ίου (nom propre) (m)''' : Argaïos.<br> '''Ἀργοναῦτης, -ύτου (nom commun) (m)''' : Argonaute.<br> '''Ἀργῷος, -ῴος, -ῷον (adjectif)''' : .<br> '''Ἀργώ, -οῦς (nom propre) (f)''' : Argo.<br> '''Ἀρετή, -ῆς (nom propre) (f)''' : Arété (déesse).<br> '''Ἄρευς, -εως (nom propre) (m)''' : Forme éolienne de ''Ἄρης''.<br> '''Ἄρης, -εως (nom propre) (m)''' : [[wikt:Arès|Arès]].<br> '''Ἀρήτη, -ης (nom propre) (f)''' : Arété (philosophe grecque de l'école des Cyrénaiques).<br> '''Ἀρίσταρχος, -άρχου (nom commun) (m)''' : Aristarque.<br> '''Ἀριστόϐουλος, -ύλου (nom propre) (m)''' : Aristobule.<br> '''Ἀριστογείτων, -ονος (nom propre) (m)''' : Aristogiton.<br> '''Ἀριστοτέλης, -ους (nom propre) (m)''' : Aristote.<br> '''Ἀριστώνυμος, -ύμου (nom propre) (m)''' : Aristonyme.<br> '''Ἀρίων, -ονος (nom propre) (m)''' : Arion.<br> '''Ἀρκαδία, -ας (nom propre) (f)''' : Arcadie.<br> '''Ἀρκάς, -δος (nom commun) (m/f)''' : Arcadien ; Arcadienne.<br> '''Ἀρκτοῦρος, -ύρου (nom propre) (m)''' : Arcturus.<br> '''Ἁρμαγεδών (nom propre) (m)''' : Armageddon.<br> '''Ἁρμόδιος, -ίου (nom propre) (m)''' : Harmodios.<br> '''Ἀρσένιος, -ίου (nom propre) (m)''' : Arsène.<br> '''Ἀρσινόη, -ης (nom propre) (f)''' : Arsinoé.<br> '''Ἀρταξέρξης, -ου (nom propre) (m)''' : Artaxerxès.<br> '''Ἄρτεμις, -έμιδος (nom propre) (f)''' : [[wikt:Artémis|Artémis]].<br> '''Ἀρχίας, -ου (nom propre) (m)''' : Archias.<br> '''Ἀρχιμήδης, -ους (nom propre) (m)''' : Archimède.<br> '''Ἀσάνα, -ας (nom propre) (f)''' : Forme dorienne de ''Ἀθηνᾶ''.<br> '''Ἀσδρούϐας, -ου (nom propre) (m)''' : Hasdrubal (véritable nom de Clitomaque de Carthage).<br> '''Ἀσήρ (nom propre) (m)''' : Aser.<br> '''Ἀσκαλωνίτης, -ου (nom commun) (m)''' : Ascalonite.<br> '''Ἀσκαλωνῖτις, -ίτιδος (nom commun) (f)''' : Ascalonite.<br> '''Ἀσκάλων, -ος (nom propre) (m)''' : Ascalon.<br> '''Ἀσκληπιός, -οῦ (nom propre) (m)''' : [[wikt:Asclépios|Asclépios]].<br> '''Ἀσμοδαῖος, -ίου (nom propre) (m)''' : Asmodée.<br> '''Ἀσεννέθ (nom propre) (m)''' : Asnath.<br> '''Ἀσπαθίνης, -ου (nom propre) (m)''' : Aspathinès.<br> '''Ἀσσυρία, -ας (nom propre) (f)''' : Assyrie.<br> '''Ἀσσύριος, -ίου (nom commun) (m)''' : Assyrien.<br> '''Ἀστάρτη, -ης (nom propre) (f)''' : Astarté.<br> '''Ἀστυάναξ, -κτος (nom propre) (m)''' : Astyanax.<br> '''Ἀστυάνασσα, -ας (nom propre) (f)''' : Astyanassa.<br> '''Ἄστυ, -εως (nom propre) (n)''' : Athènes.<br> '''Ἄτη, -ης (nom propre) (f)''' : [[wikt:Até|Até]]. (Déesse de l’égarement.)<br> '''Ἀττική, -ῆς (nom propre) (f)''' : Attique.<br> '''Ἀτλαντίς, -δος (nom propre) (f)''' : (Toponymie) océan Atlantique. (Mythologie) Atlantide.<br> '''Ἄτλας, -αντος (nom propre) (m)''' : Atlas.<br> '''Ἄτροπος, -όπου (nom propre) (f)''' : Atropos (troisième Moire).<br> '''Αὐγείας, -ου (nom propre) (m)''' : Augias.<br> '''Αὐλίς, -δος (nom propre) (f)''' : Aulis.<br> '''Αὐνάν (nom propre) (m)''' : Onan.<br> '''Αὐξώ, -οῦς (nom propre) (f)''' : Auxo.<br> '''Αὐσονία, -ας (nom propre) (f)''' : Italie.<br> '''Αὐσονίη, -ης (nom propre) (f)''' : Forme alternative de ''Αὐσονία''.<br> '''Αὔσων, -ονος (nom propre) (m)''' : Auson (fils d’Ulysse.)<br> '''Αὐτόλυκος, -ύκου (nom propre) (m)''' : Autolycos (Aïeul maternel d’Ulysse.)<br> '''Αὐτομέδων, -οντος (nom propre) (m)''' : Automédon (Conducteur du char d’Achille.)<br> '''Αὔως, -ω (nom propre) (f)''' : Forme alternative de ''Ἕως''.<br> '''Ἀφρική, -ῆς (nom propre) (f)''' : Afrique.<br> '''Ἀφροδίτη, -ης (nom propre) (f)''' : Aphrodite.<br> '''Ἀφρόδιτος, -ίτου (nom propre) (m)''' : Aphroditos.<br> '''Ἀφρώ, -οῦς (nom propre) (f)''' : Aphrô.<br> '''Ἀχαΐα, -ας (nom propre) (f)''' : Achaïe.<br> '''Ἀχαιμένης, -ους (nom propre) (m)''' : Achéménès.<br> '''Ἀχαιμενίδης, -ου (nom propre) (m)''' : Achéménide.<br> '''Ἀχαιός, -οῦ (nom propre) (m)''' : Achaïos (fils de Xouthos).<br> '''Ἀχατης, -ου (nom propre) (m)''' : Achatès (fleuve de Sicile).<br> '''Ἀχελῷος, -ῴου (nom propre) (m)''' : Achéloos.<br> '''Ἀχέρων, -οντος (nom propre) (m)''' : Achéron.<br> '''Ἀχιλλεύς, -έως (nom propre) (m)''' : Achille.<br> '''Ἀωσφόρος, -ου (nom propre) (m)''' : Forme dorienne de ''Ἑωσφόρος''.<br> ==Β== '''βαθμίς, -δος (nom commun) (f)''' : échelon.<br> '''βάθρον, -ου (nom commun) (n)''' : podium.<br> '''βαθέως (adverbe)''' : profondément.<br> '''βάθος, -ους (nom commun) (n)''' : Profondeur, hauteur.<br> '''βαθύς, -εῖα, -ύ (adjectif)''' : profond.<br> '''βαθύτατος, -άτη, -ύτατον (adjectif)''' : Superlatif de ''βαθύς''.<br> '''βαθύτερος, -έρα, -ύτερον (adjectif)''' : Comparatif de ''βαθύς''.<br> '''βαΐον, -ου (nom commun) (n)''' : rameau.<br> '''βακτηρία, -ας (nom commun) (f)''' : Bâton de marche ; bâton employé comme insigne de juge.<br> '''βαλανεῖον, -ίου (nom commun) (n)''' : bain (lieu public).<br> '''βαλανεύς, -έως (nom commun) (n)''' : plongeur.<br> '''βάλανος, -άνου (nom commun) (f)''' : Gland de chêne. (Botanique) Datte. Fermoir d’un collier. Pêne d’un verrou. Moule de mer (poisson). Noix, châtaigne. Suppositoire.<br> '''βαλάντιον, -ίου (nom commun) (n)''' : bourse (sac d'argent).<br> '''βαλλίζω (verbe)''' : danser.<br> '''βάμϐαξ, -κος (nom commun) (m)''' : coton.<br> '''βαμϐακερός, -ή, -όν (adjectif)''' : .<br> '''βαμϐακηρός, -ά, -όν (adjectif)''' : .<br> '''βαμϐάκινος, -ίνου (nom commun) (n)''' : .<br> '''βαμϐάκιον, -ίου (nom commun) (n)''' : .<br> '''βαμϐακοειδής, -ής, -ές (adjectif)''' : .<br> '''βανά, -ᾶς (nom commun) (f)''' : Forme béotienne de ''γυνή''.<br> '''βάπτω (verbe)''' : plonger, teindre ; baptiser.<br> '''βάρϐαρα, -ας (nom commun) (f)''' : barbare.<br> '''βάρϐαρικός, -ή, -όν (adjectif)''' : barbare.<br> '''βάρϐαρικῶς (adverbe)''' : barbarement.<br> '''βάρϐαρικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''βάρϐαρικός''.<br> '''βάρϐαρικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''βάρϐαρικός''.<br> '''βάρϐαρικώτατα, -, - (adverbe)''' : Superlatif de ''βάρϐαρικῶς''.<br> '''βάρϐαρικώτερον, -, - (adverbe)''' : Comparatif de ''βάρϐαρικῶς''.<br> '''βάρϐαρος, -άρου (nom commun) (m)''' : barbare.<br> '''βαρέως (adverbe)''' : lourdement.<br> '''βᾶρις, -άριδος (nom commun) (f)''' : barque.<br> '''βᾶρκις, -άρκιδος (nom commun) (f)''' : barque.<br> '''βαρύς, -εῖα, -ύ (adjectif)''' : lourd.<br> '''βαρύτατος, -άτη, -ύτατον (adjectif)''' : Superlatif de ''βαρύς''.<br> '''βαρύτερος, -έρα, -ύτερον (adjectif)''' : Comparatif de ''βαρύς''.<br> '''βασιλεία, -ας (nom commun) (f)''' : pouvoir royal ; royauté. Royaume.<br> '''βασίλεια, -ίας (nom commun) (f)''' : princesse. (héritière du souverain régnant)<br> '''βασιλείδης, -ου (nom commun) (m)''' : prince. (héritier du souverain régnant)<br> '''βασίλειος, -ία, -ιον (adjectif)''' : royal.<br> '''βασιλεύς, -έως (nom commun) (m)''' : roi.<br> '''βασιλήϊος, -, - (adjectif)''' : Forme ionienne de ''βασίλειος''.<br> '''βασιλῇος, -, - (adjectif)''' : Forme éolienne de ''βασίλειος''.<br> '''βασιλικός, -ή, -όν (adjectif)''' : royal.<br> '''βασίλισσα, -ας (nom commun) (f)''' : reine.<br> '''βάσις, -εως (nom commun) (f)''' : Action de marcher, marche. Organe pour la marche. Ce sur quoi l’on marche ou l’on se tient.<br> '''βάσκανος, -ος, -ον (adjectif)''' : Maléfique ; médisant.<br> '''βασκάνως (adverbe)''' : maléfiquement.<br> '''βασκανώτατος, -, - (adverbe)''' : Superlatif de ''βάσκανος''.<br> '''βασκανώτερος, -, - (adverbe)''' : Comparatif de ''βάσκανος''.<br> '''βασσάρα, -ας (nom commun) (f)''' : renard.<br> '''βαστάζω (verbe)''' : lever, soulever. Relever. Tenir dans ses bras ou ses mains.<br> '''βάτος, -ου (nom commun) (f)''' : Ronce, buisson. Épine.<br> '''βατός, -ή, -όν (adjectif)''' : accessible.<br> '''βάτραχος, -άχου (nom commun) (m/f)''' : Crapaud ; grenouille.<br> '''βατῶ (verbe)''' : Forme phocienne de ''πατῶ''.<br> '''βαυϐάω (verbe)''' : s’endormir.<br> '''βαυϐών, -ῶνος (nom commun) (m)''' : godemichet.<br> '''βαυϐώ, -οῦς (nom commun) (f)''' : nourrice.<br> '''βαυκάλημα, -ήματος (nom commun) (n)''' : berceuse.<br> '''βαυκίζομαι (verbe)''' : être prude.<br> '''βαυκός, -ή, -όν (adjectif)''' : prude.<br> '''βαυκότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''βαυκός''.<br> '''βαυκότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''βαυκός''.<br> '''βαυκῶς (adverbe)''' : prudemment.<br> '''βαυκώτατα, -, - (adverbe)''' : Superlatif de ''βαυκῶς''.<br> '''βαυκώτερον, -, - (adverbe)''' : Comparatif de ''βαυκῶς''.<br> '''βαφεύς, -έως (nom commun) (m)''' : peintre.<br> '''βδαλεύς, -έως (nom commun) (m)''' : suceur.<br> '''βδάλσις, - (nom commun) (f)''' : succion.<br> '''βδάλλω (verbe)''' : Sucer, téter. Traire le lait.<br> '''βδέλλα, -ης (nom commun) (f)''' : sangsue.<br> '''βδέω ‎(verbe)''' : péter (flatuler)<br> '''βεϐαιῶ (verbe)''' : garantir (se rendre garant de la valeur, de la qualité d’une chose).<br> '''βέϐηλος, -ος, -ον (adjectif)''' : Franchissable, profane. Impur, interdit.<br> '''βεϐηλότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''βέϐηλος''.<br> '''βεϐηλότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''βέϐηλος''.<br> '''βέϐηλως (adverbe)''' : profanement.<br> '''βεϐηλώτατα, -, - (adverbe)''' : Superlatif de ''βεϐρῶς''.<br> '''βεϐηλώτερον, -, - (adverbe)''' : Comparatif de ''βεϐρῶς''.<br> '''βεϐρός, -ά, -όν (adjectif)''' : stupide.<br> '''βεϐρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''βεϐρός''.<br> '''βεϐρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''βεϐρός''.<br> '''βεϐρῶς (adverbe)''' : stupidement.<br> '''βεϐρώτατα, -, - (adverbe)''' : Superlatif de ''βεϐρῶς''.<br> '''βεϐρώτερον, -, - (adverbe)''' : Comparatif de ''βεϐρῶς''.<br> '''βελόνη, -ης (nom commun) (f)''' : aiguille.<br> '''βέλος, -ους (nom commun) (n)''' : flèche.<br> '''βέλτιστος, -ίστη, -έλτιστον (adjectif)''' : Superlatif de ''ἀγαθός''.<br> '''βελτίων, -ων, -έλτιον (adjectif)''' : Comparatif de ''ἀγαθός''.<br> '''βένθος, -ους (nom commun) (n)''' : benthos.<br> '''βερϐέριον, -ίου (nom commun) (n)''' : .<br> '''βεῦδος, -ύδους (nom commun) (n)''' : .<br> '''βέφυρα, -ύρας (nom commun) (f)''' : Forme béotienne de ''γέφυρα ''.<br> '''βῆ βῆ (onomatopée)''' : bêlement.<br> '''βῆμα, -ήματος (nom commun) (n)''' : .<br> '''βήξ, -χός (nom commun) (m)''' : toux.<br> '''βήσσω (verbe)''' : tousser.<br> '''βῆτα (nom commun) (n)''' : bêta.<br> '''βήττω (verbe)''' : Forme attique ''βήσσω''.<br> '''βία, -ας (nom commun) (f)''' : Force, violence.<br> '''βιάζω (verbe)''' : Contraindre, forcer. (Au passif) Être contraint, forcé soumis.<br> '''βιϐάζω (verbe)''' : Faire aller ; exalter.<br> '''βιϐλαρίδιον, -ίου (nom commun) (n)''' : livret.<br> '''βιϐλιοθήκη, -ης (nom commun) (f)''' : bibliothèque.<br> '''βιϐλίον, -ου (nom commun) (n)''' : livre.<br> '''βιϐλιοπωλεῖον, -ίου (nom commun) (n)''' : librairie.<br> '''βιϐλιοπώλης, -ου (nom commun) (m)''' : libraire.<br> '''βίϐλος, -ου (nom commun) (f)''' : Papier fait à partir de l'écorce de papyrus.<br> '''βιϐρώσκω (verbe)''' : Dévorer, manger avec avidité. (Figuré) Dévorer ou engloutir (une fortune).<br> '''βίος, -ου (nom commun) (m)''' : vie.<br> '''βίωσις, -ώσεως (nom commun) (f)''' : manière de vie.<br> '''βινῶ (verbe)''' : foutre, baiser (avoir un rapport sexuel).<br> '''βιῶ (verbe)''' : être, vivre.<br> '''βλαδαρός, -ά, -όν (adjectif)''' : flasque.<br> '''βλαδύς, -εῖα, -ύ (adjectif)''' : faible.<br> '''βλαδυτής, -ῆτος (nom commun) (f)''' : faiblesse.<br> '''βλακότατα, -, - (adverbe)''' : Superlatif de ''βλακωδῶς''.<br> '''βλακότερον, -, - (adverbe)''' : Comparatif de ''βλακωδῶς''.<br> '''βλακωδῶς (adverbe)''' : stupidement.<br> '''βλακώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''βλάξ''.<br> '''βλακώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''βλάξ''.<br> '''βλαπτικός, -ή, -όν (adjectif)''' : .<br> '''βλαπτικῶς (adverbe)''' : -ment.<br> '''βλαπτικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''βλαπτικός''.<br> '''βλαπτικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''βλαπτικός''.<br> '''βλαπτικώτατα, -, - (adverbe)''' : Superlatif de ''βλαπτικῶς''.<br> '''βλαπτικώτερον, -, - (adverbe)''' : Comparatif de ''βλαπτικῶς''.<br> '''βλάπτω (verbe)''' : Léser, endommager. (Au passif) Éprouver un accident. Gêner, embarrasser. (En parlant de l’esprit) Troubler sa raison. (Postérieur) Faire du tort, nuire.<br> '''βλάξ, -κός (nom commun) (m/f)''' : stupide.<br> '''βλαισός, -ή, -όν (adjectif)''' : balbutiant.<br> '''βλέμμα, -τος (nom commun) (n)''' : Regard. (Au pluriel) Yeux.<br> '''βλεννογόνος, -ου (nom commun) (m)''' : muqueuse.<br> '''βλεννός, -οῦ (nom commun) (m)''' : mucus.<br> '''βλέπω (verbe)''' : voir.<br> '''βλεφαρίς, -δος (nom commun) (f)''' : cil.<br> '''βλεφαρῖτις, -ίτης (nom commun) (f)''' : blépharite.<br> '''βλέφαρον, -άρου (nom commun) (n)''' : paupière.<br> '''βλῆμα, -ήματος (nom commun) (n)''' : projectile.<br> '''βοή, -ῆς (nom commun) (f)''' : clameur.<br> '''βοήθεια, -ας (nom commun) (f)''' : aide.<br> '''βοηθός, -ός, -όν (adjectif)''' : aidant.<br> '''βοηθῶ (verbe)''' : aider.<br> '''βοιώτιος, -, - (adjectif)''' : béotien.<br> '''βόλλα, -ας (nom commun) (f)''' : Forme éolienne de ''βουλή''.<br> '''βορά, -ᾶς (nom commun) (f)''' : proie.<br> '''βόρειος, -ία, -ιον (adjectif)''' : septentrional.<br> '''βορειώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''βόρειος''.<br> '''βορειώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''βόρειος''.<br> '''βορειώτατα, -, - (adverbe)''' : Superlatif de ''βόρειως''.<br> '''βορειώτερον, -, - (adverbe)''' : Comparatif de ''βόρειως''.<br> '''βόρειως (adverbe)''' : septentrionalement.<br> '''βόμϐος, -ου (nom commun) (m)''' : bourdonnement.<br> '''βομϐυλιός, -οῦ (nom commun) (m)''' : .<br> '''βόμϐυξ, -κος (nom commun) (m)''' : ver à soie ; sorte de flûte.<br> '''βόρειος, -α, -ον (adjectif)''' : septentrional.<br> '''βορρᾶς, -ᾶ (nom commun) (m)''' : nord.<br> '''βόσκω (verbe)''' : Nourrir. Paître, se nourrir (en parlant des animaux)<br> '''βόστρυχος, -ύχου (nom commun) (m)''' : boucle de cheveux.<br> '''βοτάνη, -ης (nom commun) (f)''' : herbe.<br> '''βοτανηφάγος, -ος, -ον (adjectif)''' : herbivore.<br> '''βοτανηφόρος, -ος, -ον (adjectif)''' : enherbé.<br> '''βοτανίδιον, -ίου (nom commun) (n)''' .<br> '''βοτανίζω (verbe)''' : désherber.<br> '''βοτάνιον, -ίου (nom commun) (n)''' : .<br> '''βοτανικός, -ή, -όν (adjectif)''' : botanique.<br> '''βοτανισμός, -οῦ (nom commun) (m)''' : botanisme.<br> '''βοτανολογία ''' : botanologie.<br> '''βοτανολόγος ''' : herboriste.<br> '''βοτανολογῶ (verbe)''' : herboriser.<br> '''βοτανώδης, -ης, -ης (adjectif)''' : botanique.<br> '''βοτήρ, -ῆρος (nom commun) (m)''' : berger ; pasteur.<br> '''βοτόν, -οῦ (nom commun) (n)''' : bétail.<br> '''βουϐών, -ῶνος (nom commun) (m)''' : aine.<br> '''βουίζω (verbe)''' : bourdonner.<br> '''βουκολικός, -ή, -όν (adjectif)''' : pastoral.<br> '''βουκολικῶς (adverbe)''' : pastoralement.<br> '''βουκολικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''βουκολικικός''.<br> '''βουκολικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''βουκολικικός''.<br> '''βουκολικώτατα, -, - (adverbe)''' : Superlatif de ''βουκολικικῶς''.<br> '''βουκολικώτερον, -, - (adverbe)''' : Comparatif de ''βουκολικικῶς''.<br> '''βουκόλος, -ου (nom commun) (m)''' : bouvier.<br> '''βουλευτήριον, -ίου (nom commun) (n)''' : bouleutérion.<br> '''βουλή, -ῆς (nom commun) (f)''' : Volonté, vouloir. Décision, conseil. Sénat athénien.<br> '''βούλησις, -ήσεως (nom commun) (f)''' : volonté.<br> '''βούπρηστις, -ήστιδος (nom commun) (f)''' : bupreste.<br> '''βουνός, -οῦ (nom commun) (m)''' : mont, montagne.<br> '''βοῦς, -ός (nom commun) (m/f)''' : bœuf, vache.<br> '''βουστροφηδόν (adverbe)''' : En écrivant alternativement de gauche à droite, puis de droite à gauche.<br> '''βούτημα, -ήματος (nom commun) (n)''' : biscuit.<br> '''βούτυρον, -ύρου (nom commun) (n)''' : beurre.<br> '''βραδινός, -ή -όν (adjectif)''' : Forme éolienne de ''ῥαδινός''.<br> '''βραϐευτής, -οῦ (nom commun) (m)''' : arbitre.<br> '''βραδέως (adverbe)''' : lentement.<br> '''βραδύς, -εῖα, -ύ (adjectif)''' : lent.<br> '''βραδύτατος, -άτη, -ύτατον (adjectif)''' : Superlatif de ''βραδύς''.<br> '''βραδύτερος, -έρα, -ύτερον (adjectif)''' : Comparatif de ''βραδύς''.<br> '''βραδυτής, -ῆτος (nom commun) (f)''' : lenteur.<br> '''βράγος, -ους (nom commun) (n)''' : bas-fond.<br> '''βραχέως (adverbe)''' : courtement.<br> '''βράχος, -ου (nom commun) (m)''' : écueil.<br> '''βραχύς, -εῖα, -ύ (adjectif)''' : court.<br> '''βραχύτατος, -άτη, -ύτατον (adjectif)''' : Superlatif de ''βραχύς''.<br> '''βραχύτερος, -έρα, -ύτερον (adjectif)''' : Comparatif de ''βραχύς''.<br> '''βρέμω (verbe)''' : gronder, retentir.<br> '''βρένθος, -ου (nom commun) (m)''' : fierté.<br> '''βρέφος, -ους (nom commun) (n)''' : fœtus, nouveau-né.<br> '''βρεχμός, -οῦ (nom commun) (m)''' : .<br> '''βρία, -ης (nom commun) (f)''' : ville.<br> '''βρίμημα, -ήματος (nom commun) (n)''' : .<br> '''βρεττανικός, -ή, -όν (adjectif)''' : breton insulaire.<br> '''βρεττανικῶς (adverbe)''' : en breton insulaire.<br> '''βρεττανικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''βρεττανικός''.<br> '''βρεττανικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''βρεττανικός''.<br> '''βρεττανικώτατα, -, - (adverbe)''' : Superlatif de ''βρεττανικῶς''.<br> '''βρεττανικώτερον, -, - (adverbe)''' : Comparatif de ''βρεττανικῶς''.<br> '''βρόμος, -ου (nom commun) (m)''' : Frémissement, grondement. Pétillement du feu. Grondement du tonnerre.<br> '''βροντή, -ῆς (nom commun) (f)''' : Tonnerre. Stupeur.<br> '''βροχίς, -δος (nom commun) (f)''' : .<br> '''βρόχος, -ου (nom commun) (m)''' : nœud coulant.<br> '''βρυγμός, -οῦ (nom commun) (m)''' : bruxisme.<br> '''βρύον, -ου (nom commun) (n)''' : mousse (plante).<br> '''βρυχηθμός, -οῦ (nom commun) (m)''' : rugissement.<br> '''βρυχός, -οῦ (nom commun) (m)''' : brycose.<br> '''βρυχῶμαι (verbe)''' : rugir.<br> '''βύας, -ου (nom commun) (m)''' : hibou.<br> '''βύρσα, -ας (nom commun) (f)''' : outre, cuir.<br> '''βρώσιμος, -ος, -ον (adjectif)''' : mangeable.<br> '''βρῶσις, -ώσεως (nom commun) (f)''' outre, cuir.<br> '''βωϐός, -ή -όν (adjectif)''' : muet.<br> '''βωλά, -ᾶς (nom commun) (f)''' : Forme dorienne de ''βουλή''.<br> '''Βάαλ (nom propre) (m)''' : Baal.<br> '''Βαϐυλωνεύς, -έως (nom commun) (m)''' : Babylonien.<br> '''Βαϐυλωνία, -ας (nom commun) (f)''' : Babylonie.<br> '''Βαϐυλωνιακός, -ός, -όν (adjectif)''' : babylonien.<br> '''Βαϐυλώνιος, -ος, -ον (adjectif)''' : babylonien.<br> '''Βαϐυλωνίς, -δος (nom commun) (f)''' : Babylonienne.<br> '''Βαϐυλών, -ῶνος (nom propre) (f)''' : Babylone.<br> '''Βάκχος, -ου (nom propre) (m)''' : Bacchus. (Épithète de Dionysos, parfois de Zeus.)<br> '''Βαλλά, -ᾶς (nom propre) (f)''' : Bilha.<br> '''Βαρϐάρα, -ας (nom propre) (f)''' : Barbara.<br> '''Βαρϐαρικόν, -οῦ (nom propre) (m)''' : Barbaricum.<br> '''Βαρθολομαῖος, -ίου (nom propre) (m)''' : Barthélémy.<br> '''Βασίλειος, -ίου (nom propre) (m)''' : Basile.<br> '''Βαταυΐα, -ας (nom propre) (f)''' : Batavie.<br> '''Βατραχομυομαχία, -ας (nom propre) (f)''' : Bataille des grenouilles et des rats. (Parodie de l’''Iliade'' attribuée à un dénommé Pigrès d’Halicarnasse par Plutarque.)<br> '''Βάττος, -ου (nom propre) (m)''' : Battos.<br> '''Βαυϐώ, -οῦς (nom propre) (f)''' : Baubo.<br> '''Βαῦκος, -ύκου (nom propre) (m)''' : Baukos.<br> '''Βεελφεγώρ (nom propre) (m)''' : Belphégor.<br> '''Βενδῖς, -ίδος (nom propre) (f)''' : Bendis.<br> '''Βερενίκη, -ης (nom propre) (f)''' : Bérénice.<br> '''Βηθανία, -ας (nom propre) (f)''' : Béthanie.<br> '''Βηθλεέμ (nom propre) (f)''' : Bethléem.<br> '''Bηλησαμα, -ας (nom propre) (f)''' : Belisama.<br> '''Βῆλος, -ήλου (nom propre) (m)''' : Bel.<br> '''Βηρυτός, -οῦ (nom propre) (f)''' : Beyrouth.<br> '''Βία, -ας (nom propre) (m)''' : Bia.<br> '''Βλάσιος, -ίου (nom propre) (m)''' : Blaise.<br> '''Βλάχος, -ου (nom commun) (m)''' : Valaque.<br> '''Βοανεργές (nom propre) (m)''' : Boanergès.<br> '''Βοιωτία, -ας (nom propre) (f)''' : Béotie. (Région de Grèce centrale.)<br> '''Βοιωτός, -οῦ (nom commun) (m)''' : Béotien.<br> '''Βοιωτίς, -δος (nom commun) (f)''' : Béotienne.<br> '''Βορέας, -ου (nom propre) (m)''' : Borée. (dieu du vent du Nord)<br> '''Βορέης, -ου (nom propre) (m)''' : Forme ionienne de ''Βορέας''.<br> '''Βορρᾶς, -ᾶ (nom propre) (m)''' : Forme attique de ''Βορέας''.<br> '''Βοσπορίτης, -ου (nom commun) (m)''' : Bosphorite.<br> '''Βόσπορος, -όρου (nom propre) (m)''' : Bosphore.<br> '''Βούϐαστις, -άστιος (nom propre) (f)''' : Bastet.<br> '''Βουκέφαλος, -άλου (nom propre) (m)''' : Bucéphale (Cheval préféré d’Alexandre le Grand.)<br> '''Βουτώ, -οῦς (nom propre) (f)''' : Ouadjet.<br> '''Βρέννος, -ου (nom commun) (m)''' : Brennos.<br> '''Βρεττανία, -ας (nom propre) (f)''' : Bretagne (province romaine).<br> '''Βρεττανίς, -δος (nom commun) (f)''' : Bretonne insulaire.<br> '''Βρεττανός, -οῦ (nom commun) (m)''' : Breton insulaire.<br> '''Βύϐλος, -ου (nom commun) (f)''' : Byblos.<br> '''Βυζάντιον, -ίου (nom propre) (n)''' : Byzance.<br> '''Βύζας, -αντος (nom propre) (m)''' : Byzas.<br> '''Βιθυνία, -ας (nom propre) (f)''' : Bithynie.<br> '''Βιθυνίς, -δος (nom commun) (f)''' : Bithynienne.<br> '''Βιθυνός, -οῦ (nom commun) (o)''' : Bithynien.<br> ==Γ== '''γα (particule)''' : Forme dorienne et béotienne de ''γε''.<br> '''γαίω (verbe)''' : exulter, se réjouir.<br> '''γάλα, -κτος (nom commun) (n)''' : lait.<br> '''γαλανός, -ός, -όν (adjectif)''' : Forme dorienne de ''γαληνός''.<br> '''γαλήνη, -ης, -ης (nom commun) (f)''' : Calme de la mer. (Par extension) Calme, sérénité. Galène. Antidote contre les morsures de vipères.<br> '''γαληνός, -ός, -όν (adjectif)''' : calme (spécialement à propos de la mer).<br> '''γαλέη, -ης (nom commun) (f)''' : belette.<br> '''γαλῆ, -ς (nom commun) (f)''' : Forme alternative de ''γαλέη''.<br> '''γαλιῶ (verbe)''' : Être lascif comme une belette.<br> '''γάμμα (nom commun) (n)''' : gamma.<br> '''γαμέτης, -ου (nom commun) (m)''' : époux, mari.<br> '''γαμῶ (verbe)''' : se marier (quand on parle d’un homme)<br> '''γάργαλος, -άλου (nom commun) (m)''' : .<br> '''γαργαλίζω (verbe)''' : chatouiller.<br> '''γαργαλισμός, -οῦ (nom commun) (m)''' : chatouille.<br> '''γαργαρεών, -ῶνος (nom commun) (m)''' : luette.<br> '''γάρ (conjonction)''' : car ; en effet.<br> '''γαστήρ, -τρός (nom commun) (f)''' : ventre.<br> '''γαῦρος, -ύρη, -ῦρον (adjectif)''' : Exultant, joyeux. Hautain, dédaigneux.<br> '''γαυρότατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''γαῦρος''.<br> '''γαυρότερος, -έρα, -ερον (adjectif)''' : Comparatif de ''γαῦρος''.<br> '''γαῦρως (adverbe)''' : joyeusement ; hautainement, dédaigneusement.<br> '''γαυρότης, -τος (nom commun) (f)''' : Exultation. Emportement, férocité.<br> '''γε (particule)''' : (Devient ''γ’'' devant un mot commençant par une voyelle.) Marque une restriction, une affirmation, ou une conclusion.<br> '''γείτων, -ονος (nom commun) (m/f)''' : voisin(e).<br> '''γέλαιμι (verbe)''' : Forme éolienne de ''γελάω''.<br> '''γελάω (verbe)''' : Rire ; briller.<br> '''γελοῖος, -ία, -ῖον (adjectif)''' : ridicule ; risible.<br> '''γελοιότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''γελοῖος''.<br> '''γελοιότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''γελοῖος''.<br> '''γελοίως (adverbe)''' : ridiculement ; risiblement.<br> '''γελόω (verbe)''' : Forme homérique de ''γελάω''.<br> '''γέλως, -τος (nom commun) (m)''' : rire.<br> '''γελωτοποιός, -ός, -όν (adjectif)''' : comique.<br> '''γελωτοποιός, -οῦ (nom commun) (m)''' : Bouffon ; pitre.<br> '''γεμίζω (verbe)''' : emplir.<br> '''γέμισμα, -ίσματος (nom commun) (n)''' : emplissage.<br> '''γενεά, -ᾶς (nom commun) (f)''' : naissance, genre ; espèce.<br> '''γένεσις, -έσεως (nom commun) (f)''' : origine, source. Naissance. Création.<br> '''γενετήσιος, -α, -ον (adjectif)''' : sexuel.<br> '''γενετησιότατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''γενετήσιος''.<br> '''γενετησιότερος, -έρα, -ερον (adjectif)''' : Comparatif de ''γενετήσιος''.<br> '''γενετησίως (adverbe)''' : sexuellement.<br> '''γενναῖος, -ία, -ῖον (adjectif)''' : vaillant.<br> '''γενναιότατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''γενναῖος''.<br> '''γενναιότερος, -έρα, -ερον (adjectif)''' : Comparatif de ''γενναῖος''.<br> '''γενναίως (adverbe)''' : vaillamment.<br> '''γενναιότης, -ητος (nom commun) (f)''' : vaillance.<br> '''γεννητικός, -η, -ον (adjectif)''' : génital.<br> '''γένος, -ους (nom commun) (n)''' : naissance, origine, descendance ; race, genre, espèce ; classe, corporation; nation, peuple, tribu.<br> '''γεννῶ (verbe)''' : accoucher.<br> '''γερόντειος, -α, -ον (adjectif)''' : .<br> '''γεροντεύω (verbe)''' : .<br>'''γέρανος, -άνου (nom commun) (m/f)''' : grue (oiseau).<br> '''γερουσία, -ας (nom commun) (f)''' : sénat.<br> '''γερουσιάρχης, -ου (nom commun) (m)''' : président du sénat.<br> '''γερουσιαστής, -οῦ (nom commun) (m)''' : sénateur.<br> '''γέρων, -οντος (nom commun) (m)''' : vieillard.<br> '''γεῦμα, -ύματος (nom commun) (n)''' : déjeuner.<br> '''γεῦσις, -ύσεως (nom commun) (f)''' : goût.<br> '''γεύω (verbe)''' : goûter.<br> '''γέφυρα, -ύρας (nom commun) (f)''' : Chaussée. Pont.<br> '''γεω- (préfixe)''' : relatif à la terre.<br> '''γῆ, -ς (nom commun) (f)''' : terre.<br> '''γήινος, -η, -ο (adjectif)''' : terrestre.<br> '''γήρανσις, -άνσεως (nom commun) (f)''' : .<br> '''γηράσκω (verbe)''' : .<br> '''γῆρας, -ήρως (nom commun) (n)''' : vieillesse.<br> '''γῆρυς, -ήρυος (nom commun) (f)''' : Voix ; discours.<br> '''γηρύω (verbe)''' : chanter.<br> '''γιγαντιαῖος, -ία, -ῖον (adjectif)''' : gigantesque.<br> '''γιγαντιότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''γιγαντιαῖος''.<br> '''γιγαντιότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''γιγαντιαῖος''.<br> '''γιγαντίως (adverbe)''' : gigantesquement.<br> ''', -, - (adverbe)''' : Superlatif de ''γιγαντίως''.<br> ''', -, - (adverbe)''' : Comparatif de ''γιγαντίως''.<br> '''γίγας, -αντος (nom commun) (m)''' : géant.<br> '''γίγνομαι (verbe)''' : engendrer.<br> '''γίνιουμαι (verbe)''' : Forme béotienne de ''γίγνομαι''.<br> '''γίνομαι (verbe)''' : Forme ionienne de ''γίγνομαι''.<br> '''γίνυμαι (verbe)''' : Forme thessalienne de ''γίγνομαι''.<br> '''γιγνώσκω (verbe)''' : Apprendre à connaître.<br> '''γινώσκω (verbe)''' : Forme ionienne de ''γιγνώσκω''.<br> '''γλάγος, -ους (nom commun) (n)''' : Forme poétique de ''γάλα''.<br> '''γλάσσα, -ης (nom commun) (f)''' : Forme ionienne de ''γλῶσσα''.<br> '''γλαυκός, -ή, -όν (adjectif)''' : Brillant, étincelant, éclatant. D’un vert pâle ou gris.<br> '''γλαυκότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''γλαυκός''.<br> '''γλαυκότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''γλαυκός''.<br> '''γλαυκῶς (adverbe)''' : vivement.<br> '''γλαυκώτατα, -, - (adverbe)''' : Superlatif de ''γλαυκῶς''.<br> '''γλαυκώτερον, -, - (adverbe)''' : Comparatif de ''γλαυκῶς''.<br> '''γλαῦξ, -κός (nom commun) (f)''' : chouette.<br> '''γλαύσσω (verbe)''' : briller (En parlant des yeux).<br> '''γλεῦκος, -ύκους (nom commun) (n)''' : moût.<br> '''γλέφαρον, -άρου (nom commun) (n)''' : Forme dorienne de ''βλέφαρον''.<br> '''γλήνη, -ης (nom commun) (f)''' : pupille (partie de l’œil).<br> '''γλῆνος, -ήνους (nom commun) (n)''' : splendeur.<br> '''γλουτιαῖος, -ία, -αῖν (adjectif)''' : glutéal.<br> '''γλουτός, -οῦ (nom commun) (m)''' : derrière ; fesse.<br> '''γλυκέως (adverbe)''' : doucement.<br> '''γλυκερός, -ή, -όν (adjectif)''' : doux.<br> '''γλυκερῶς (adverbe)''' : doucement.<br> '''γλυκύς, -εῖα, -ύ (adjectif)''' : doux, sucré.<br> '''γλυκύτατος, -άτη, -ύτατον (adjectif)''' : Superlatif de ''γλυκύς''.<br> '''γλυκύτερος, -έρα, -ύτερον (adjectif)''' : Comparatif de ''γλυκύς''.<br> '''γλυκώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''γλυκερός''.<br> '''γλυκώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''γλυκερός''.<br> '''γλυπτόν, -οῦ (nom commun) (n)''' : .<br> '''γλώνη, -ης (nom commun) (f)''' : poupée.<br> '''γλῶσσα, -ώσσης (nom commun) (f)''' : langue. (Organe buccal ; expression orale)<br> '''γλωσσίς, -δος (nom commun) (f)''' : glotte.<br> '''γλῶττα, -ώττης (nom commun) (f)''' : Forme attique de ''γλῶσσα''.<br> '''γλωττίς, -δος (nom commun) (f)''' : Forme attique de ''γλωσσίς''.<br> '''γνάθος, -ου (nom commun) (f)''' : mâchoire.<br> '''γνήσιος, -α, -ον (adjectif)''' : véritable.<br> '''γνῶσις, -ώσεως (nom commun) (f)''' : Savoir ; connaissance, notion. Reconnaissance ; enquête, instruction judiciaire.<br> '''γοάω (verbe)''' : se lamenter.<br> '''γόγγρος, -ου (nom commun) (m)''' : congre.<br> '''γόησσα, -ας (nom commun) (f)''' : enchanteresse ; magicienne.<br> '''γόης, -τος (nom commun) (m)''' : enchanteur ; magicien.<br> '''γονεύς, -έως (nom commun) (m)''' : père (parent).<br> '''γονή, -ῆς (nom commun) (f)''' : génération ; procréation.<br> '''γονόρροια, -ας (nom commun) (f)''' : gonorrhée.<br> '''γόνος, -ου (nom commun) (m)''' : procréation.<br> '''γόνυ, -ατος (nom commun) (n)''' : genou.<br> '''γόος, -ου (nom commun) (m)''' : lamentation.<br> '''γοργός, -ή, -όν (adjectif)''' : terrible.<br> '''γούνα, -ας (nom commun) (f)''' : .<br> '''γοῦνος, -ύνου (nom commun) (m)''' : Forme ionienne de ''γόνος''.<br> '''γοῶ (verbe)''' : enchanter, ensorceler.<br> '''γράθμα, -τος (nom commun) (n)''' : Forme dorienne de ''γράμμα''.<br> '''γραῖα, -ίας (nom commun) (f)''' : vieillarde.<br> '''γραμματεύς, -έως (nom commun) (m)''' : scribe.<br> '''γράμμα, -τος (nom commun) (n)''' : Caractère gravé. Signes divers. Traits d’un dessin ou d’une peinture.<br> '''γραπτός, -ή, -όν (adjectif)''' : écrit.<br> '''γραπτότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''γραπτός''.<br> '''γραπτότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''γραπτός''.<br> '''γραπτῶς (adverbe)''' : .<br> '''γραῦς, -ός (nom commun) (f)''' : vieillarde.<br> '''γραφεύς, -έως (nom commun) (m)''' : peintre.<br> '''γραφή, -ῆς (nom commun) (f)''' : peinture.<br> '''γραφία, -ας (nom commun) (f)''' : écriture.<br> '''-γραφία, -ας (suffixe)''' : relatif à l’écriture.<br> '''γραφικός, -ή, -όν (adjectif)''' : peint.<br> '''γραφικῶς (adverbe)''' : graphiquement.<br> '''γραφικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''γραφικός''.<br> '''γραφικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''γραφικός''.<br> '''γραφίς, -δος (nom commun) (f)''' : .<br> '''γράφω (verbe)''' : écrire.<br> '''γρηγοράς, -δος (nom commun) (f)''' : vivacité.<br> '''γρήγορος, -η, -ον (adjectif)''' : vif.<br> '''γρηγόρως (adverbe)''' : vivement.<br> '''γρηγορώτατα, -, - (adverbe)''' : Superlatif de ''γρηγόρως''.<br> '''γρηγορώτερον, -, - (adverbe)''' : Comparatif de ''γρηγόρως''.<br> '''γρηγορώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''γρήγορος''.<br> '''γρηγορώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''γρήγορος''.<br> '''γρῖφος, -ίφου (nom commun) (m)''' : filet ; énigme.<br> '''γρόνθος, -ου (nom commun) (m)''' : poing.<br> '''γρύλλος, -ου (nom commun) (m)''' : grillon.<br> '''γρύψ, -πός (nom commun) (m)''' : griffon.<br> '''γυμνάζω (verbe)''' : entraîner (diriger l’exercice sportif).<br> '''γυμνάσιον, -ίου (nom commun) (n)''' : Lieu public réservé aux exercices corporels.<br> '''γυμνός, -ή, -όν (adjectif)''' : Nu ; légèrement vêtu.<br> '''γυμνότατα, -, - (adverbe)''' : Superlatif de ''γυμνῶς''.<br> '''γυμνότερον, -, - (adverbe)''' : Comparatif de ''γυμνῶς''.<br> '''γυμνότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''γυμνός''.<br> '''γυμνότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''γυμνός''.<br> '''γυμνότης, -τος (nom commun) (f)''' : nudité.<br> '''γύμνωσις, -ώσεως (nom commun) (f)''' : dénudage.<br> '''γυμνῶς (adverbe)''' : .<br> '''γυμνῶ (verbe)''' : dénuder.<br> '''γυνά, -ᾶς (nom commun) (f)''' : Forme dorienne de ''γυνή''.<br> '''γυναικᾶς, - (nom commun) (m)''' : homme à femmes.<br> '''γυναικεῖον, -ίου (nom commun) (n)''' : Appartement réservé aux femmes.<br> '''γυναικεῖος, -ία, -ῖον (adjectif)''' : féminin.<br> '''γυναικειότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''γυναικεῖος''.<br> '''γυναικειότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''γυναικεῖος''.<br> '''γυναικείως (adverbe)''' : fémininement.<br> '''γυναικομανία, -ας (nom commun) (f)''' : gynécomanie.<br> '''γυνή, -αικός (nom commun) (f)''' : Femme, épouse ; femelle des animaux.<br> '''γυρῖνος, -ίνου (nom commun) (m)''' : têtard.<br> '''γῦρος, -ύρου (nom commun) (m)''' : Anneau ; cercle.<br> '''γυρός, -οῦ (nom commun) (m)''' : rond.<br> '''γύψ, -πος (nom commun) (m)''' : vautour.<br> '''γωνία, -ας (nom commun) (f)''' : Angle ; coin.<br> '''γωρυτός, -οῦ (nom commun) (m)''' : carquois.<br> '''Γαϐριήλ (nom propre) (m)''' : Gabriel.<br> '''Γάζα, -ης (nom commun) (f)''' : Gaza.<br> '''Γαῖα, -ίας (nom propre) (f)''' : [[wikt:Gaïa|Gaïa]].<br> '''Γαῖη, -ίης (nom propre) (f)''' : Forme ionienne de ''Γαῖα''.<br> '''Γαλινθιάς, -δος (nom propre) (f)''' : Galanthis.<br> '''Γαλάτεια, -ίας (nom propre) (f)''' : Galatée (Néréide).<br> '''Γαλατεία, -ας (nom propre) (f)''' : Galatée.<br> '''Γαλάτης, -ου (nom commun) (m)''' : Galate.<br> '''Γαλατία, -ας (nom propre) (f)''' : Galatie.<br> '''Γαλλία, -ας (nom propre) (f)''' : Gaule.<br> '''Γανυμήδης, -ου (nom propre) (m)''' : Ganymède.<br> '''Γεδεών, -ος (nom propre) (m)''' : Gédéon.<br> '''Γελλώ, -οῦς (nom propre) (f)''' : Gello.<br> '''Γέλων, -ος (nom propre) (m)''' : Gélon.<br> '''Γεννησαρέτ (nom propre) (f)''' : Gennésaret.<br> '''Γερμανία, -ας (nom propre) (f)''' : Allemagne.<br> '''Γερμανίς, -δος (nom commun) (f)''' : Allemande.<br> '''Γερμανός, -οῦ (nom commun) (m)''' : Allemand.<br> '''Γέτης, -ου (nom commun) (m)''' : Gète.<br> '''Γεώργιος, -ίου (prénom) (m)''' : Georges.<br> '''Γῆρας, -ήρως (nom propre) (m)''' : Géras.<br> '''Γηρυόνης, -ου (nom propre) (m)''' : Forme alternative de ''Γηρυών''.<br> '''Γηρυών, -όνος (nom propre) (m)''' : Géryon.<br> '''Γῆ, -ς (nom propre) (f)''' : Terre.<br> '''Γλαῦκος, -ύκου (nom propre) (m)''' : Glaucos.<br> '''Γοργώ, -όνος (nom propre) (f)''' : Gorgone.<br> '''Γότθος, -ου (nom commun) (m)''' : Goth.<br> '''Γοῦτος, -ύτου (nom commun) (m)''' : Geat.<br> '''Γραῖα, -ίας (nom propre) (f)''' : Grée.<br> '''Γρηγόριος, -ίου (nom propre) (m)''' : Grégoire.<br> '''Γύγης, -ου (nom propre) (m)''' : Gygès.<br> '''Γύθειον, -ίου (nom propre) (n)''' : Gythio.<br> '''Γύθιον, -ίου (nom propre) (n)''' : Forme alternative de ''Γύθειον''.<br> ==Δ== '''δάγυς, -ύδος (nom commun) (f)''' : dagyde.<br> '''δαήρ, -έρος (nom commun) (m)''' : beau-frère.<br> '''δαιμόνιος, -ία, -όνιον (adjectif)''' : étrange.<br> '''δαιμόνιον, -ίου (nom commun) (n)''' : génie (être merveilleux).<br> '''δαιμονίως (adverbe)''' : étrangement.<br> '''δαιμονίοτατα, -, - (adverbe)''' : Superlatif de ''δαιμονίως''.<br> '''δαιμονίοτερον, -, - (adverbe)''' : Comparatif de ''δαιμονίως''.<br> '''δαιμονιώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''δαιμόνιος''.<br> '''δαιμονιώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''δαιμόνιος''.<br> '''δαίμων, -ονος (nom commun) (m)''' : divinité.<br> '''δακκύλιος, -υλίου (nom commun) (m)''' : Forme béotienne de ''δάκτυλος''.<br> '''δάκνω (verbe)''' : mordre.<br> '''δάκος, -ους (nom commun) (n)''' : .<br> '''δάκρυ, -ύου (nom commun) (n)''' : larme.<br> '''δακτύλιον, -ίου (nom commun) (n)''' : anneau.<br> '''δάκτυλος, -ύλου (nom commun) (m)''' : doigt.<br> '''δάλτος, -ου (nom commun) (f)''' : Forme chypriote de ''δέλτος''.<br> '''δαμάζω (dompter)''' : domestiquer ; dompter.<br> '''δάμαλις, -άλεως (nom commun) (f)''' : génisse.<br> '''δαμοκρατία, -ας (nom commun) (f)''' : Forme dorienne de ''δημοκρατία''.<br> '''δᾶμος, -άμου (nom commun) (m)''' : Forme dorienne de ''δῆμος''.<br> '''δάνειον, -ίου (nom commun) (n)''' : prêt.<br> '''δάνος, -ου (nom commun) (m)''' : Forme macédonienne de ''θάνατος''.<br> '''δαρθάνω (verbe)''' : s’endormir.<br> '''δάσος, -ους (nom commun) (n)''' : bois (lieu), forêt.<br> '''δασύνω (verbe)''' : .<br> '''δασύς, -εῖα, -ύ (adjectif)''' : Velu, poilu. feuillu ; boisé.<br> '''δασύτης, -τος (nom commun) (f)''' : pilosité.<br> '''δαῦκον, -ύκου (nom commun) (n)''' : carotte ou navet utilisé en médecine.<br> '''δεῖγμα, -ίγματος (nom commun) (f)''' : échantillon.<br> '''δείδω (verbe)''' : avoir peur.<br> '''δείκτης, -ου (nom commun) (m)''' : index.<br> '''δεινός, -ή, -όν (adjectif)''' : terrible.<br> '''δέ (particule)''' : mais, puis, d’autre part, donc.<br> '''δέκα (adjectif numéral)''' : dix.<br> '''δεκαετία, -ας (nom commun) (f)''' : décennie.<br> '''δεκάς, -δος (nom commun) (f)''' : dizaine.<br> '''δέκομαι (verbe)''' : Forme éolienne et ionienne de ''δέχομαι''.<br> '''δελεάζω (verbe)''' : appâter.<br> '''δέλεαρ, -τος (nom commun) (n)''' : appât.<br> '''δέλτα (nom commun) (n)''' : delta.<br> '''δέλτος, -ου (nom commun) (f)''' : tablette d’écriture.<br> '''δέλφαξ, -κος (nom commun) (f)''' : .<br> '''δελφίς, -ῖνος (nom commun) (m)''' : dauphin.<br> '''δελφύς, -ος (nom commun) (f)''' : matrice.<br> '''δέμω (verbe)''' : construire.<br> '''δενδρολίϐανον, -άνου (nom commun) (n)''' : romarin.<br> '''δένδρον, -ου (nom commun) (n)''' : arbre.<br> '''δένδρεον, -ου (nom commun) (n)''' : Forme homérique de ''δένδρον''.<br> '''δεξιτερός, -ή, -όν (adjectif)''' : Forme de ''δεξιός''.<br> '''δεξιός, -ά, -όν (adjectif)''' : qui est à droite, placé à droite. (Par suite) De bon augure, favorable. Qui a de la dextérité, adroit, industrieux, habile.<br> '''δέος, -ους (nom commun) (n)''' : effroi, peur.<br> '''δέρας, -ατος (nom commun) (n)''' : peau, cuir.<br> '''δέρκομαι (verbe)''' : voir clair.<br> '''δέρμα, -τος (nom commun) (n)''' : peau.<br> '''δέρω (verbe)''' : écorcher.<br> '''δέσμευσις, -ύσεως (nom commun) (f)''' : lien.<br> '''δεσμεύω (verbe)''' : lier.<br> '''δέσμη, -ης (nom commun) (f)''' : bouquet, faisceau, liasse. '''δεσμός, -οῦ (nom commun) (m)''' : Lien (corde, câble, amarre, courroie, nœud). (Par extension) Clou. (D’ordinaire au pluriel) Liens, chaînes, fers. (Par suite) Emprisonnement, prison. (En général) Captivité. (Figuré) Liens d’amitié.<br> '''δέσποινα, -ίνης (nom commun) (f)''' : maîtresse d’une maisonnée.<br> '''δεσπότης, -ου (nom commun) (m)''' : maître d’une maisonnée ; maître d’un dème.<br> '''δεῦμα, -ύματος (nom commun) (n)''' : chair cuite.<br> '''δεῦρο (adverbe)''' : ici (avec mouvement).<br> '''δευτεραγωνιστής, -οῦ (nom commun) (m)''' : deutéragoniste.<br> '''δεύτερος, -α, -ον (adjectif)''' : deuxième.<br> '''δευτήρ, -ῆρος (nom commun) (m)''' : chaudron.<br> '''δεύω (verbe)''' : mouiller.<br> '''δέφυρα, -ύρας (nom commun) (f)''' : Forme crétoise de ''γέφυρα''.<br> '''δέχομαι (verbe)''' : Accepter, admettre, agréer. Accueillir, recevoir, recueillir, adopter. Prendre, revêtir, comporter.<br> '''δή (particule)''' : vraiment, assurément.<br> '''δῆγμα, -ήγματος (nom commun) (m)''' : morsure.<br> '''δηκτήριος, -ος, -ον (adjectif)''' : mordant.<br> '''δηλητήρ, -ρός (nom commun) (m)''' : destructeur.<br> '''δηλοῦμαι (verbe)''' : détruire.<br> '''δήλωσις, -ώσεως (nom commun) (f)''' : déclaration.<br> '''δηλῶ (verbe)''' : déclarer.<br> '''δημοκρατία, -ας (nom commun) (f)''' : république.<br> '''δημόσιος, -ία, -όσιον (adjectif)''' : public.<br> '''δημοσίως (adverbe)''' : publiquement.<br> '''δημοσιώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''δημόσιος''.<br> '''δημοσιώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''δημόσιος''.<br> '''δῆμος, -ήμου (nom commun) (m)''' : contrée, pays, terre.<br> '''δημότης, -ου (nom commun) (m)''' : concitoyen.<br>‎ '''δημοτικός, -ή, -όν (adjectif)''' : commun.<br> '''δημοτικῶς (adverbe)''' : communément.<br> '''δημοτικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''δημοτικός''.<br> '''δημοτικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''δημοτικός''.<br> '''δημοτικώτατα, -, - (adverbe)''' : Superlatif de ''δημοτικῶς''.<br> '''δημοτικώτερον, -, - (adverbe)''' : Comparatif de ''δημοτικῶς''.<br> '''δημωδέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''δημώδης''.<br> '''δημωδέστερος, -έρα, -έστερον (adjectif)''' : Comparatif de ''δημώδης''.<br> '''δημώδης, -ης, -ες (adjectif)''' : vernaculaire.<br> '''δημωδῶς (adverbe)''' : vernaculairement.<br> '''δήν (particule)''' : il y a longtemps.<br> '''δηρός, -ά, -όν (adjectif)''' : .<br> '''διά (adverbe ; préposition)''' : .<br> '''διαϐεϐαιῶ (verbe)''' : garantir (se rendre garant de l’existence de la réalité d’une chose).<br> '''διαϐιϐάζω (verbe)''' : lire.<br> '''διαϐιϐρώσκω (verbe)''' : .<br> '''διάϐολος, -ου (masculin) (m)''' : calomniateur ; diable.<br> '''διαϐολικός, -ή, -όν (adjectif)''' : du diable.<br> '''διαϐολικῶς (adverbe)''' : diaboliquement.<br> '''διαϐολικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''διαϐολικός''.<br> '''διαϐολικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''διαϐολικός''.<br> '''διάγνωσις, -ώσεως (nom commun) (f)''' : .<br> '''διάδημα, -ήματος (nom commun) (n)''' : diadème.<br> '''διαδῶ (verbe)''' : .<br> '''διάζωμα, -ώματος (nom commun) (n)''' : caleçon.<br> '''διάθεσις, -έσεως (nom commun) (f)''' : disposition.<br> '''διαθήκη, -ης (nom commun) (f)''' : testament, volonté (document écrit). Testament (livre religieux)<br> '''διαίρεσις, -έσεως (nom commun) (f)''' : division.<br> '''διαίσθησις, -ήσεως (nom commun) (f)''' : intuition.<br> '''διαισθητικός, -ή, -όν (adjectif)''' : intuitif.<br> '''διαισθητικῶς (adverbe)''' : intuitivement.<br> '''διαιτητής, -οῦ (nom commun) (m)''' : arbitre.<br> '''διακινῶ (verbe)''' : .<br> '''διάκονος, -όνου (nom commun) (m/f)''' : Serviteur, servante.<br> '''διακοπή, -ῆς (nom commun) (f)''' : interruption.<br> '''διακόπτω (verbe)''' : interrompre.<br> '''διακορεύω (verbe)''' : déflorer.<br> '''διακόρησις, -ήσεως (nom commun) (f)''' : défloration.<br> '''διάκρισις, -ίσεως (nom commun) (f)''' : discrétion ; distinction.<br> '''διακριτικός, -ή, -όν (adjectif)''' : discret ; distinct.<br> '''διακριτικότατα, -, - (adverbe)''' : Superlatif de ''διακριτικῶς''.<br> '''διακριτικότερον, -, - (adverbe)''' : Comparatif de ''διακριτικῶς''.<br> '''διακριτικότατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''διακριτικός''.<br> '''διακριτικότερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''διακριτικός''.<br> '''διακριτικῶς (adverbe)''' : discrètement ; distinctement.<br> '''διάλεξις, -έξεως (nom commun) (f)''' : exposé.<br> '''διαλέγομαι (verbe)''' : discuter.<br> '''διάλεκτος, -έκτου (nom commun) (f)''' : discussion ; dialecte.<br> '''διαλλάττω (verbe)''' : transiger.<br> '''διάλογος, -όγου (nom commun) (m)''' : dialogue.<br> '''διαμαστίγωσις, -ώσεως (nom commun) (f)''' : .<br> '''διαμαστιγῶ (verbe)''' : .<br> '''διανόησις, -ήσεως (nom commun) (f)''' : pensée.<br> '''διανοῶ (verbe)''' : penser.<br> '''διαπραγμάτευσις, -ύσεως (nom commun) (f)''' : négociation.<br> '''διαπραγματεύομαι (verbe)''' : négocier.<br> '''διαρρήγνυμι (verbe)''' : cambrioler.<br> '''διαρρήκτης, -ου (nom commun) (m)''' : cambrioleur.<br> '''διάρρηξις, -ήξεως (nom commun) (m)''' : cambriolage.<br> '''διάρροια, -ας (nom commun) (f)''' : diarrhée.<br> '''διάσεισις, -ίσεως (nom commun) (f)''' : commotion.<br> '''διασείω (verbe)''' : .<br> '''διασκέδασις, -άσεως (nom commun) (f)''' : divertissement.<br> '''διάστασις, -άσεως (nom commun) (f)''' : dimension.<br> '''διαστέλλω (verbe)''' : Répandre, séparer. Distinguer, déterminer.<br> '''διάστημα, -ήματος (nom commun) (n)''' : espace.<br> '''διαστολή, -ῆς (nom commun) (f)''' : Élargissement, expansion, dilatation. Petite coche ou fente.<br> (Figuré) Distinction.<br> '''διάστρεμμα, -έμματος (nom commun) (n)''' : entorse.<br> '''διαστρέφω (verbe)''' : disposer.<br> '''διατίθημι (verbe)''' : disposer.<br> '''διατριϐή, -ῆς (nom commun) (f)''' : conversation (philosophique).<br> '''διαφθείρω (verbe)''' : corrompre.<br> '''διαφθορά, -ᾶς (nom commun) (f)''' : corruption.<br> '''διαφθορεῖον, -ίου (nom commun) (n)''' : .<br> '''διαφθορεύς, -έως (nom commun) (m)''' : .<br> '''διαχειριστής, -οῦ (masculin) (m)''' : gestionnaire.<br> '''διαχείρισις, -ίσεως (nom commun) (f)''' : gestion.<br> '''διαχειριστικός, -ή, -όν (adjectif)''' : .<br> '''διαχειριστικῶς (adverbe)''' : -ment.<br> '''διαχειριστικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''διαχειριστικός''.<br> '''διαχειριστικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''διαχειριστικός''.<br> '''διαχειριστικώτατα, -, - (adverbe)''' : Superlatif de ''διαχειριστικῶς''.<br> '''διαχειριστικώτερον, -, - (adverbe)''' : Comparatif de ''διαχειριστικῶς''.<br> '''διδάσκαλος, -άλου (nom commun) (m)''' : instituteur.<br> '''διδάσκω (verbe)''' : enseigner, instruire ; entraîner.<br> '''διαφέρω (verbe)''' : différer.<br> '''διαφορά, -ᾶς (nom commun) (f)''' : différence.<br> '''διαφορετικός, -ή, -όν (adjectif)''' : différent.<br> '''διαφορετικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''διαφορετικός''.<br> '''διαφορετικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''διαφορετικός''.<br> '''διαφορετικώτατα, -, - (adverbe)''' : Superlatif de ''διαφορετικῶς''.<br> '''διαφορετικώτερον, -, - (adverbe)''' : Comparatif de ''διαφορετικῶς''.<br> '''δίδυμος, -ος, -ον (adjectif)''' : double ; jumeau.<br> '''δίδωμι (verbe)''' : donner.<br> '''διείσδυσις, -ύσεως (nom commun) (f)''' : pénétration.<br> '''διεισδύω (verbe)''' : pénétrer.<br> '''διεύθυνσις, -ύνσεως (nom commun) (f)''' : direction.<br> '''διευθύνων, -ουσα, -ον (adjectif)''' : directeur.<br> '''διευθυντής, -οῦ (nom commun) (m)''' : directeur.<br> '''διευθύνω (verbe)''' : diriger.<br> '''διθύραμϐος, -άμϐου (nom commun) (m)''' : dithyrambe.<br> '''διήγημα, -ήματος (nom commun) (n)''' : conte.<br> '''διήγησις, -ήσεως (nom commun) (f)''' : narration.<br> '''διηγοῦμαι (verbe)''' : narrer.<br> '''διήκονος, -όνου (nom commun) (m/f)''' : Forme ionienne de ''διάκονος''.<br> '''διίσταμαι (verbe)''' : .<br> '''διίστημι (verbe)''' : .<br> '''δικάζω (verbe)''' : juger.<br> '''δικαίωμα, -ώματος (nom commun) (n)''' : (Droit) Jugement. Justification. Décret.<br> '''δικαιῶ (verbe)''' : rendre juste.<br> '''δικαστήριον, -ίου (nom commun) (n)''' : tribunal.<br> '''δικαστής, -οῦ (nom commun) (m)''' : juge.<br> '''δίκη, -ης (nom commun) (f)''' : Coutume, manière, mode. Ordre, loi, droit. Justice. Jugement. Punition, vengeance, pénalité.<br> '''δίκτυον, -ύου (nom commun) (n)''' : filet.<br> '''δίνη, -ης (nom commun) (f)''' : tourbillon.<br> '''δίλημμα, -ήμματος (nom commun) (n)''' : dilemme.<br> '''διπλοῦς, -ῆ, -οῦν ‎(adjectif)''' : double.<br> '''διοίκησις, -ήσεως (nom commun) (f)''' : administration.<br> '''διοικητής, -οῦ (nom commun) (m)''' : administrateur.<br> '''διοικητικός, -ή, -όν ‎(adjectif)''' : administratif.<br> '''διοικῶ (verbe)''' : administrer.<br> '''διορθώνω (verbe)''' : corriger.<br> '''δισσός, -ή, -όν ‎(adjectif)''' : double.<br> '''δισσότατα, -, - (adverbe)''' : Superlatif de ''δισσῶς''.<br> '''δισσότερον, -, - (adverbe)''' : Comparatif de ''δισσῶς''.<br> '''δισσότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''δισσός''.<br> '''δισσότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''δισσός''.<br> '''δίς (adverbe)''' : deux fois.<br> '''δισσῶς (adverbe)''' : doublement.<br> '''δίφθογγος, -όγγου (nom commun) (f)''' : diphtongue.<br> '''δίφουρα, -ύρας (nom commun) (f)''' : Forme laconienne de ''γέφυρα''.<br> '''δίφρος, -ου (nom commun) (m)''' : tabouret.<br> '''διχόνοια, -ας (nom commun) (f)''' : discorde.<br> '''διχορεῖος, -ίου (nom commun) (m)''' : dichorée.<br> '''δίψα, -ης (nom commun) (f)''' : soif.<br> '''διψώ (verbe)''' : avoir soif.<br> '''διωγμός, -οῦ (nom commun) (m)''' : persécution.<br> '''διώκω (verbe)''' : persécuter.<br> '''διῶρυξ, -ώρυγος (nom commun) (f)''' : canal.<br> '''δμωή, -ῆς (nom commun) (f)''' : domestique, servante.<br> '''δμῳή, -ῆς (nom commun) (f)''' : esclave.<br> '''δμῴιος, -ίου (nom commun) (m)''' : esclave.<br> '''δμώς, -ός (nom commun) (m)''' : domestique, serviteur.<br> '''δόγμα, -τος (nom commun) (n)''' : Opinion. Décision, décret, arrêt. Doctrine.<br> '''δογματικός, -ή, -όν (adjectif)''' : doctrinal.<br> '''δογματικῶς (adverbe)''' : doctrinalement.<br> '''δογματικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''δογματικός''.<br> '''δογματικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''δογματικός''.<br> '''δοθιήν, -ένος (nom commun) (m)''' : furoncle.<br> '''δόκησις, -ήσεως (nom commun) (f)''' : Opinion ; croyance.<br> '''δοκέω (verbe)''' : Penser, supposer. Sembler.<br> '''δολερός, -ή, -όν (adjectif)''' : rusé.<br> '''δολιόω (verbe)''' : abuser.<br> '''δόλος, -ου (nom commun) (m)''' : ruse.<br> '''δόξα, -ης (nom commun) (f)''' : Opinion, vue, point de vue, conjecture, supposition. (Dans le Nouveau Testament.) Gloire, honneur ; splendeur.<br> '''δοξάζω (verbe)''' : Imaginer. Glorifier.<br> '''δοξολογία, -ας (nom commun) (f)''' : doxologie.<br> '''δοξόλογος, -όγου (nom commun) (m)''' : doxologue.<br> '''δοξοσοφία, -ας (nom commun) (f)''' : doxosophie.<br> '''δοξόσοφος, -όφου (nom commun) (m)''' : doxosophe.<br> '''δουλεία, -ας (nom commun) (f)''' : servitude.<br> '''δουλεύω (verbe)''' : être esclave. Travailler à gages, faire un travail mercenaire.<br> '''δούλη, -ης (nom commun) (f)''' : esclave.<br> '''δοῦλος, -ύλου (nom commun) (m)''' : esclave.<br> '''δουλόω (verbe)''' : asservir.<br> '''δούξ, -κός (nom commun) (m)''' : chef.<br> '''δόμος, -ου (nom commun) (m)''' : Maison, palais ; chambre, appartement.<br> '''δόναξ, -κος (nom commun) (m)''' : Roseau ; objet fait de roseau.<br> '''δονέω (verbe)''' : agiter.<br> '''δόνημα, -ήματος (nom commun) (n)''' : agitation.<br> '''δορκάς, -δος (f)''' : chevreuil.<br> '''δοράκινον, -ίνου (nom commun) (n)''' : pêche (fruit).<br> '''δόρκος, -ου (nom commun) (m)''' : Forme de ''δορκάς''.<br> '''δόρκων, -ος (nom commun) (m)''' : Forme de ''δορκάς''.<br> '''δόρξ, -κος (nom commun) (m)''' : Forme de ''δορκάς''.<br> '''δόσις, -εως (nom commun) (f)''' : don ; cadeau.<br> '''δοχεῖον, -ίου (nom commun) (n)''' : récipient.<br> '''δράκαινα, -ίνης (nom commun) (f)''' : dracène.<br> '''δράκων, -οντος (nom commun) (m)''' : dragon.<br> '''δρᾶμα, -άματος (nom commun) (n)''' : action théâtrale ; pièce de théâtre.<br> '''δραπέτης, -ου (nom commun) (m)''' : fugitif.<br> '''δράσσομαι (verbe)''' : saisir.<br> '''δραχμή, -ῆς (nom commun) (f)''' : Poignée, contenu de la main. Drachme attique.<br> '''δράω (verbe)''' : .<br> '''δρίλαξ, -κος (nom commun) (m)''' : sangsue.<br> '''δρομαῖος, -ία, -ῖον (adjectif)''' : .<br> '''δρομάς, -δος (nom commun) (m)''' : dromadaire.<br> '''δρόμος, -ου (nom commun) (m)''' : Course (de chevaux), lutte à la course, tour de promenade.<br> '''δρόσος, -ου (nom commun) (f)''' : rosée.<br> '''δρυμός, -οῦ (nom commun) (m)''' : bois (lieu), forêt.<br> '''δύη, -ης (nom commun) (f)''' : misère.<br> '''δύναμις, -εως (nom commun) (f)''' : force en puissance.<br> '''δύο (adjectif numéral)''' : deux.<br> '''δύσις, -εως (nom commun) (f)''' : ouest.<br> '''δυσλογία, -ας (nom commun) (f)''' : .<br> '''δυσμικός, -ή, -όν (adjectif)''' : occidental.<br> '''δυσ- (préfixe)''' : Difficulté, malheur.<br> '''δυσσέϐεια, -ίας (nom commun) (f)''' : impiété.<br> '''δυσσεϐέστατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''δυσσεϐής''.<br> '''δυσσεϐέστερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''δυσσεϐής''.<br> '''δυσσεϐής, -ής, -ές (adjectif)''' : impie.<br> '''δυσσεϐῶς (adverbe) : impieusement.<br> '''δυστύχημα, -ήματος (nom commun) (n)''' : accident.<br> '''δυστυχής, -ής, -ές (adjectif)''' : malheureux.<br> '''δυστυχία, -ας (nom commun) (f)''' : malheur.<br> '''δυστυχῶς (adverbe)''' : malheureusement.<br> '''δυστυχῶ (verbe)''' : causer un malheur.<br> '''δυτικός, -ή, -όν (adjectif)''' : occidental.<br> '''δυτικότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''δυτικός''.<br> '''δυτικότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''δυτικός''.<br> '''δυτικότατα, -, - (adverbe)''' : Superlatif de ''δυτικῶς''.<br> '''δυτικότερον, -, - (adverbe)''' : Comparatif de ''δυτικῶς''.<br> '''δυτικῶς (adverbe)''' : occidentalement.<br> '''δύω (verbe)''' : S’enfoncer, se plonger. (Par extension) Pénétrer dans. (Par analogie) Se revêtir de.<br> '''δώδεκα (adjectif numéral)''' : douze.<br> '''δωδεκάς, -δος (nom commun) (f)''' : douzaine.<br> '''δῶμα, -ώματος (nom commun) (n)''' : Construction. Maison, demeure. Chambre principale. Temple (demeure d’un dieu).<br> '''δωμάτιον, -ίου (nom commun) (n)''' : chambre.<br> '''δωράκινον, -ίνου (nom commun) (n)''' : pêche (fruit).<br> '''δῶρον, -ώρου (nom commun) (n)''' : Don ; présent. Paume de la main ; palme.<br> '''δώτωρ, -ορος (nom commun) (m)''' : donneur.<br> '''δῶ (verbe)''' : Lier, attacher. (Par extension) Enfermer, emprisonner. (Par analogie) Entraver, empêcher, retenir. (Figuré) Lier, enchaîner. Manquer, avoir besoin de. (Impersonnel) Il est besoin de, il faut. (Forme moyenne) Avoir besoin. (Par suite) Demander, prier.<br> '''Δαϐίδ (nom propre) (m)''' : Forme alternative de ''Δαυίδ''.<br> '''Δαίδαλος, -άλου (nom propre) (m)''' : Dédale.<br> '''Δάκης, -ου (nom commun) (n)''' : Dace.<br> '''Δαμασκός, -οῦ (nom propre) (f)''' : Damas.<br> '''Δαμαστής, -οῦ (nom propre) (m)''' : Damastès (Autre surnom de Polypémon).<br> '''Δαμάτηρ, -τρός (nom propre) (f)''' : Forme arcado-chypriote, béotienne, et dorienne de ''Δημήτηρ''.<br> '''Δαμιανός, -οῦ (nom propre) (m)''' : Damien.<br> '''Δαμία, -ας (nom propre) (f)''' : Damia.<br> '''Δάμις, - (nom propre) (m)''' : Damis.<br> '''Δάν, -ός (nom propre) (m)''' : Forme de ''Ζεύς''.<br> '''Δανιήλ (nom propre) (m)''' : Daniel.<br> '''Δάνος, -ου (nom commun) (m)''' : Forme macédonienne de ''Θάνατος''.<br> '''Δαυείδ (nom propre) (m)''' : Forme alternative de ''Δαυίδ''.<br> '''Δαυίδ (nom propre) (m)''' : David.<br> '''Δεῖμος, -ίμου (nom propre) (m)''' : Déimos.<br> '''Δεινώ, -οῦς (nom propre) (f)''' : Dino. (une des Grées)<br> '''Δέσποινα, -ίνης (nom propre) (f)''' : [[wikt:Despina|Despina]].<br> '''Δεύς, -ως (nom propre) (m)''' : Forme laconienne de ''Ζεύς''.<br> '''Δῃάνειρα, -ίρας (nom propre) (f)''' : Déjanire.<br> '''Δηϊδάμεια, -ίας (nom propre) (f)''' : Déidamie.<br> '''Δηιόκης, -ου (nom propre) (m)''' : Déjocès.<br> '''Δηΐφοϐος, -όϐου (nom propre) (m)''' : Déiphobe.<br> '''Δημήτηρ, -τρος (nom propre) (f)''' : [[wikt:Déméter|Déméter]].<br> '''Δημήτριος, -ίου (nom propre) (m)''' : Démétrios.<br> '''Δημιουργός, -οῦ (nom propre) (m)''' : Créateur.<br> '''Δημοσθένης, -ους (nom propre) (m)''' : Démosthène.<br> '''Δημώναξ, -ώνακτος (nom propre) (m)''' : Démonax.<br> '''Δίδυμοι, -ων (nom propre) (m)''' : Gémeaux.<br> '''Δίκη, -ης (nom propre) (f)''' : [[wikt:Dicé|Dicé]]. (Déesse de la justice divine.)<br> '''Δίκτυον, -ύου (nom propre) (n)''' : Réticule.<br> '''Διόδωρος, -ώρου (nom propre) (m)''' : Diodore.<br> '''Διογένης, -ους (nom propre) (m)''' : Diogène.<br> '''Διόνυσος, -ύσου (nom propre) (m)''' : [[wikt:Dionysos|Dionysos]].<br> '''Διομέδων, -οντος (nom propre) (m)''' : Diomède.<br> '''Διώνη, -ης (nom propre) (f)''' : [[wikt:Dioné|Dioné]].<br> '''Δούναϐις, -άϐεως (nom propre) (m)''' : Danube.<br> '''Δύμη, -ης (nom propre) (f)''' : Dymé.<br> '''Δυσνομία, -ας (nom propre) (m)''' : Dysnomie.<br> '''Δωμάτηρ, -τρός (nom propre) (f)''' : Forme éolienne de ''Δημήτηρ''.<br> '''Δωριεύς, -έως (nom commun) (m)''' : Dorien.<br> '''Δωρικός, -ή, -όν (adjectif)''' : dorien.<br> '''Δωρίς, -δος (nom propre) (f)''' : Doris. (Océanide) (nom commun) Dorienne.<br> '''Δωροθέα, -ας (nom propre) (f)''' : Dorothée.<br> '''Δωρόθεος, -έου (nom propre) (m)''' : Dorothéos.<br> '''Δῶρος, -ώρου (nom propre) (m)''' : Doros.<br> ==Ε== '''ἐάν (conjonction)''' : si (éventuel).<br> '''ἔαρ, -ος (nom commun) (n)''' : printemps.<br> '''ἑϐδομάς, -δος (nom commun) (f)''' : semaine.<br> '''ἑϐδομήκοντα (adjectif numéral)''' : soixante-dix.<br> '''ἕϐδομος, -όμη, -ομον (adjectif numéral)''' : septième.<br> '''ἑϐραΐζω (verbe)''' : .<br> '''ἑϐραῖος, -ία, -ῖον (adjectif)''' : israélite.<br> '''ἑϐραϊκός, -ή, -όν (adjectif)''' : hébraïque.<br> '''ἑϐραϊστί (adverbe)''' : en hébreu.<br> '''ἐγγόνη, -ης (nom commun) (f)''' : petite-fille.<br> '''ἐγγύησις, -ήσεως (nom commun) (f)''' : garantie.<br> '''ἐγγύς (adverbe)''' : proche.<br> '''ἐγγυῶμαι (verbe)''' : garantir (se rendre garant, répondre d’une chose, du maintien, de l’exécution d’une chose).<br> '''ἐγείρω (verbe)''' : réveiller.<br> '''ἐγκέφαλος, -άλου (nom commun) (m)''' : cerveau.<br> '''ἔγκλησις, -ίσεως (nom commun) (f)''' : accusation.<br> '''ἔγκλισις, -ίσεως (nom commun) (f)''' : mode (grammaire).<br> '''ἐγκόπρησις, -ήσεως (nom commun) (f)''' : incontinence fécale.<br> '''ἐγκόσμιος, -α, -ο (adjectif)''' : .<br> '''ἔγκυος, -ος, -ον (adjectif)''' : enceinte.<br> '''ἐγκυμονῶ (verbe)''' : engrossir.<br> '''ἐγκύμων, -ων, -ον (adjectif)''' : .<br> '''ἐγώ (pronom personnel)''' : je.<br> '''ἔδαφος, -άφους (nom commun) (n)''' : sol.<br> '''ἐδεμικός, -ή, -όν (adjectif)''' : édénique.<br> '''ἐδεμικῶς (adverbe)''' : édéniquement.<br> '''ἐδεμικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἐδεμικός''.<br> '''ἐδεμικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἐδεμικός''.<br> '''ἐδεμικώτατα, -, - (adverbe)''' : Superlatif de ''ἐδεμικῶς''.<br> '''ἐδεμικώτερον, -, - (adverbe)''' : Comparatif de ''ἐδεμικῶς''.<br> '''ἔδεσμα, -έσματος (nom commun) (n)''' : nourriture.<br> '''ἕδρα, -ας (nom commun) (f)''' : Siège. Trône. Résidence, demeure. Partie du corps sur laquelle on s'assied. Action de s'asseoir. Assemblée siégeante.<br> '''ἑδραῖος, ία, -ῖον (adjectif)''' : .<br> '''ἐδώδιμος, -η, -ο (adjectif)''' : mangeable.<br> '''ἐδωδή, -ῆς (nom commun) (f)''' : .<br> '''ἔδω (verbe)''' : nourrir.<br> '''ἕζομαι (verbe)''' : asseoir.<br> '''ἔζω (verbe)''' : nourrir.<br> '''ἐθίζω (verbe)''' : accoutumer.<br> '''ἐθικός, -ή, -όν (adjectif)''' : coutumier.<br> '''ἐθικῶς (adverbe)''' : coutumièrement.<br> '''ἐθικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἐθικός''.<br> '''ἐθικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἐθικός''.<br> '''ἐθνικός, -ή, -όν (adjectif)''' : national.<br> '''ἐθνικῶς (adverbe)''' : sagement.<br> '''ἐθνικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἐθνικός''.<br> '''ἐθνικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἐθνικός''.<br> '''ἔθνος, -ους (nom commun) (n)''' : Famille, ensemble des proches. Nation. Tribu. (Religion) (Au pluriel) Gentils, les non-juifs, usage tardif dans la Bible. Troupeau.<br> '''ἔθος, -ους (nom commun) (n)''' : coutume.<br> '''ἔθω (verbe)''' : avoir coutume de ; être habituel.<br> '''-ειδής, -ής, -ές (suffixe)''' : en forme de.<br> '''-ειδῶς (suffixe)''' : .<br> '''-ειδέστατος, -άτη, -έστατον (suffixe)''' : Superlatif de ''-ειδής''.<br> '''-ειδέστερος, -έρα, -έστερον (suffixe)''' : Comparatif de ''-ειδής''.<br> '''εἰδοποίησις, -ήσεως (nom commun) (f)''' : information.<br> '''εἰδοποιῶ (verbe)''' : informer.<br> '''εἶδος, -ἴδους (nom commun) (f)''' : Forme du corps ; air d'une personne ou d'une chose.<br> '''εἰδύλλιον, -ίου (nom commun) (n)''' : Petit poème lyrique.<br> '''εἰδωλολάτρης, -ου (nom commun) (m)''' : païen.<br> '''εἰδωλολατρία, -ας (nom commun) (f)''' : paganisme.<br> '''εἴδωλον, -ώλου (nom commun) (n)''' : Simulacre, fantôme ; image, portrait.<br> '''εἴδω (verbe)''' : voir.<br> '''εἰ (adverbe, conjonction)''' : si.<br> '''εἰ μή (conjonction)''' : à moins que ; sauf si.<br> '''εἰκονικός, -ή, -όν (adjectif)''' : virtuel.<br> '''εἰκός, -τος (nom commun) (n)''' : raison.<br> '''εἰκών, -όνος (nom commun) (f)''' : image, portrait.<br> '''εἴκω (verbe)''' : Être semblable ; ressembler.<br> '''εἰσαφίημι (verbe)''' : .<br> '''εἰς (adverbe ; préposition)''' : Dans. Jusqu’à ; vers.<br> '''εἷς, ἑνός (adjectif numéral)''' : un.<br> '''εἰκοσαριά, -ᾶς (nom commun) (f)''' : vingtaine.<br> '''εἴκοσι(ν) (adjectif numéral)''' : vingt.<br> '''ἐείκοσι(ν) (adjectif numéral)''' : Forme homérique de ''εἴκοσι(ν)''.<br> '''ϝίκατι(ν) (adjectif numéral)''' : Forme béotienne de ''εἴκοσι(ν)''.<br> '''ϝείκατι(ν) (adjectif numéral)''' : Forme dorienne de ''εἴκοσι(ν)''.<br> '''βείκατι(ν) (adjectif numéral)''' : Forme sud-orientale de ''εἴκοσι(ν)''.<br> '''εἷλιξ, -κος (nom commun) (f)''' : Forme poétique de ''ἕλιξ''.<br> '''εἰλύω (verbe)''' : .<br> '''εἴλω (verbe)''' : tourner ; enrouler. Entasser.<br> '''εἷμα, -ἵματος (nom commun) (n)''' : Couverture ; vêtement.<br> '''εἶμι (verbe)''' : aller, se déplacer.<br> '''εἰμί (verbe)''' : être.<br> '''-εῖον, -ίου (suffixe) (n)''' : lieu caractéristique.<br> '''εἶπα (verbe)''' : Forme ionienne de ''εἶπον''.<br> '''εἴπην (verbe)''' : Forme dorienne de ''εἶπον''.<br> '''ἔειπον (verbe)''' : Forme homérique de ''εἶπον''.<br> '''εἶπον (verbe)''' : dire, parler.<br> '''εἰρωνεία, -ας (nom commun) (f)''' : dissimulation.<br> '''εἴρων, -ος (nom commun) (m/f)''' : dissimulateur.<br> '''εἰσϐάλλω (verbe)''' : envahir.<br> '''εἰσϐδάλλω (verbe)''' : .<br> '''εἰσϐολέυς, -έως (nom commun) (m)''' : envahisseur.<br> '''εἰσϐολή, -ῆς (nom commun) (f)''' : invasion.<br> '''εἰσχωρῶ (verbe)''' : pénétrer.<br> '''ἕκαστος, -άστη, -αστον (adjectif)''' : Chaque, chacun.<br> '''ἑκάτερος, -έρα, -άτερον (adjectif)''' : L’un de deux, chacun des deux.<br> '''ἑκατόν (adjectif numéral)''' : cent.<br> '''ἑκατομμύριον, -ίου (nom commun) (n)''' : million.<br> '''ἑκατονταρχία, -ας (nom commun) (f)''' : centurie.<br> '''ἑκατόνταρχος, -άρχου (nom commun) (m)''' : centurion.<br> '''ἐκϐιάζω (verbe)''' : faire chanter.<br> '''ἐκϐιασμός, -οῦ (nom commun) (m)''' : chantage.<br> '''ἐκδίδω (verbe)''' : éditer.<br> '''ἐκδίκησις, -ήσεως (nom commun) (f)''' : vengeance.<br> '''ἐκδικητής, -οῦ (nom commun) (m)''' : vengeur.<br> '''ἐκδικητικός, -ή, -ον (adjectif)''' : vengeur.<br> '''ἐκδικῶ (verbe)''' : venger.<br> '''ἔκδοσις, -όσεως (nom commun) (f)''' : édition.<br> '''ἐκδοχή, -ῆς (nom commun) (f)''' : version.<br> '''ἐκδύω (verbe)''' : Faire disparaître, ôter.<br> '''ἐκ (adverbe ; préposition ; préfixe)''' (Devient ''ἐξ'' devant un mot commençant par une voyelle, et ''ἐγ'' devant un mot commençant par ''β'', ''δ'', ''λ'' ou ''μ''.) : Hors, dehors.<br> '''ἐκεῖθεν (adverbe démonstratif)''' : de là-bas.<br> '''ἐκεῖ (adverbe démonstratif)''' : là-bas (sans mouvement).<br> '''ἐκεῖσε (adverbe démonstratif)''' : là-bas (avec mouvement).<br> '''ἐκείνῃ (adverbe démonstratif)''' : par là-bas.<br> '''ἔκζεμα, -έματος (nom commun) (n)''' : eczéma.<br> '''ἑκηϐόλος, -όλου (nom commun) (m)''' : tireur d’élite.<br> '''ἔκθεσις, -έσεως (nom commun) (f)''' : exposition.<br> '''ἐκκαλέω (verbe)''' : sommer.<br> '''ἐκκένωσις, -ώσεως (nom commun) (f)''' : évacuation.<br> '''ἐκκενῶ (verbe)''' : évacuer.<br> '''ἐκκεντρικός, -ή, -όν (adjectif)''' : excentrique.<br> '''ἐκκίνησις, -ήσεως (nom commun) (f)''' : départ.<br> '''ἐκκλεισία, -ας (nom commun) (f)''' : Forme thessalienne de ''ἐκκλησία''.<br> '''ἐκκλησία, -ας (nom commun) (f)''' : assemblée.<br> '''ἐκκλησίασμα, -άσματος (nom commun) (n)''' : congrégation.<br> '''ἐκλέγω (verbe)''' : choisir, sélectionner.<br> '''ἐκλεκτικός, -ή, -όν (adjectif)''' : sélectif.<br> '''ἐκλογή, -ῆς (nom commun) (f)''' : choix, élection.<br> '''ἐκμιαίνομαι (verbe)''' : éjaculer.<br> '''ἐκπομπή, -ῆς (nom commun) (f)''' : émission.<br> '''ἐκπέμπω (verbe)''' : émettre.<br> '''ἔκστασις, -άσεως (nom commun) (f)''' : transport spirituel.<br> '''ἐκτάμνω (verbe)''' : Forme homérique et ionienne de ''ἐκτέμνω''.<br> '''ἐκτέμνω (verbe)''' : .<br> '''ἐκθέτης, -ου (nom commun) (m)''' : exposant.<br> '''ἐκθετικός, -ή, -όν (adjectif)''' : exponentiel.<br> '''ἔκρηξις, -ήξεως (nom commun) (f)''' : explosion.<br> '''ἐκτίθημι (verbe)''' : exposer.<br> '''ἑκτικός, -ή, -όν (adjectif)''' : habituel.<br> '''ἑκτικότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ἑκτικός''.<br> '''ἑκτικότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ἑκτικός''.<br> '''ἑκτικῶς (adverbe)''' : habituellement.<br> '''ἐκτιμῶ (verbe)''' : estimer.<br> '''-εκτομία, -ας (suffixe)''' : action de couper.<br> '''ἐκτός (adverbe ; préposition)''' : au-dehors ; hors de.<br> '''ἑκυρά, -ᾶς (nom commun) (f)''' : belle-mère.<br> '''ἑκυρός, -οῦ (nom commun) (m)''' : beau-père.<br> '''ἐκφεύγω (verbe)''' : échapper à.<br> '''ἔκφρασις, -άσεως (nom commun) (f)''' : expression.<br> '''ἐκφράζω (verbe)''' : exprimer.<br> '''ἐκφοϐῶ (verbe)''' : intimider.<br> '''ἐκχύμωμα, -ώµατος (nom commun) (n)''' : Forme alternative de ''ἐκχύμωσις''.<br> '''ἐκχύμωσις, -ώσεως (nom commun) (f)''' : bleu.<br> (tache de sang extravasé).<br> '''ἐκχῶ (verbe)''' : s’écouler.<br> '''ἐλάσσων, -ων, -ον (adjectif)''' : Comparatif de ''ἐλαχύς''.<br> '''ἐλάττωμα, -ώµατος (nom commun) (n)''' : vice.<br> '''ἔλαφος, -άφου (nom commun) (m/f)''' : Cerf ; biche.<br> '''ἐλαφρός, -ή, -όν (adjectif)''' : léger, leste ; agile.<br> '''ἐλαφρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ἐλαφρός''.<br> '''ἐλαφρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ἐλαφρός''.<br> '''ἐλαφρῶς (adverbe)''' : légèrement, lestement ; agilement.<br> '''ἐλαχέως (adverbe)''' : petitement, courtement ; moyennement.<br> '''ἐλάχιστος, -ίστη, -άχιστον (adjectif)''' : Superlatif de ''ἐλαχύς''.<br> '''ἐλαχύς, -άχεια, -ύ (adjectif)''' : petit, court ; moyen.<br> '''ἔλεγχος, -έγχους (nom commun) (n)''' : examen ; réfutation.<br> '''ἐλέγχω (verbe)''' : examiner ; réfuter.<br> '''ἐλεεινός, -ή, -όν (adjectif)''' : compatissant.<br> '''ἐλέφας, -αντος (nom commun) (m)''' : Éléphant ; dent d’éléphant ; défense d’éléphant, ivoire. Objet garni d’ivoire ou ressemblant à de l’ivoire.<br> '''ἐλεημοσύνη, -ης (nom commun) (f)''' : aumône.<br> '''ἐλεημονέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''ἐλεήμων''.<br> '''ἐλεημονέστερος, -έρα, -έστερον (adjectif)''' : Comparatif de ''ἐλεήμων''.<br> '''ἐλεήμονως (adverbe)''' : charitablement.<br> '''ἐλεήμων, -ων, -ον (adjectif)''' : charitable.<br> '''ἔλεος, -έου (nom commun) (f)''' : Pitié ; compassion.<br> '''ἐλευθερία, -ας (nom commun) (f)''' : liberté.<br> '''ἐλευθερίη, -ας (nom commun) (f)''' : Forme ionienne de ''ἐλευθερία''.<br> '''ἐλεύθερος, -έρα, ύθερον (adjectif)''' : libre. Qui convient à un homme libre, digne d’un homme libre.<br> '''ἐλευθέρως (adverbe)''' : librement.<br> '''ἐλευθερώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἐλεύθερος''.<br> '''ἐλευθερώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἐλεύθερος''.<br> '''ἐλελεῦ (verbe)''' : pousser un cri de guerre.<br> '''ἐλελελεῦ (nom commun)''' : cri de guerre.<br> '''ἐλεῶ (verbe)''' : avoir pitié.<br> '''ἕλιξ, -κος (nom commun) (f)''' : Spirale, vrille. (Par analogie) Oreille externe.<br> '''ἑλίσσω (verbe)''' : tourner autour.<br> '''ἕλκηθρον, -ήτρου (nom commun) (n)''' : traîneau.<br> '''ἕλκω (verbe)''' : hisser.<br> '''ἐλλείπω (verbe)''' : Laisser derrière soi. Laisser de côté, négliger ; omettre. Manquer, faire défaut. (Intransitif) Rester en arrière.<br> '''ἔλλειψις, -ίψεως (nom commun) (f)''' : Manque, défaut ; insuffisance.<br> '''ἑλληνίζω (verbe)''' : parler grec.<br> '''ἑλληνικός, -ή, -όν (adjectif)''' : grec.<br> '''ἑλληνικῶς (adverbe)''' : .<br> '''ἑλληνικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἑλληνικός''.<br> '''ἑλληνικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἑλληνικός''.<br> '''ἑλληνιστής, -οῦ (nom commun) (m)''' : homme parlant grec.<br> '''ἑλληνιστί (adverbe)''' : en grec.<br> '''ἑλληνίστρια, -ας (nom commun) (f)''' : femme parlant grec.<br> '''ἐλλός, -οῦ (nom commun) (m)''' : faon.<br> '''ἐλπίς, -δος (nom commun) (f)''' : espoir.<br> '''ἔλυτρον, -ύτρου (nom commun) (n)''' : Enveloppe, étui, fourreau. (Par extension) Tout ce qui sert d’enveloppe.<br> '''ἐλύω (verbe)''' : Entourer, rouler autour.<br> '''ἔμϐρυον, -ύου (nom commun) (n)''' : embryon.<br> '''ἔμεσις, -έσεως (nom commun) (f)''' : .<br> '''ἐμετικός, -ή, -όν (adjectif)''' : vomitif.<br> '''ἔμετος, -έτου (nom commun) (f)''' : vomissement.<br> '''ἐµμί (verbe)''' : Forme éolienne de ''εἰμί''.<br> '''ἐμῶ (verbe)''' : vomir.<br> '''ἐμμονή, -ῆς (nom commun) (f)''' : obsession.<br> '''ἐμός, -ή, -όν (adjectif possessif)''' : mon.<br> '''ἐμπειρία, -ας (nom commun) (f)''' : expérience.<br> '''ἐμπειρικός, -ή, -όν (adjectif)''' : expérienciel.<br> '''ἐμπειρικότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ἐμπειρικός''.<br> '''ἐμπειρικότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ἐμπειρικός''.<br> '''ἐμπειρικότατα, -, - (adverbe)''' : Superlatif de ''ἐμπειρικῶς''.<br> '''ἐμπειρικότερον, -, - (adverbe)''' : Comparatif de ''ἐμπειρικῶς''.<br> '''ἐμπειρικῶς (adverbe)''' : expérienciellement.<br> '''ἐμπλάσσω (verbe)''' : emplâtrer.<br> '''ἔμπλαστρον, -άστρου (nom commun) (n)''' : emplâtre.<br> '''ἔμπνευσις, -ύσεως (nom commun) (f)''' : .<br> '''ἐμπορεῖον, -ίου (nom commun) (n)''' : boutique.<br> '''ἐμπόρευμα, -ύματος (nom commun) (n)''' : marchandise.<br> '''ἐμπορεύομαι (verbe)''' : commercer.<br> '''ἐμπόριον, -ίου (nom commun) (n)''' : commerce.<br> '''ἔμπορος, -όρου (nom commun) (m)''' : marchand.<br> '''ἐμπρός (verbe)''' : devant.<br> '''ἐμφαίνω (verbe)''' : Montrer ; présenter.<br> '''ἐμφανής, -ής, -ές (adjectif)''' : apparent.<br> '''ἐμφανίζω (verbe)''' : apparaître.<br> '''ἐμφάνισις, -ίσεως (nom commun) (f)''' : apparence.<br> '''ἔμφασις, -άσεως (nom commun) (f)''' : apparence.<br> '''ἔμφραγμα, -άγματος (nom commun) (n)''' : infarctus.<br> '''ἐμφρουρῶ (verbe)''' : .<br> '''ἐμφύσημα, -ήματος (nom commun) (n)''' : inflation.<br> '''ἐμφυσηματώδης, -ης, -ες (adjectif)''' : inflationnaire.<br> '''ἐναλλακτικός, -ή, -όν (adjectif)''' : alternatif.<br> '''ἐναλλακτικῶς (adverbe)''' : alternativement.<br> '''ἐναλλακτικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἐναλλακτικός''.<br> '''ἐναλλακτικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἐναλλακτικός''.<br> '''ἐνάρετος, -ος, -ον (adjectif)''' : vertueux.<br> '''ἔνδεια, -ας (nom commun) (f)''' : indigence.<br> '''ἐνδεής, -ής, -ής (adjectif)''' : indigent.<br> '''ἐνδόμυχος, -ος, -ον (adjectif)''' : intime.<br> '''ἔνδον (adverbe ; préposition)''' : en dedans, intérieurement, à l'intérieur ; au-dedans de, à l'intérieur de.<br> '''ἔνδος (adverbe ; préposition)''' : Forme dorienne de ''ἔνδον''.<br> '''ἐνδοτάτω (adverbe)''' : Superlatif de ''ἔνδον''.<br> '''ἐνδοτέρω (adverbe)''' : Comparatif de ''ἔνδον''.<br> '''ἔνδυμα, -ύματος (nom commun) (n)''' : vêtement.<br> '''ἐνέργεια, -ίας (nom commun) (f)''' : force en action.<br> '''ἐνεργής, -ής, -ής (adjectif)''' : productif.<br> '''ἐνεργός, -ός, -όν (adjectif)''' : actif.<br> '''ἐνεργούμενος, -ένου (nom commun) (m)''' : énergumène.<br> '''ἐνεργῶ (verbe)''' : Agir, produire, accomplir, exécuter. Agir sur, influencer (particulièrement en mauvaise part en parlant du mauvais esprit). (Voie moyenne) Opérer, agir.<br> '''ἐνενήκοντα (adjectif numéral)''' : quatre-vingt-dix.<br> '''ἐνέχομαι (verbe)''' : .<br> '''ἔνθα (adverbe)''' : ici.<br> '''ἐνθάδε (adverbe)''' : ici-même.<br> '''ἐνθένδε (adverbe)''' : d’ici.<br> '''ἐννέα (adjectif numéral)''' : neuf.<br> '''ἔνεμα, -έματος (nom commun) (n)''' : lavement. (Remède liquide.)<br> '''ἔνεσις, -έσεως (nom commun) (f)''' : injection.<br> '''ἐνεστώς, -ῶτος (nom commun) (n)''' : présent.<br> '''ἐννῆ (adjectif numéral)''' : Forme de ''ἐννέα''.<br> '''ἐνέχομαι (verbe)''' : .<br> '''ἐνίημι (verbe)''' : injecter.<br> '''ἐν (adverbe ; préposition)''' : Dans, en, parmi.<br> '''ἐν- (préfixe)''' (Devient ''ἐγ-'' devant ''γ'', ''κ'', ''ξ'', ''χ'' ; ''ἐλ-'' devant ''λ'' ; ''ἐμ-'' devant ''β'', ''µ'', ''π'', ''φ'', ''ψ'' ; ''ἐρ-'' devant ''ρ'' dans quelques mots comme ''ἔρρινον'' ; ''ἐσ-'' devant ''σ''.) : in-.<br> '''ἐνηλικίωσις, -ώσεως (nom commun) (f)''' : majorité.<br> '''ἐνήλικος -η -ον (adjectif)''' : adulte.<br> '''ἐνῆλιξ, -ήλικος (nom commun) (m)''' : adulte.<br> '''ἔνθεσις, -έσεως (nom commun) (f)''' : enthèse.<br> '''ἐνθουσιασμός, -οῦ (nom commun) (m)''' : enthousiasme.<br> '''ἐνθουσιαστικός, -ή, -όν (adjectif)''' : enthousiasmant.<br> '''ἐνθουσιαστικῶς (adverbe)''' : -ment.<br> '''ἐνθουσιαστικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἐνθουσιαστικός''.<br> '''ἐνθουσιαστικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἐνθουσιαστικός''.<br> '''ἐνθουσιαστικώτατα, -, - (adverbe)''' : Superlatif de ''ἐνθουσιαστικῶς''.<br> '''ἐνθουσιαστικώτερον, -, - (adverbe)''' : Comparatif de ''ἐνθουσιαστικῶς''.<br> '''ἐνθουσιώδης, -ης, -ες (adjectif)''' : enthousiaste.<br> ''', -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἐνθουσιώδης''.<br> ''', -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἐνθουσιώδης''.<br> ''', -, - (adverbe)''' : Superlatif de ''''.<br> ''', -, - (adverbe)''' : Comparatif de ''''.<br> '''ἐνίοτε (adverbe)''' : quelquefois.<br> '''ἔννοια, -ίας (nom commun) (f)''' : concept.<br> '''ἐνοριακός, -ή, -όν (adjectif)''' : paroissial.<br> '''ἐνορία, -ας (nom commun) (f)''' : paroisse.<br> '''ἐνοχή, -ῆς (nom commun) (f)''' : culpabilité.<br> '''ἕννυμι (verbe)''' : enfiler. (mettre un vêtement)<br> '''ἑνότης, -τος (nom commun) (f)''' : unité.<br> '''ἐνούρησις, -ήσεως (nom commun) (f)''' : incontinence urinaire.<br> '''ἐνουρῶ (verbe)''' : ne pas pouvoir retenir son urine.<br> '''ἐνοχή, -ῆς (nom commun) (f)''' : culpabilité.<br> '''ἐνόχλησις, -ήσεως (nom commun) (f)''' : Dérangement ; embêtement.<br> '''ἐνοχλητικός, -ή, -όν (adjectif)''' : Dérangeant ; embêtant.<br> '''ἐνοχλῶ (verbe)''' : Déranger ; embêter.<br> '''ἐνσκήπτω (verbe)''' : sévir.<br> '''ἔνταξις, -άξεως (f)''' : insertion.<br> '''ἐντάσσω (verbe)''' : insérer.<br> '''ἐνταῦθα (adverbe)''' : là.<br> '''ἐντίθημι (verbe)''' : introduire.<br> '''ἐντρέπω (verbe)''' : .<br> '''ἐντύπωσις, -ώσεως (nom commun) (f)''' : impression.<br> '''ἐντυπῶ (verbe)''' : .<br> '''ἕνωσις, -ώσεως (nom commun) (f)''' : union.<br> '''ἐνώτιον, -ίου (nom commun) (n)''' : boucle d'oreille.<br> '''ἔορ, -ος (nom commun) (f)''' : Fille ; cousine.<br> '''ἐρείκη, -ης (nom commun) (f)''' : bruyère.<br> '''ἑορτάζω (verbe)''' : fêter.<br> '''ἑορτή, -ῆς (nom commun) (f)''' : fête.<br> '''ἐξαδελφή, -ῆς (nom commun) (f)''' : cousine.<br> '''ἐξάδελφος, -ου (nom commun) (m)''' : cousin.<br> '''ἐξαίρεσις, -έσεως (nom commun) (m)''' : extraction.<br> '''ἐξαίρω (verbe)''' : exalter.<br> '''ἐξαιρῶ (verbe)''' : retirer.<br> '''ἐξαίσιος, -ια, -ιον (adjectif)''' : .<br> '''ἑξαν (adverbe)''' : Forme dorienne de ''ἑξῆς''.<br> '''ἔξαρσις, -άρσεως (nom commun) (f)''' : exaltation.<br> '''ἐξάρτημα, -ήματος (nom commun) (n)''' : accessoire.<br> '''ἕξ (adjectif numéral) (m/f/n)''' : six.<br> '''ϝέξ (adjectif numéral) (m/f/n)''' : Forme dorienne de ''ἕξ''.<br> '''ἑξακόσιοι (adjectif numéral)''' : six-cents.<br> '''ἐξάντλησις, -ήσεως (nom commun) (f)''' : épuisement.<br> '''ἐξαντλῶ (verbe)''' : épuiser.<br> '''ἐξαπάτησις, -ήσεως (nom commun) (f)''' : supercherie.<br> '''ἐξαπατῶ (verbe)''' : .<br> '''ἐξέδρα, -ας (nom commun) (f)''' : plate-forme.<br> '''ἐξέγερσις, -έρσεως (nom commun) (f)''' : insurrection.<br> '''ἑξείης (adverbe)''' : Forme poétique de ''ἑξῆς''.<br> '''ἐξήγησις, -ήσεως (nom commun) (f)''' : Exposé. Explication.<br> '''ἐξηγητής, -ου (nom commun) (m)''' : .<br> '''ἐξἡγοῦμαι (verbe)''' : Conduire, exposer.<br> '''ἑξήκοντα (adjectif numéral)''' : soixante.<br> '''ἑξῆς (adverbe)''' : .<br> '''ἐξιλέωσις, -ώσεως (nom commun) (f)''' : expiation.<br> '''ἐξιλεῶ (verbe)''' : expier.<br> '''ἐξέλιξις, -ίξεως (nom commun) (f)''' : évolution.<br> '''ἐξελίσσω (verbe)''' : évoluer.<br> '''ἐξευτελίζω (verbe)''' : humilier.<br> '''ἐξέτασις, -άσεως (nom commun) (f)''' : examen, recherche.<br> '''ἐξίστημι (verbe)''' : déplacer.<br> '''ἕξις, -εως (nom commun) (f)''' : habitude.<br> '''ἐξόγκωμα, -ώματος (nom commun) (n)''' : Proéminence ; protubérance.<br> '''ἔξοδος, -ου (nom commun) (f)''' : Issue ; sortie, départ.<br> '''ἐξομολόγησις, -ήσεως (nom commun) (f)''' : confession.<br> '''ἐξομολογητήριον, -ίου (nom commun) (n)''' : confessionnal.<br> '''ἐξομολογητής, -οῦ (nom commun) (m)''' : confesseur.<br> '''ἐξομολογῶ (verbe)''' : confesser.<br> '''ἐξορία, -ας (nom commun) (f)''' : exil.<br> '''ἐξορίζω (verbe)''' : exorciser.<br> '''ἐξορκισμός, -οῦ (nom commun) (m)''' : exorcisme.<br> '''ἐξορκιστής, -οῦ (nom commun) (m)''' : exorciste.<br> '''ἐξύπνημα, -ήματος (nom commun) (n)''' : réveil.<br> '''ἔξυπνος, -ος, -ον (adjectif)''' : .<br> '''ἐξυπνῶ (verbe)''' : réveiller.<br> '''ἐξωθῶ (verbe)''' : .<br> '''ἐξωκκλήσιον, -ίου (nom commun) (n)''' : chapelle.<br> '''ἐξωµίς, -δος (nom commun) (f)''' : exomide.<br> '''ἐξώστης, -ου (nom commun) (m)''' : balcon.<br> '''ἐξωτερικός, -ή, -όν (adjectif)''' : extérieur, externe.<br> '''ἐξωτικός, -ή, -όν (adjectif)''' : étranger.<br> '''ἔξω (adverbe)''' : hors de.<br> '''ἐπαινῶ (verbe)''' : vanter.<br> '''ἐπαναλαμϐάνω (verbe)''' : répéter ; reprendre.<br> '''ἐπαλήθευσις, -ύσεως (nom commun) (f)''' : vérification.<br> '''επαληθευτικός, -ή, -όν (adjectif)''' : vérificatif.<br> '''ἐπαληθευτικῶς (adverbe)''' : vérificativement.<br> '''ἐπαληθευτικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''επαληθευτικός''.<br> '''ἐπαληθευτικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''επαληθευτικός''.<br> '''ἐπαληθευτικώτατα, -, - (adverbe)''' : Superlatif de ''επαληθευτικῶς''.<br> '''ἐπαληθευτικώτερον, -, - (adverbe)''' : Comparatif de ''επαληθευτικῶς''.<br> '''ἐπαληθεύω (verbe)''' : vérifier.<br> '''ἐπαναληπτικός, -ή, -όν (adjectif)''' : répétitif.<br> '''ἐπαναληπτικῶς (adverbe)''' : répétitivement.<br> '''ἐπαναληπτικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἐπαναληπτικός''.<br> '''ἐπαναληπτικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἐπαναληπτικός''.<br> '''ἐπαναληπτικώτατα, -, - (adverbe)''' : Superlatif de ''ἐπαναληπτικῶς''.<br> '''ἐπαναληπτικώτερον, -, - (adverbe)''' : Comparatif de ''ἐπαναληπτικῶς''.<br> '''ἐπανάληψις, -ήψεως (nom commun) (f)''' : répétition.<br> '''ἐπανάστασις, -άσεως (nom commun) (f)''' : révolution.<br> '''ἐπανεκκίνησις, -ήσεως (nom commun) (f)''' : redémarrage.<br> '''ἐπάνω (adverbe)''' : .<br> '''ἐπαρχία, -ας (nom commun) (f)''' : province.<br> '''ἔπαρχος, -άρχου (nom commun) (m)''' : .<br> '''ἐπάρχω (verbe)''' : .<br> '''ἐπαφή, -ῆς (nom commun) (f)''' : contact.<br> '''ἐπαφίημι (verbe)''' : contacter.<br> '''ἐπεξῆς (adverbe)''' : Forme ionienne de ''ἐφεξῆς''.<br> '''ἐπένδυσις, -ύσεως (nom commun) (f)''' : .<br> '''ἐπενδύω (verbe)''' : revêtir par-dessus.<br> '''ἐπένθεσις, -έσεως (nom commun) (f)''' (Grammaire) Insertion d’une lettre à l’intérieur d’un mot.<br> '''ἐπεντίθημι (verbe)''' : Insérer une lettre à l’intérieur d’un mot.<br> '''ἐπερώτησις, -ήσεως (nom commun) (f)''' : interpellation.<br> '''ἑπτά (adjectif numéral)''' : sept.<br> '''ἐπεισοδιακός, -ή, -όν (adjectif)''' : épisodique.<br> '''ἐπεισόδιον, -ου (nom commun) (n)''' : épisode.<br> '''ἐπιϐαίνω (verbe)''' : Monter. (Marine) Embarquer, monter dans un bateau. (Militaire) Attaquer, avancer sur l’ennemi. Monter à cheval, aller à cheval.<br> '''ἐπιϐδάλλω (verbe)''' : .<br> '''ἐπιϐήτωρ, -ορος (nom commun) (m)''' : étalon.<br> '''ἐπιϐλαϐής, -ής, -ές (adjectif)''' : .<br> '''ἐπίϐλημα, -ήματος (nom commun) (m)''' : châle.<br> '''ἐπίγραθμα, -άθματος (nom commun) (n)''' : Forme dorienne de ''ἐπίγραμμα''.<br> '''ἐπίγραμμα, -άμματος (nom commun) (n)''' : inscription.<br> '''ἐπίδειξις, -ίξεως (nom commun) (f)''' : exhibition.<br> '''ἐπιδεκτικός, -ή, -όν (adjectif)''' : .<br> '''ἐπιδέχομαι (verbe)''' : .<br> '''ἐπιείκεια, -ίας (nom commun) (f)''' : indulgence.<br> '''ἐπιεικής, -ής, -ές (adjectif)''' : indulgent.<br> '''ἐπί (adverbe)''' (Devient ''ἐπ<nowiki>'</nowiki>'' devant une voyelle avec esprit doux et ''ἐφ<nowiki>'</nowiki>'' devant une voyelle avec esprit rude.) : sur.<br> '''ἐπιθαλάμιον, -ίου (nom commun) (n)''' : .<br> '''ἐπιθιγγάνω (verbe)''' : .<br> '''ἐπιτιθέναι (verbe)''' : .<br> '''ἐπίθεσις, -έσεως (nom commun) (f)''' : attaque ; assaut.<br> '''ἐπίθετον, -έτου (nom commun) (n)''' : adjectif.<br> '''ἐπίθετος, -, - (adjectif)''' : adjectival.<br> '''ἐπίθημα, -ήματος (nom commun) (n)''' : .<br> '''ἐπιθυμέω (verbe)''' : désirer.<br> '''ἐπιθυμία, -ας (nom commun) (f)''' : Désir, souhait. Passion.<br> '''ἐπίθυμος, -, - (adjectif)''' : Désireux ; passionné.<br> '''ἐπικαλοῦμαι (verbe)''' : invoquer.<br> '''ἐπικαλύπτω (verbe)''' : recouvrir.<br> '''ἐπικάλυψις, -ύψεως (nom commun) (f)''' : recouvrement.<br> '''ἐπικός, -ή, -όν (adjectif)''' : relatif aux vers.<br> '''ἐπικότατα, -, - (adverbe)''' : Superlatif de ''ἐπικῶς''.<br> '''ἐπικότερον, -, - (adverbe)''' : Comparatif de ''ἐπικῶς''.<br> '''ἐπικύρωσις, -ώσεως (nom commun) (f)''' : ratification.<br> '''ἐπικυρῶ (verbe)''' : ratifier.<br> '''ἐπικῶς (adverbe)''' : épiquement.<br> '''ἐπικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἐπικός''.<br> '''ἐπικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἐπικός''.<br> '''ἐπιλαμϐάνω (verbe)''' : invoquer.<br> '''ἐπίληπτος, -ος, -ον (adjectif)''' : .<br> '''ἐπιληψία, -ας (nom commun) (f)''' : .<br> '''ἐπιλογή, -ῆς (nom commun) (f)''' : sélection.<br> '''ἐπίλογος, -όγου (nom commun) (m)''' : postface.<br> '''ἐπίπληξις, -ήξεως (nom commun) (f)''' : réprimande.<br> '''ἐπιπλήττω (verbe)''' : réprimander.<br> '''ἐπιτίθημι (verbe)''' : attaquer.<br> '''ἐπιείκεια, -ίας (nom commun) (f)''' : indulgence.<br> '''ἐπιεικής, -ής -ές (adjectif)''' : indulgent.<br> '''ἐπιμέλεια, -ίας (nom commun) (f)''' : sollicitude.<br> '''ἐπιμελής, -ής -ές (adjectif)''' : soigneux.<br> '''ἐπιμέλησις, -ήσεως (nom commun) (f)''' : soin.<br> '''ἐπιμελότατα, -, - (adverbe)''' : Superlatif de ''ἐπιμελῶς''.<br> '''ἐπιμελότερον, -, - (adverbe)''' : Comparatif de ''ἐπιμελῶς''.<br> '''επιμελοῦμαι (verbe)''' : prendre soin de, veiller à ; se préoccuper de.<br> '''ἐπιμελῶς (adverbe)''' : soigneusement.<br> '''ἐπιούσιος, -α, -ον (adjectif)''' : supersubstantiel.<br> '''ἔπιπλον, -ίπλου (nom commun) (n)''' : fourniture.<br> '''ἐπίρρημα, -ήματος (nom commun) (n)''' : adverbe.<br> '''ἐπιρρίπτω (verbe)''' : .<br> '''ἐπιρρωνύω (verbe)''' : corroborer.<br> '''ἐπίρρωσις, -ώσεως (nom commun) (f)''' : corroboration.<br> '''ἐπίσημος, -α, -ον''' : Marqué, noté. Notable, remarquable.<br> '''ἐπισκέπτης, -ου (nom commun) (m)''' : visiteur.<br> '''ἐπισκέπτομαι (verbe)''' : visiter.<br> '''ἐπίσκεψις, -έψεως (nom commun) (f)''' : visite (action de visiter).<br> '''ἐπιστάζω (verbe)''' : saigner du nez.<br> '''ἐπίσταμαι (verbe)''' : Savoir ; connaitre.<br> '''ἐπίσταξις, -άξεως (nom commun) (f)''' : saignement nasal.<br> '''ἐπιστέλλω (verbe)''' : envoyer.<br> '''ἐπιστήμη, -ης (nom commun) (f)''' : Science ; savoir.<br> '''ἐπιστημονέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''ἐπιστήμων''.<br> '''ἐπιστημονέστερος, -έρα, -έστερον (adjectif)''' : Comparatif de ''ἐπιστήμων''.<br> '''ἐπιστήμονως (adverbe)''' : savamment.<br> '''ἐπιστήμων, -ων, -ον (adjectif)''' : Savant ; instruit.<br> '''ἐπιστολή, -ῆς (nom commun) (f)''' : Ordre ou avis émis par un message verbal ou écrit. Message écrit, lettre.<br> '''ἐπιστολικός, -ή, -όν (adjectif)''' : épistolaire.<br> '''ἐπιστολικῶς (adverbe)''' : épistolairement.<br> '''ἐπιστολικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἐπιστολικός''.<br> '''ἐπιστολικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἐπιστολικός''.<br> '''ἐπιστολικώτατα, -, - (adverbe)''' : Superlatif de ''ἐπιστολικῶς''.<br> '''ἐπιστολικώτερον, -, - (adverbe)''' : Comparatif de ''ἐπιστολικῶς''.<br> '''ἐπιστροφή, -ῆς (nom commun) (f)''' : retour.<br> '''ἐπιτακτικός, -ή, -όν (adjectif)''' : impératif.<br> '''ἐπιτακτικῶς (adverbe)''' : impérativement.<br> '''ἐπιτακτικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἐπιτακτικός''.<br> '''ἐπιτακτικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἐπιτακτικός''.<br> '''ἐπιτακτικώτατα, -, - (adverbe)''' : Superlatif de ''ἐπιτακτικῶς''.<br> '''ἐπιτακτικώτερον, -, - (adverbe)''' : Comparatif de ''ἐπιτακτικῶς''.<br> '''ἐπιτέμνω (verbe)''' : .<br> '''ἐπιτήδειος, -α, -ον (adjectif)''' : commode ; pratique.<br> '''ἐπιτηδειότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ἐπιτήδειος''.<br> '''ἐπιτηδειότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ἐπιτήδειος''.<br> '''ἐπιτηδειότατα, -, - (adverbe)''' : Superlatif de ''ἐπιτηδείως''.<br> '''ἐπιτηδειότερον, -, - (adverbe)''' : Comparatif de ''ἐπιτηδείως''.<br> '''ἐπιτηδείως (adverbe)''' : commodément.<br> '''ἐπιτομή, -ῆς (nom commun) (f)''' : compendium.<br> '''ἐπιτόνιον, -ίου (nom commun) (n)''' : .<br> '''ἐπιτρέπω (verbe)''' : autoriser, permettre.<br> '''ἐπιφέρω (verbe)''' : .<br> '''ἐπιφώνημα, -ήματος (nom commun) (n)''' : interjection.<br> '''ἐπιφώνησις, -ήσεως (nom commun) (f)''' : .<br> '''ἐπιφωνῶ (verbe)''' : .<br> '''ἐπιχαιρεκακία, -ας (nom commun) (f)''' : .<br> '''ἐπιχαιρέκακος, -ος, -ον (adjectif)''' : .<br> '''ἐπιχαίρω (verbe)''' : réjouir.<br> '''ἐπιχείρημα, -ήματος (nom commun) (n)''' : argument.<br> '''ἐπιχειρῶ (verbe)''' : cicatriser.<br> '''ἕπομαι (verbe)''' : argumenter.<br> '''ἔπος, -ους (nom commun) (n)''' : Parole ; vers.<br> '''ἐποποιία, -ας (nom commun) (f)''' : épopée.<br> '''ἐπουλῶ (verbe)''' : cicatriser.<br> '''ἐπύλλιον, -ίου (nom commun) (n)''' : .<br> '''ἐπῳδή, -ῆς (nom commun) (f)''' : incantation.<br> '''ἐπώδυνος, -ος, -ον (adjectif)''' : douloureux. Causé par la douleur.<br> '''ἑπωµίς, -δος (nom commun) (f)''' : épaulette.<br> '''ἐπωνύμιον, -ίου (nom commun) (n)''' : nom de famille.<br> '''ἐπωφελής, -ής, -ές (adjectif)''' : .<br> '''ἔραμαι (verbe)''' : aimer d'amour, désirer.<br> '''ἔρανος, -άνου (nom commun) (m)''' : quête.<br> '''ἐραστής, -οῦ (nom commun) (m)''' : amant.<br> '''ἑραστός, -ή, -όν (adjectif)''' : aimable, amoureux.<br> '''ἐράστρια, -ας (nom commun) (f)''' : amante.<br> '''ἐραστριάω (verbe)''' : être amoureux.<br> '''ἐρέϐινθος, -ίνθου (nom commun) (m)''' : pois chiche.<br> '''ἔρεϐος, -έϐους (nom commun) (n)''' : obscurité.<br> '''ἐρρωσθαι (verbe)''' : se bien porter.<br> '''ἐργάζομαι (verbe)''' : travailler.<br> '''ἐργαλεῖον, -ίου (nom commun) (n)''' : outil.<br> '''ἐργαστήριακός, -ή -όν (adjectif)''' : laborantin.<br> '''ἐργαστήριον, -ίου (nom commun) (n)''' : atelier, laboratoire.<br> '''ἐργαστήρ, -ῆρος (nom commun) (m)''' : travailleur.<br> '''ἐργάτης, -ου (nom commun) (m)''' : ouvrier, travailleur.<br> '''ἔργον, -ου (nom commun) (n)''' : travail.<br> '''ἐργώδης, -ης, -ες (adjectif)''' : laborieux.<br> '''ϝέργον, -ου (nom commun) (n)''' : Forme dorienne de ''ἔργον''.<br> '''ϝάργον, -ου (nom commun) (n)''' : Forme éléenne de ''ἔργον''.<br> '''ἐρέσσω (verbe)''' : ramer.<br> '''ἐρετμόν, -οῦ (nom commun) (n)''' : rame.<br> '''ἐρεύγομαι (verbe)''' : roter.<br> '''ἔρευνα, -ας (nom commun) (f)''' : enquête, recherche.<br> '''ἐρευνητής, -οῦ (nom commun) (m)''' : enquêteur, chercheur.<br> '''ἐρευνῶ (verbe)''' : enquêter, rechercher.<br> '''ἐρέφω (verbe)''' : toiturer, couronner.<br> '''ἐρημίτης, -ου (nom commun) (m)''' : ermite.<br> '''ἔρημος, -ήμου (nom commun) (f)''' : désert.<br> '''ἑρμηνεύς, -έως (nom commun) (m)''' : Interprète, traducteur ; messager des dieux.<br> '''ἑρμηνευτικός, -ή, -όν (adjectif)''' : .<br> '''ἑρμηνεύω (verbe)''' : Exprimer sa pensée par la parole. (Par suite) Faire connaître, indiquer, exposer (quelque chose). Interpréter, traduire.<br> '''ἔρομαι (verbe)''' : Demander, enquêter ; s’enquérir de.<br> '''ἑρπετόν, -οῦ (nom commun) (n)''' : Reptile ; serpent.<br> '''ἕρπυλλος, -ύλλου (nom commun) (m)''' : serpolet.<br> '''ἑρπυσμός, -οῦ (nom commun) (m)''' : fluage.<br> '''ἐρῥωσθαι (verbe)''' : se bien porter.<br> '''ἔρσην, -ενος (nom commun) (m)''' : Forme crétoise et éolienne de ''ἄρσην''.<br> '''ἐρεύθω (verbe)''' : rougir.<br> '''ἔρχομαι (verbe)''' : Venir, aller. S'en aller.<br> '''ἐρύθημα, -ήματος (nom commun) (n)''' : érythème.<br> '''ἐρυθρός, -ά, -όν (adjectif)''' : rouge.<br> '''ἐρυσίπελας, -έλατος (nom commun) (n)''' : inflammation cutanée.<br> '''ἐρωή, -ῆς (nom commun) (f)''' : précipitation.<br> '''ἐρωδιός, -οῦ (nom commun) (m)''' : héron.<br> '''ἐρωμένη, -ης (nom commun) (f)''' : femme aimé.<br> '''ἐρώμενος, -ένου (nom commun) (m)''' : homme aimé.<br> '''ἔρως, -τος (nom commun) (n)''' : amour « naturel » ; désir sexuel, plaisir corporel.<br> '''ἐρώτημα, -ήματος (nom commun) (n)''' : question.<br> '''ἐρωτηματικός, -ή, -όν (adjectif)''' : interrogatif.<br> '''ἐρωτηματικότατα, -, - (adverbe)''' : Superlatif de ''ἐρωτηματικῶς''.<br> '''ἐρωτηματικότερον, -, - (adverbe)''' : Comparatif de ''ἐρωτηματικῶς''.<br> '''ἐρωτηματικῶς (adverbe)''' : érotiquement.<br> '''ἐρωτηματικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἐρωτηματικός''.<br> '''ἐρωτηματικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἐρωτηματικός''.<br> '''ἐρώτησις, -ήσεως (nom commun) (f)''' : interrogation.<br> '''ἐρωτικός, -ή, -όν (adjectif)''' : relatif à l'amour « naturel ».<br> '''ἐρωτικότατα, -, - (adverbe)''' : Superlatif de ''ἐρωτικῶς''.<br> '''ἐρωτικότερον, -, - (adverbe)''' : Comparatif de ''ἐρωτικῶς''.<br> '''ἐρωτικῶς (adverbe)''' : érotiquement.<br> '''ἐρωτικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἐρωτικός''.<br> '''ἐρωτικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἐρωτικός''.<br> '''ἐρωτῶ (verbe)''' : interroger.<br> '''ἐρῶ (verbe)''' : aimer d'amour, désirer. Verser hors de ; vomir.<br> '''ἐσσαῖος, -ίου (nom commun) (m)''' : essénien.<br> '''ϝεσή, -ῆς (nom commun) (f)''' : toilettes.<br> '''ἐσθής, -ήτος (nom commun) (f)''' : vêtement.<br> '''ἐσθίω (verbe)''' : manger.<br> '''ἐσθλός, -ή, -όν (adjectif)''' : Excellent ; (poétique) bon.<br> '''ἐσθλῶς (adverbe)''' : excellemment.<br> '''ἐσθλώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἐσθλός''.<br> '''ἐσθλώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἐσθλός''.<br> '''ἐσλός, -ή, -όν (adjectif)''' : Forme dorienne de ''ἐσθλός''.<br> '''ἑσπέρα, -ας (nom commun) (f)''' : Soir ; ouest.<br> '''ϝεσπέρα, -ας (nom commun) (f)''' : Forme ancienne de ''ἑσπέρα''.<br> '''ἕσπερος, -ος, -ον (adjectif)''' : Relatif au soir ; occidental.<br> '''ἑστίασις, -άσεως (nom commun) (f)''' : restauration.<br> '''ἑστιατόριον, -ίου (nom commun) (n)''' : restaurant.<br> '''ἑστιάτωρ, -ορος (nom commun) (m)''' : restaurateur.<br> '''ἑστιάω (verbe)''' recevoir chez soi.<br> '''ἐσχάρα, -ας (nom commun) (f)''' : Foyer ; autel domestique et sanctuaire pour les suppliants. Autel pour les sacrifices. Brasier. Réchaud.<br> '''ἐσχάριον, -ίου (nom commun) (n)''' : cale (dispositif maritime).<br> '''ἔσχατος, -άτη, -ον (adjectif)''' : dernier.<br> '''ἐσωτερικός, -ή, -όν (adjectif)''' : intérieur, interne.<br> '''ἔσω (adverbe)''' : .<br> '''ἐσωτάτω (adverbe)''' : Superlatif de ''ἔσω''.<br> '''ἐσωτέρω (adverbe)''' : Comparatif de ''ἔσω''.<br> '''ἑταῖρα, -ίρας (nom commun) (f)''' : compagne.<br> '''ἑταιρείη, -ης (nom commun) (f)''' : Forme ionienne de ''ἑταιρεία''.<br> '''ἑταιρεῖος, -ία, -ῖον (adjectif)''' : compagnon.<br> '''ἑταῖρη, -ίρης (nom commun) (f)''' : Forme ionienne de ''ἑταῖρα''.<br> '''ἑταίρησις, -ήσεως (nom commun) (f)''' : compagnie.<br> '''ἑταῖρος, -ίρου (nom commun) (m)''' : compagnon.<br> '''ἐτεός, -ά, -όν (adjectif)''' : .<br> '''ἐτεῶς (adverbe)''' : .<br> '''ἐτεώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἐτεός''.<br> '''ἐτεώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de''ἐτεός''.<br> '''ἔτης, -ου (nom commun) (m)''' : cousin ; voisin.<br> '''ἔτος, -ους (nom commun) (n)''' : année.<br> '''ϝέτος, -ους (nom commun) (n)''' : Forme ancienne de ''ἔτος''.<br> '''ἔτυμος, -η, -ον (adjectif)''' : Vrai ; réel, véritable.<br> '''εὐάζω (verbe)''' : .<br> '''εὐαί (interjection)''' : .<br> '''εὐαγγελίζω (verbe)''' : annoncer une bonne nouvelle.<br> '''εὐαγγελισμός, -οῦ (nom commun) (m)''' : annonciation.<br> '''εὖγμα, -ὔγματος (nom commun) (n)''' : vœu.<br> '''εὐδαιμονία, -ας (nom commun) (f)''' : bonheur.<br> '''εὐδαίμων, -ων, -ον (adjectif)''' : heureux.<br> '''εὐδαιμόνως (adverbe)''' : heureusement.<br> '''εὐδαιμονέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''εὐδαίμων''.<br> '''εὐδαιμονέστερος, -έρα, -έρερον (adjectif)''' : Comparatif de ''εὐδαίμων''.<br> '''εὕδω (verbe)''' : dormir.<br> '''εὐγενής, -ής, -ές (adjectif)''' : noble.<br> '''εὐεργεσία, -ας (nom commun) (f)''' : bénéfice.<br> '''εὐεργέτης, -ου (nom commun) (n)''' : bienfaiteur.<br> '''εὐεργέτις, -δος (nom commun) (f)''' : bienfaitrice.<br> '''εὐεργετῶ (bénéfice)''' : bénéficier.<br> '''εὐ- (préfixe)''' : bon, bien.<br> '''εὐθέως (adverbe)''' : Directement ; immédiatement.<br> '''εὔθυνα, -ύνης (nom commun) (f)''' : responsabilité.<br> '''εὐθυνότης, -ητος (nom commun) (f)''' : responsabilité.<br> '''εὐθύνω (verbe)''' : être responsable.<br> '''εὐθύς, -εῖα, -ύ (adjectif)''' : Direct ; immédiat.<br> '''εὐθύτατος, -άτη, -ύτατον (adjectif)''' : Superlatif de ''εὐθύς''.<br> '''εὐθύτερος, -έρα, -ύτερον (adjectif)''' : Comparatif de ''εὐθύς''.<br> '''εὐλάϐεια, -ας (nom commun) (f)''' : piété.<br> '''εὐλαϐής, -ής, -ές (adjectif)''' : pieux.<br> '''εὐλαϐικός, -ή, -όν (adjectif)''' : .<br> '''εὐλαϐικῶς (adverbe)''' : avec piété.<br> '''εὐλαϐῶς (adverbe)''' : pieusement.<br> '''εὐλαλος, -ος, -ον (adjectif)''' : qui parle bien.<br> '''εὐλογιά, -ᾶς (nom commun) (f)''' : variole.<br> '''εὐλογία, -ας (nom commun) (f)''' : louange.<br> '''εὐμετάϐλητος, -η, -ον (adjectif)''' : .<br> '''εὐμορφία, -ας (nom commun) (f)''' : beauté.<br> '''εὔμορφος, -ος, -ον (adjectif)''' : beau.<br> '''εὔνοια, -ίας (nom commun) (f)''' : faveur.<br> '''εὐνοϊκός, -ή, -όν (adjectif)''' : favorable.<br> '''εὐνοϊκῶς (adverbe)''' : favorablement.<br> '''εὐνοϊκώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''εὐνοϊκός''.<br> '''εὐνοϊκώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''εὐνοϊκός''.<br> '''εὐνοϊκώτατα, -, - (adverbe)''' : Superlatif de ''εὐνοϊκῶς''.<br> '''εὐνοϊκώτερον, -, - (adverbe)''' : Comparatif de ''εὐνοϊκῶς''.<br> '''εὔνους, -ους, -ουν (adjectif)''' : .<br> '''εὐπατρίδης, -ου (nom commun) (m)''' : gentilhomme.<br> '''εὐοπλέω (verbe)''' : être bien armé.<br> '''εὐρετήριον, -ήριου (nom commun) (n)''' : index (liste).<br> '''εὐρέως (adverbe)''' : largement.<br> '''εὐρύς, -εῖα, -ύ (adjectif)''' : Large. (Par extension) Vaste, spacieux.<br> '''εὐρύτατος, -άτη, -ύτατον (adjectif)''' : Superlatif de ''εὐρύς''.<br> '''εὐρύτερος, -έρα, -ύτερον (adjectif)''' : Comparatif de ''εὐρύς''.<br> '''εὔρωστος, -ος, -ον (adjectif)''' : .<br> '''εὐρωστότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''εὔρωστος''.<br> '''εὐρωστότερος, -έρα, -ότερον (adjectif)'''' : Comparatif de ''εὔρωστος''.<br> '''εὐρωστότατα, -, - (adverbe)''' : Superlatif de ''εὐρώστως''.<br> '''εὐρωστότερον, -, - (adverbe)''' : Comparatif de ''εὐρώστως''.<br> '''εὐρώστως (adverbe)''' : .<br> '''εὐσέϐεια, -ίας (nom commun) (f)''' : piété.<br> '''εὐσεϐέστατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''εὐσεϐής''.<br> '''εὐσεϐέστερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''εὐσεϐής''.<br> '''εὐσεϐής, -ής, -ές (adjectif)''' : pieux.<br> '''εὐσεϐῶς (adverbe)''' : pieusement.<br> '''εὐσυνείδητος, -ος, -ον (adjectif)''' : consciencieux.<br> '''ἐύς, -εῖα, -ύ (adjectif)''' : bon, brave.<br> '''εὐτελέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''εὐτελής''.<br> '''εὐτελέστερος, -έρα, -έστερον (adjectif)''' : Comparatif de ''εὐτελής''.<br> '''εὐτελής, -ής, -ές (adjectif)''' : Bon marché. De vil prix, de peu de valeur. Avare.<br> '''εὐτελίζω (verbe)''' : mépriser.<br> '''εὐτελῶς (adverbe)''' : .<br> '''εὐτυχία, -ας (nom commun) (f)''' : bonheur.<br> '''εὖ (adverbe)''' : Bien (idée d’origine) Noblement. Bien, régulièrement ; justement. Bien, avec bienveillance. Heureusement.<br> '''εὐτυχέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''εὐτυχής''.<br> '''εὐτυχέστερος, -έρα, -έστερον (adjectif)''' : Comparatif de ''εὐτυχής''.<br> '''εὐτυχής, -ής, -ές (adjectif)''' : heureux.<br> '''εὐτυχῶς (adverbe)''' : heureusement.<br> '''εὔφλεκτος, -ος, -ον (adjectif)''' : inflammable.<br> '''εὐφραδέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''εὐφραδής''.<br> '''εὐφραδέστερος, -έρα, -έστερον (adjectif)''' : Comparatif de ''εὐφραδής''.<br> '''εὐφραδής, -ής, -ές (adjectif)''' : .<br> '''εὔφρων, -ων, -ον (adjectif)''' : .<br> '''εὐφυέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''εὐφυής''.<br> '''εὐφυέστερος, -έρα, -έστερον (adjectif)''' : Comparatif de ''εὐφυής''.<br> '''εὐφυής, -ής, -ές (adjectif)''' : .<br> '''εὐφυῶς (adverbe)''' : .<br> '''εὐφωνία, -ας (nom commun) (f)''' : bonne sonorité.<br> '''εὐχαριστία, -ας (nom commun) (f)''' : .<br> '''εὐχάριστος, -ος, -ον (adjectif)''' : .<br> '''εὐχαριστῶ (verbe)''' : remercier.<br> '''εὐχή, -ῆς (nom commun) (f)''' : vœu.<br> '''εὔχομαι (verbe)''' : formuler un vœu.<br> '''εὖχος, -ὔχους (nom commun) (n)''' : Prière, vœu.<br> '''εὐχωλή, -ῆς (nom commun) (f)''' : Prière, vœu.<br> '''-εύς, -έως (suffixe) (m)''' : .<br> '''-εύω (suffixe)''' : .<br> '''ἐφαμέριος, -ίου (nom commun) (m)''' : Forme dorienne de ''ἐφημέριος''.<br> '''ἐφαμερεύω (verbe)''' : Forme dorienne de ''ἐφημερεύω''.<br> '''ἐφαρμόζω (verbe)''' : appliquer.<br> '''ἐφεξείης (adverbe)''' : Forme poétique de ''ἐφεξῆς''.<br> '''ἐφεξῆς (adverbe)''' : dorénavant, désormais.<br> '''ἐφήϐαιον, -ίου (nom commun) (m)''' : pubis.<br> '''ἐφηϐεία, -ας (nom commun) (f)''' : Service militaire rassemblant les jeunes Athéniens âgés de 18 à 20 ans.<br> '''ἐφηϐικός, -ή, -όν (adjectif)''' : adolescent.<br> '''ἔφηϐος, -ήϐου (nom commun) (m)''' : Jeune garçon ayant quitté l’autorité des femmes.<br> '''ἐφημέριος, -ίου (nom commun) (m)''' : curé.<br> '''ἐφημερεύω (verbe)''' : .<br> '''ἐφιάλτης, -ου (nom commun) (m)''' : cauchemar.<br> '''ἔχθος, -ους (nom commun) (n)''' : Haine ; hostilité.<br> '''ἐχθρά, -ᾶς (nom commun) (f)''' : ennemie.<br> '''ἐχθρός, -ά, -όν (adjectif)''' : Détesté de ; ennemi de.<br> '''ἐχθρός, -οῦ (nom commun) (m)''' : ennemi.<br> '''ἐχθρότης, -τος (nom commun) (f)''' : inimitié.<br> '''ἔχθω (verbe)''' : Haïr ; être hostile.<br> '''ἔχιδνα, -ης (nom commun) (f)''' : vipère.<br> '''ἐχῖνος, -ίνου (nom commun) (m)''' : hérisson.<br> '''ἔχις, -εως (nom commun) (m)''' : vipère.<br> '''ἔχω (verbe)''' : avoir.<br> '''ἕψημα, -ήματος (nom commun) (f)''' : cuisson.<br> '''ἕψησις, -ήσεως (nom commun) (f)''' : ébulition.<br> '''ἒ ψιλόν (nom commun) (n)''' : epsilon.<br> '''ἕψω (verbe)''' : Bouillir, cuire. Fondre, en parlant des métaux, raffiner, purifier. (Figuré) Être chaud pour ; chérir.<br> '''ἕως (conjonction)''' : jusqu'à ce que ; tant que.<br> '''Ἑϐραία, -ας (nom commun) (f)''' : Israélite.<br> '''Ἑϐραῖος, -ίου (nom commun) (m)''' : Israélite.<br> '''Ἑϐραΐς, -δος (nom commun) (f)''' : Israélite.<br> '''Ἐδέμ (nom propre) (m)''' : Éden.<br> '''Εἰλείθυια, -ίας (nom propre) (f)''' : [[wikt:Ilithyie|Ilithyie]] (déesse de l'enfantement).<br> '''Εἰρηναῖος, -ίου (nom propre) (m)''' : Irénée.<br> '''Εἰρήνη, -ης (nom propre) (f)''' : [[wikt:Eiréné|Eiréné]].<br> '''Ἑκάϐη, -ης (nom propre) (f)''' : Hécube.<br> '''Ἑκάτη, -ης (nom propre) (f)''' : Hécate.<br> '''Ἑκατόγχειρες, -ων (nom propre) (m)''' : Hécatonchires.<br> '''Ἕκτωρ, -ορος (nom propre) (m)''' : Hector.<br> '''Ἐλεάζαρος, -άρου (nom propre) (m)''' : Éléazar.<br> '''Ἐλαμείτης, -ου (nom commun) (m)''' : Élamite.<br> '''Ἐλεύθυια, -ίας (nom propre) (f)''' : Forme ancienne de ''Εἰλείθυια''.<br> '''Ἑλένη, -ης (nom propre) (f)''' : Hélène.<br> '''Ἕλενος, -ένου (nom propre) (m)''' : Hélénos.<br> '''Ἐλισάϐετ (nom propre) (f)''' : Élisabeth.<br> '''Ἑλλάς, -δος (nom propre) (f)''' : Grèce.<br> '''Ἕλλη, -ης (nom propre) (f)''' : Hellé.<br> '''Ἕλλην, -ος (nom propre) (m)''' : Hellen.<br> '''Ἕλλην, -ος (nom commun) (m)''' : Grec.<br> '''Ἑλληνίς, -δος (nom commun) (f)''' : Grecque.<br> '''Ἑλλήσποντος, -όντου (nom commun) (m)''' : Helléspont.<br> '''Ἐμπεδοκλῆς, -έους (nom propre) (m)''' : Empédocle.<br> '''Ἐνάρετη, -ης (nom propre) (f)''' : Énarété.<br> '''Ἐνδυμίων, -ωνος (nom propre) (m)''' : Endymion.<br> '''Ἐνετός, -οῦ (nom commun) (m)''' : Vénète.<br> '''Ἐνυώ, -οῦς (nom propre) (f)''' : [[wikt:Ényo|Ényo]].<br> '''Ἐπαμεινώνδας, -ου (nom commun) (m)''' : Épaminondas.<br> '''Ἐπίκτητος, -ήτου (nom propre) (m)''' : Épictète.<br> '''Ἐπιμηθεύς, -έως (nom propre) (m)''' : Épiméthée.<br> '''Ἐπιφί (nom propre) (m)''' : Epiphi.<br> '''Ἐρατοσθένης, -ους (nom propre) (m)''' : Ératosthène. (Savant grec né en -276 et mort en -194.)<br> '''Ἐρατώ, -οῦς (nom propre) (f)''' : Érato.<br> '''Ἔρεϐος, -έϐους (nom propre) (n)''' : [[wikt:Érèbe|Érèbe]].<br> '''Ἐρεχθεύς, -έως (nom propre) (m)''' : Érechtée.<br> '''Ἐρινύς, -ος (nom propre) (f)''' : Érynie.<br> '''Ἔρις, -εως (nom propre) (f)''' : [[wikt:Éris|Éris]].<br> '''Ἐριφύλη, -ης (nom propre) (f)''' : Ériphyle.<br> '''Ἑρμᾶς, -οῦ (nom propre) (m)''' : Forme dorienne de ''Ἑρμῆς''.<br> '''Ἑρμαφρόδιτος, -ίτου (nom propre) (m)''' : Hermaphrodite.<br> '''Ἑρμῆς, -οῦ (nom propre) (m)''' : [[wikt:Hermès|Hermès]].<br> '''Ἑρμιονεύς, -έως (nom propre) (m)''' : Hermionée.<br> '''Ἑρμιόνη, -ης (nom propre) (f)''' : Hermione.<br> '''Ἑρμιονίς, -δος (nom propre) (f)''' : Hermionide.<br> '''Ἑρμιών, -ῶνος (nom propre) (m)''' : Hermion.<br> '''Ἑρμογένης, -ους (nom propre) (m)''' : Hermogénès.<br> '''Ἐρυσίχθων, -ονος (nom propre) (m)''' : Érysichthon.<br> '''Ἔρως, -τος (nom propre) (m)''' : [[wikt:Éros|Éros]].<br> '''Ἑσπερία, -ας (nom propre) (f)''' : Hespérie.<br> '''Ἑσπερίδες, -ων (nom propre) (f)''' : Hespérides.<br> '''Ἑσπερίς, -δος (nom propre) (f)''' : Hespéris.<br> '''Ἕσπερος, -έρου (nom propre) (m)''' : Hespéros.<br> '''Εὔα, -ας (nom propre) (f)''' : Ève.<br> '''Εὐάγριος, -ίου (nom propre) (m)''' : Évagre.<br> '''Εὐγενία, -ας (nom propre) (f)''' : Eugénie.<br> '''Εὐγένιος, -ίου (nom propre) (m)''' : Eugène.<br> '''Εὔδημος, -ήµου (nom propre) (m)''' : Eudème.<br> '''Εὔιος, -ίου (nom propre) (m)''' : Euïos.<br> '''Εὐλαλία, -ας (nom propre) (f)''' : Eulalie.<br> '''Εὐλάλιος, -ίου (nom propre) (m)''' : Eulalios.<br> '''Εὔμαιος, -ίου (nom propre) (m)''' : Eumée. (Porcher de Laërte et d’Ulysse.)<br> '''Εὐήμερος, -έρου (nom propre) (m)''' : Évhémère.<br> '''Εὔμηλος, -ήλου (nom propre) (m)''' : Eumélos.<br> '''Εὔνηος, -ήου (nom propre) (m)''' : Eunée.<br> '''Εὐνομία, -ας (nom propre) (f)''' : Eunomie.<br> '''Εὐήρης, -ου (nom propre) (m)''' : Évérès.<br> '''Εὐριπίδης, -ου (nom propre) (m)''' : Euripide.<br> '''Εὔρος, -ου (nom propre) (m)''' : Euros. (dieu du vent d'est)<br> '''Εὐρυάλη, -ης (nom propre) (f)''' : Euryale.<br> '''Εὐρυδίκη, -ης (nom propre) (f)''' : Eurydice.<br> '''Εὐρύθεμις, -έμιδας (nom propre) (f)''' : Eurythémis.<br> '''Εὐρύκλεια, -ίας (nom propre) (f)''' : Euryclée.<br> '''Εὐρύλοχος, -όχου (nom propre) (m)''' : Euryloque.<br> '''Εὐρυσθεύς, -έως (nom propre) (m)''' : Eurysthée (fils de Sthénélos et Nicipée).<br> '''Εὐρωπαῖος, -ίου (nom commun) (m)''' : Européen.<br> '''Εὐρώπη, -ης (nom propre) (f)''' : Europe.<br> '''Εὐσέϐεια, -ας (nom propre) (f)''' : Eusébie.<br> '''Εὐσέϐιος, -ίου (nom propre) (m)''' : Eusèbe.<br> '''Εὐστάθιος, -ίου (prénom) (m)''' : Eustache.<br> '''Εὔσταχυς, -άχυος (prénom) (m)''' : Eustache.<br> '''Εὐτέρπη, -ης (nom propre) (f)''' : Euterpe.<br> '''Εὐτύχιος, -ίου (nom propre) (m)''' : Eutychius.<br> '''Εὐφημία, -ας (nom propre) (f)''' : Euphémie.<br> '''Εὔφημος, -ήμου (nom propre) (m)''' : Euphémos.<br> '''Εὐφράτης, -ου (nom propre) (m)''' : Euphrate (fleuve de Turquie et d’Irak).<br> '''Εὐφροσύνη, -ης (nom propre) (f)''' : Euphrosyne.<br> '''Εὔφρων, -ονος (nom propre) (m)''' : Euphron.<br> '''Ἔφεσος, -έσου (nom propre) (f)''' : Éphèse.<br> '''Ἐφιάλτης, -ου (nom propre) (m)''' : Éphialtès.<br> '''Ἕως, -ω (nom propre) (f)''' : Forme alternative de ''Ἠώς''.<br> '''Ἑωσφόρος, -ου (nom propre) (m)''' : Lucifer.<br> ==Ζ== '''ζῆλος, -ήλου (nom commun) (m)''' : Jalousie ; zèle.<br> '''ζηλοτυπία, -ας (nom commun) (m)''' : jalousie.<br> '''ζηλότυπος, -ος, -ον (adjectif)''' : jaloux.<br> '''ζηλωτής, -οῦ (nom commun) (m)''' : zélote.<br> '''ζηλῶ (verbe)''' : aimer ardemment.<br> '''ζῆτα (nom commun) (n)''' : zêta.<br> '''ζήτησις, -ήσεως (nom commun) (f)''' : recherche.<br> '''ζητητικός, -ός, -όν (adjectif)''' : aimant chercher ; rechercher.<br> '''ζητῶ (verbe)''' : demander ; chercher.<br> '''ζιγγίϐερις, -έρεως (nom commun) (f)''' : gingembre.<br> '''ζιζάνιον, -ίου (nom commun) (n)''' : ivraie.<br> '''ζιζανοσπορεύς, -έως (nom commun) (m)''' : .<br> '''ζιζανιοσπόρος, -ου (nom commun) (m)''' : .<br> '''ζιζανώδης, -ης, -ες (adjectif)''' : .<br> '''ζίζυφον, -ύϕου (nom commun) (n)''' : jujubier.<br> '''ζόα, -ας (nom commun) (f)''' : Forme dorienne de ''ζωή''.<br> '''ζόη, -ης (nom commun) (f)''' : Forme ionienne de ''ζωή''.<br> '''ζοΐα, -ας (nom commun) (f)''' : Forme éolienne de ''ζωή''.<br> '''ζόρξ, -κος (nom commun) (m)''' : Forme de ''δορκάς''.<br> '''ζυγαριά, -ᾶς (nom commun) (f)''' : balance.<br> '''ζυγόν, -οῦ (nom commun) (n)''' : joug.<br> '''ζῦθος, -ύθου (nom commun) (m)''' : bière.<br> '''ζωά, -ᾶς (nom commun) (f)''' : Autre forme dorienne de ''ζωή''.<br> '''ζωή, -ῆς (nom commun) (f)''' : vie.<br> '''ζῶμα, -ώματος (nom commun) (n)''' : caleçon.<br> '''ζώμευμα, -ύματος (nom commun) (n)''' : soupe.<br> '''ζωμεύω (verbe)''' : bouillir en soupe.<br> '''ζωμήρυσις, -ύσεως (nom commun) (f)''' : louche à soupe.<br> '''ζωμίδιον, -ίου (nom commun) (n)''' : sauce.<br> '''ζωμός, -οῦ (nom commun) (m)''' : bouillon, soupe.<br> '''ζωός, -ή, -όν (adjectif)''' : vivant.<br> '''ζῷον, -ῴου (nom commun) (n)''' : animal.<br> '''ζωοπανήγυρις, -ύρεως (nom commun) (f)''' : .<br> '''ζῶ (verbe)''' : vivre.<br> '''Ζαϐουλών (nom propre) (m)''' : Zabulon.<br> '''Ζαγρεύς, -έως (nom propre) (m)''' : Zagreus.<br> '''Ζακχαῖος, -ίου (nom propre) (m)''' : Zachée.<br> '''Ζάν, -ός (nom propre) (m)''' : Forme dorienne de ''Ζεύς''.<br> '''Ζάς, -νος (nom propre) (m)''' : Autre forme dorienne de ''Ζεύς''.<br> '''Ζαχαρίας, -ου (nom propre) (m)''' : Zacharie.<br> '''Ζεϐεδαῖος, -ίου (nom propre) (m)''' : Zébédée.<br> '''Ζευξίππη, -ης (nom propre) (f)''' : Zeuxippe.<br> '''Ζεῦξις, -ύξεως (nom propre) (m)''' : Zeuxis.<br> '''Ζεῦς, -ύσεως (nom propre) (m)''' : Forme lesbienne de ''Ζεύς''.<br> '''Ζεύς, Διός (nom propre) (m)''' : [[wikt:Zeus|Zeus]].<br> '''Ζέφυρος, -ύρου (nom propre) (m)''' : [[wikt:Zéphyr|Zéphyr]]. (dieu du vent d'ouest)<br> '''Ζῆλος, -ήλου (nom propre) (m)''' : Zélos.<br> '''Ζήν, -ός (nom propre) (m)''' : Forme poétique de ''Ζεύς''.<br> '''Ζηνοϐία, -ας (nom propre) (f)''' : Zénobie.<br> '''Ζηνοϐίος, -ίου (nom propre) (m)''' : Zénobios.<br> '''Ζυγός, -οῦ (nom propre) (m)''' : Balance.<br> '''Ζωροάστρης, -ου (nom propre) (m)''' : Zoroastre.<br> ==Η== '''ἡ (article défini)''' : la.<br> '''ἤ (conjonction)''' : ou.<br> '''ᾗ (adverbe relatif)''' : par là où (je passe).<br> '''ἥϐη, -ης (nom commun) (f)''' : jeunesse.<br> '''ἡϐητέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''ἡϐητής''.<br> '''ἡϐητέστερος, -έρα, -έστερον (adjectif)''' : Comparatif de ''ἡϐητής''.<br> '''ἡϐητής, -ής, -ές (adjectif)''' : juvénile.<br> '''ἡϐητῶς (adverbe)''' : juvénilement.<br> '''ἡϐός, -ή, -όν (adjectif)''' : jeune.<br> '''ἡϐότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ἡϐός''.<br> '''ἡϐότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ἡϐός''.<br> '''ἡγείσθαι (verbe)''' : conduire.<br> '''ἡγεμονία, -ας (nom commun) (f)''' : Action de conduire, de diriger. Suprématie, puissance. Règne.<br> '''ἡγεμονεύω (verbe)''' : .<br> '''ἡγεμών, -όνος (nom commun) (m)''' : souverain.<br> '''ἡγέομαι (verbe)''' : Marcher devant. (après Homère) Croire, penser.<br> '''ἡγέτης, -ου (nom commun) (m)''' : leader.<br> '''-ηγός, -οῦ (suffixe) (m/f)''' : .<br> '''ἥδομαι (verbe)''' : avoir plaisir à, se réjouir de.<br> '''ἡδονή, -ῆς (nom commun) (f)''' : plaisir.<br> '''ἡδύς, -εῖα, -ύ (adjectif)''' : doux, agréable.<br> '''ἡδύχρουν, - (nom commun) (n)''' : .<br> '''ἠθικός, -ή, -όν (adjectif)''' : moral.<br> '''ἠθικότατα, -, - (adverbe)''' : Superlatif de ''ἠθικῶς''.<br> '''ἠθικότερον, -, - (adverbe)''' : Comparatif de ''ἠθικῶς''.<br> '''ἠθικῶς (adverbe)''' : moralement.<br> '''ἠθικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἠθικός''.<br> '''ἠθικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἠθικός''.<br> '''ἦθος, ἤθους (nom commun) (n)''' : us et coutumes.<br> '''ἠϊθέη, -ης (nom commun) (f)''' : célibataire.<br> '''ἠΐθεος, -έου (nom commun) (m)''' : célibataire.<br> '''ἠι (adverbe)''' : Forme béotienne de ''ἀεί''.<br> '''-ήϊον, -ΐου (suffixe)''' : Forme ionienne de ''-εῖον''.<br> '''ἥκω (verbe)''' : être présent, être là.<br> '''ἠλακάτη, -ης (nom commun) (f)''' : quenouille.<br> '''ἤλεκτρον, -έκτρου (nom commun) (n)''' : ambre jaune.<br> '''ἠλέκτωρ, -, - (adjectif)''' : brillant.<br> '''ἡλιακός, -ή, -όν (adjectif)''' : solaire.<br> '''ἤλιθιος, -η, -ον (adjectif)''' : stupide.<br> '''ἡλικία, -ας (nom commun) (f)''' : âge.<br> '''ἥλιος, -ίου (nom commun) (m)''' : soleil.<br> '''ἠέλιος, -ίου (nom commun) (m)''' : Forme homérique de ''ἥλιος''.<br> '''ἡλιοστάσιον, -ίου (nom commun) (n)''' : solstice.<br> '''ἧλιξ, ἥλικος (nom commun) (m/f)''' : camarade.<br> '''ἧλος, ἥλου (nom commun) (m)''' : Clou, tête de clou. Cal, durillon, galle.<br> '''ἧμαι (verbe)''' : être assis.<br> '''ἡμεῖς (pronom personnel) (m)''' : nous.<br> '''ἡμέρα, -ας (nom commun) (f)''' : jour.<br> '''ἡμέρα Ἡλίου (nom commun) (f)''' : dimanche.<br> '''ἡμέρα Σελήνης (nom commun) (f)''' : lundi.<br> '''ἡμέρα Ἄρεως (nom commun) (f)''' : mardi.<br> '''ἡμέρα Ἕρμου (nom commun) (f)''' : mercredi.<br> '''ἡμέρα Διός (nom commun) (f)''' : jeudi.<br> '''ἡμέρα Ἀφροδίτης (nom commun) (f)''' : vendredi.<br> '''ἡμέρα Κρόνου (nom commun) (f)''' : samedi.<br> '''ἡμέρη, -ης''' (nom commun) (f) Forme homérique et ionienne de ''ἡμέρα''.<br> '''ἡμερήσιος, -ια, -ον (adjectif)''' : journalier ; diurne.<br> '''ἡμερολόγιον, -ίου (nom commun) (n)''' : calendrier.<br> '''ἡμέτερος, -έρα, -έτερον (adjectif possessif)''' : notre.<br> '''ἡμι- (préfixe)''' : à moitié.<br> '''ἡμίκλαστος, -, - (adjectif)''' : .<br> '''ἡμικρανία, -ας (nom commun) (f)''' : migraine.<br> '''ἡμίονος, -όνου (nom commun) (m)''' : hémione.<br> '''ἡνία, -ας (nom commun) (f)''' : .<br> '''ἡνίοχος, -όχου (nom commun) (m)''' : cocher.<br> '''ἧπαρ, ἥπατος (nom commun) (n)''' : foie.<br> '''ἡπατικός, -ή, -όν (adjectif)''' : hépatique.<br> '''ἡπατῖτις, -ίτης (nom commun) (f)''' : hépatite.<br> '''ἤπειρος, -ίρου (nom commun) (f)''' : continent.<br> '''ἠπειρωτικός, -ή, -όν (adjectif)''' : continental.<br> '''ἡράκλειος, -α, -ον (adjectif)''' : herculéen.<br> '''ἡρωίνη, -ης (nom commun) (f)''' : héroïne.<br> '''ἡρωικός, -ή, -όν (adjectif)''' : héroïque.<br> '''ἡρωικότατα, -, - (adverbe)''' : Superlatif de ''ἡρωικῶς''.<br> '''ἡρωικότερον, -, - (adverbe)''' : Comparatif de ''ἡρωικῶς''.<br> '''ἡρωικῶς (adverbe)''' : héroïquement.<br> '''ἡρωικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἡρωικός''.<br> '''ἡρωικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἡρωικός''.<br> '''ἡρωισμός, -οῦ (nom commun) (m)''' : héroïsme.<br> '''ἡρωίς, -δος (nom commun) (f)''' : héroïne.<br> '''ἥρως, -ος (nom commun) (m)''' : héros.<br> '''ἧσσα, ἥσσης (nom commun) (f)''' : défaite.<br> '''ἡσσῶμαι (verbe)''' : être défait.<br> '''ἡσυχάζω (verbe)''' : être en paix, garder le silence.<br> '''ἡσυχασμός, -οῦ (nom commun) (m)''' : hésychasme.<br> '''ἡσυχία, -ας (nom commun) (f)''' : Immobilité. Repos, calme ; silence.<br> '''ἥσυχος, -ος, -ον (adjectif)''' : Calme, tranquille.<br> '''ἡσύχως (adverbe)''' : Calmement, tranquillement.<br> '''ἡσυχώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἥσυχος''.<br> '''ἡσυχώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἥσυχος''.<br> '''σωματικώτατα, -, - (adverbe)''' : Superlatif de ''ἡσύχως''.<br> '''σωματικώτερον, -, - (adverbe)''' : Comparatif de ''ἡσύχως''.<br> '''ἦτα (nom commun) (n)''' : êta.<br> '''ἧτρον, ἥτρου (nom commun) (n)''' : abdomen.<br> '''ἧττα, ἥττης (nom commun) (f)''' : Forme attique de ''ἧσσα''.<br> '''ἡττῶμαι (verbe)''' : Forme attique de ''ἡσσῶμαι''.<br> '''ἡφαιστεῖον, -ίου (nom commun) (m)''' : volcan.<br> '''ἦχος, ἤχου (nom commun) (m)''' : son.<br> '''ἠχώ, -οῦς (nom commun) (f)''' : son répercuté.<br> '''ἠώς, -οῦς (nom commun) (f)''' : aurore.<br> '''Ἥϐη, -ης (nom propre) (f)''' : [[wikt:Hébé|Hébé]].<br> '''Ἡγήσιππος, -ίππου (nom propre) (m)''' : Hégésippe.<br> '''Ἡγησώ, -οῦς (nom propre) (f)''' : Hègèsô.<br> '''Ἠλίας, -α (nom propre) (m)''' : Élie.<br> '''Ἥλιος, -ίου (nom propre) (m)''' : [[wikt:Hélios|Hélios]].<br> '''Ἠλύσιον, -ίου (nom propre) (n)''' : Élysée. (Séjour des hommes vertueux après leur mort.)<br> '''Ἡμέρα, -ας (nom propre) (f)''' : [[wikt:Héméra|Héméra]].<br> '''Ἤπειρος, -ίρου (nom propre) (f)''' : Épire.<br> '''Ἠπιδανός, -οῦ (nom propre) (m)''' : Forme ionienne d<nowiki>'</nowiki>''Ἀπιδανός''.<br> '''Ἥρα, -ας (nom propre) (f)''' : [[wikt:Héra|Héra]].<br> '''Ἡρακλέης, -ους (nom propre) (m)''' : Forme poétique de ''Ἡρακλῆς''.<br> '''Ἡρακλῆς, -έους (nom propre) (m)''' : Héraclès.<br> '''Ἡρόστρατος, -άτου (nom propre) (m)''' : Hérostrate.<br> '''Ἠσαΐας, -ου (nom propre) (m)''' : Isaïe.<br> '''Ἡσαΐας, -ου (nom propre) (m)''' : Forme alternative de ''Ἠσαΐας''.<br> '''Ἡσαῦ (nom propre) (m)''' : Ésaü.<br> '''Ἠσαῦ (nom propre) (m)''' : Forme alternative de ''Ἡσαῦ''.<br> '''Ἡσύχιος, -ίου (nom propre) (m)''' : Hésychios.<br> '''Ἥφαιστος, -ίστου (nom propre) (m)''' : [[wikt:Héphaïstos|Héphaïstos]].<br> '''Ἠχώ, -οῦς (nom propre) (f)''' : [[wikt:Écho|Écho]].<br> '''Ἠώς, -οῦς (nom propre) (f)''' : [[wikt:Éos|Éos]].<br> ==Θ== '''θαλάμη, -ης (nom commun) (f)''' : Gîte ; tanière.<br> '''θάλαμος, -άμου (nom commun) (m)''' : chambre.<br> '''θάλασσα, -ης (nom commun) (f)''' : mer.<br> '''θάλαττα, -ης (nom commun) (f)''' : Forme attique de ''θάλασσα''.<br> '''θάμϐος, -ους (nom commun) (n)''' : stupeur.<br> '''θανατηφόρος, -ος, -ον (adjectif)''' : mortifère.<br> '''θάνατος, -άτου (nom commun) (m)''' : mort.<br> '''θανάτωσις, -ώσεως (nom commun) (f)''' : .<br> '''θανατῶ (verbe)''' : .<br> '''θανών, -ών, -όν (adjectif)''' : mort.<br> '''θάπτω (verbe)''' : enterrer.<br> '''θαυμάζω (verbe)''' : être stupéfait.<br> '''θαῦμα, -ύατος (nom commun) (n)''' : objet d’admiration ou d’étonnement ; merveille.<br> '''θαυμαστός, -ή, -όν (adjectif)''' : merveilleux.<br> '''θαυματουργία, -ας (nom commun) (f)''' : tour de force ; création de merveilles.<br> '''θαυματουργός, -ός, -όν (adjectif)''' : Qui crée des merveilles.<br> '''θαυματουργός, -οῦ (nom commun) (m)''' : créateur de merveilles.<br> '''θαυματουργῶ (verbe)''' : créer des merveilles.<br> '''θεά, -ᾶς (nom commun) (f)''' : déesse.<br> '''θέα, -ας (nom commun) (f)''' : contemplation.<br> '''θέαμα, -άματος (nom commun) (n)''' : spectacle.<br> '''θεατής, -οῦ (nom commun) (m)''' : spectateur.<br> '''θεατρικός, -ή, -όν (adjectif)''' : théâtral.<br> '''θεατρικῶς (adverbe)''' : théâtralement.<br> '''θεατρικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''θεατρικός''.<br> '''θεατρικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''θεατρικός''.<br> '''θεατρικώτατα, -, - (adverbe)''' : Superlatif de ''θεατρικῶς''.<br> '''θεατρικώτερον, -, - (adverbe)''' : Comparatif de ''θεατρικῶς''.<br> '''θέατρον, -ου (nom commun) (n)''' : théâtre.<br> '''θεατρινισμός, -οῦ (nom commun) (m)''' : .<br> '''θεατρινίστικος, -η, -ον (adjectif)''' : .<br> '''θεατρίνος, -ου (nom commun) (m)''' : acteur.<br> '''θέημα, -ήματος (nom commun) (n)''' : Forme ionienne de ''θέαμα''.<br> '''θέητρον, -ου (nom commun) (n)''' : Forme ionienne de ''θέατρον''.<br> '''θεῖα, -ίας (nom commun) (f)''' : tante.<br> '''θεῖον, -ίου (nom commun) (m)''' : soufre ; fumée de soufre.<br> '''θεῖος, -ίου (nom commun) (m)''' : oncle.<br> '''θέειος, -ίου (nom commun) (m)''' : Forme homérique de ''θεῖος''.<br> '''θεήϊος, -ΐου (nom commun) (m)''' : Forme de ''θεῖος''.<br> '''-θέτης, -ου (suffixe) (m)''' : .<br> '''θέλγω (verbe)''' : fasciner.<br> '''θέμα, -τος (nom commun) (n)''' : Dépôt, ce qui est placé, posé ou déposé. Endroit où l’on pose ou place quelque chose. .<br> '''θεματίζω (verbe)''' : déposer.<br> '''θεματίτης, -ου (nom commun) (m)''' : dépositaire.<br> '''θεματικός, -ή, -όν (adjectif)''' : thématique.<br> '''θέμις, -τος (nom commun) (f)''' : loi divine ou morale.<br> '''θέογνις, -δος (nom commun) (m)''' : .<br> '''θεός, -οῦ (nom commun) (m)''' : dieu.<br> '''θεραπεία, -ας (nom commun) (f)''' : soin.<br> '''θεραπευτήριον, -ίου (nom commun) (n)''' : sanatorium.<br> '''θεραπευτής, -οῦ (nom commun) (m)''' : soignant.<br> '''θεραπευτικός, -ή, -όν (adjectif)''' : attentif, serviable ; curatif.<br> '''θεραπεύω (verbe)''' : soigner ; prendre soin de.<br> '''θεράπων, -οντος (nom commun) (m)''' : serviteur.<br> '''θερμόν, -οῦ (nom commun) (n)''' : chaleur.<br> '''θερμός, -ή, -όν (adjectif)''' : chaud.<br> '''θερμότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''θερμός''.<br> '''θερμότερος, -έρη, -ότατον (adjectif)''' : Comparatif de ''θερμός''.<br> '''θερμῶς (adverbe)''' : chaudement.<br> '''θέρος, -ους (nom commun) (n)''' : été.<br> '''θέρω (verbe)''' : chauffer.<br> '''θέσις, -εως (nom commun) (f)''' : .<br> '''θεσμός, -οῦ (nom commun) (m)''' : (Primitivement) Toute loi ou institution établie par les dieux, institution sacrée, rite, coutume antique. Loi divine ou naturelle, par opposition à la loi écrite. (Par extension) Loi faite par les hommes, loi écrite.<br> '''θεσμοθέτης, -ου (nom commun) (m)''' : parlementaire.<br> '''θεσμοθετεῖον, -ίου (nom commun) (n)''' : parlement.<br> '''θεύς, -έως (nom commun) (m)''' : Forme dorienne de ''θεός''.<br> '''θεῶμαι (verbe)''' : Regarder, contempler (le plus souvent avec étonnement ou admiration), admirer. Contempler en esprit. Voir clairement. Être spectateur. Revoir, passer en revue, examiner.<br> '''θεώρημα, -ήματος (nom commun) (n)''' : Spectacle, fête ; règle, principe, objet d'étude ou de méditation ; contemplation, recherche.<br> '''θεωρητικός, -ή, -όν (adjectif)''' : théorique.<br> '''θεωρητικῶς (adverbe)''' : théoriqument.<br> '''θεωρητικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''θεωρητικός''.<br> '''θεωρητικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''θεωρητικός''.<br> '''θεωρητικώτατα, -, - (adverbe)''' : Superlatif de ''θεωρητικῶς''.<br> '''θεωρητικώτερον, -, - (adverbe)''' : Comparatif de ''θεωρητικῶς''.<br> '''θεωρία, -ας (nom commun) (f)''' : Observation, vue, action de voir. Spectacle, ce qui est vu. Mission diplomatique. État de spectateur, audience.<br> '''θεωρός, -οῦ (nom commun) (m)''' : Spectateur, observateur.<br> '''θεωρῶ (verbe)''' : Observer, examiner, contempler. Inspecter, passer en revue. Contempler. (Figuré) Contempler par l’intelligence.<br> '''θέω (verbe)''' : courir.<br> '''θήϊος, -ΐου (nom commun) (m)''' : Forme éolienne de ''θεῖος''.<br> '''θήκη, -ης (nom commun) (f)''' : Boîte, coffre. Cercueil, tombeau.<br> '''θήλεια, - (nom commun) (f)''' : .<br> '''θηλυκός, -ή, -όν (adjectif)''' : féminin.<br> '''θῆλυ, -ήλεας (nom commun) (f)''' : femelle.<br> '''θῆλυς, -ήλεια, -ῆλυ (adjectif)''' : femelle.<br> '''θηλύτης, -τος (nom commun) (f)''' : féminité.<br> '''θηλῶ (verbe)''' : .<br> '''θῆμα, -ήματος (nom commun) (n)''' : tombe.<br> '''θήρα, -ας (nom commun) (f)''' : chasse.<br> '''θήραμα, -άματος (nom commun) (n)''' : proie.<br> '''θηρευτής, -οῦ (nom commun) (m)''' : chasseur.<br> '''θηρευτικός, -ή, -όν (adjectif)''' : de chasse.<br> '''θηριότης, -τας (nom commun) (f)''' : monstruosité.<br> '''θηριώδης, -ης, -ες (adjectif)''' : monstrueux.<br> '''θηριωδία, -ας (nom commun) (f)''' : monstruosité.<br> '''θηρίον, -ου (nom commun) (n)''' : animal sauvage.<br> '''θήρ, -ός (nom commun) (m)''' : bête sauvage.<br> '''θηρῶ (verbe)''' : chasser.<br> '''θησαυρός, -οῦ (nom commun) (m)''' : trésor.<br> '''θῆσσα, -ήσσα (nom commun) (f)''' : serve.<br> '''θής, -τός (nom commun) (m)''' : serf.<br> '''θῆτα (nom commun) (n)''' : thêta.<br> '''θητεία, -ας (nom commun) (f)''' : service.<br> '''θητεύω (verbe)''' : asservir.<br> '''θῆττα, -ήττα (nom commun (f)''' : Forme attique de ''θῆσσα''.<br> '''θιγγάνω (verbe)''' : toucher.<br> '''θιός, -οῦ (nom commun) (m)''' : Forme béotienne et arcado-chypriote de ''θεός''.<br> '''θλάσις, -εως (nom commun) (f)''' : contusion.<br> '''θλιϐή, -ῆς (nom commun) (f)''' : .<br> '''θλίϐω (verbe)''' : Presser ; compresser, réduire. Oppresser, attrister.<br> '''θλῖψις, -ίψεως (nom commun) (f)''' : Pression, compression ; oppression.<br> '''θλίψις, -εως (nom commun) (f)''' : chagrin, tristesse.<br> '''θλῶ (verbe)''' : étendre.<br> '''θναίσκω (verbe)''' : Forme éolienne de ''θνῄσκω''.<br> '''θνᾴσκω (verbe)''' : Forme dorienne de ''θνῄσκω''.<br> '''θνῄσκω (verbe)''' : mourir.<br> '''θοάζω (verbe)''' : se hâter.<br> '''θολερός, -ά, -όν (adjectif)''' : sale.<br> '''θολερώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''θολερός''.<br> '''θολερώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''θολερός''.<br> '''θολερῶς (adverbe)''' : salement.<br> '''θοός, -ή, -όν (adjectif)''' : rapide.<br> '''θόρυϐος, -ύϐου (nom commun) (m)''' : bruit.<br> '''θορυϐωδέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''θορυϐώδης''.<br> '''θορυϐωδέστερος, -έρα, -έστερον (adjectif)''' : Comparatif de ''θορυϐώδης''.<br> '''θορυϐώδης, -ης, -ες (adjectif)''' : bruyant.<br> '''θορυϐώδως (adverbe)''' : bruyamment.<br> '''θοῶς (adverbe)''' : rapidement.<br> '''θοώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''θοός''.<br> '''θοώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''θοός''.<br> '''θρᾴκιος, -ος, -ον (adjectif)''' : thrace.<br> '''θρασέως (adverbe)''' : audacieusement.<br> '''θράσος, -ους (nom commun) (n)''' : audace.<br> '''θρασύς, -εῖα, -ύ (adjectif)''' : audacieux.<br> '''θρασύτατος, -άτη, -ύτατον (adjectif)''' : Superlatif de ''θρασύς''.<br> '''θρασύτερος, -έρα, -ύτερον (adjectif)''' : Comparatif de ''θρασύς''.<br> '''θρασύτης, -τητος (nom commun) (f)''' : audace (qualité).<br> '''θρῄκιος, -ος, -ον (adjectif)''' : Forme poétique de ''θρᾴκιος''.<br> '''θρῆνος, -ήνου (nom commun) (m)''' : lamentation.<br> '''θρηνῶ (verbe)''' : se lamenter.<br> '''θρησκεία, -ας (nom commun) (n)''' : religion.<br> '''θρησκεύω (verbe)''' : observer religieusement.<br> '''θρῆσκος, -ήσκα, -ῆσκον (adjectif)''' : pieux.<br> '''θρίαμϐος, -άμϐου (nom commun) (m)''' : triomphe.<br> '''θρίξ, τριχός (nom commun) (f)''' : poil.<br> '''θρίψ, -πός (nom commun) (m)''' : petite vrillette. (Au figuré) avare.<br> '''θροέω (verbe)''' : froisser.<br> '''θρόμϐος, -ου (nom commun) (m)''' : Grumeau, caillot.<br> '''θρόνος, -ου (nom commun) (m)''' : siège élevé.<br> '''θρόος, -ου (nom commun) (m)''' : froissement.<br> '''θροῦς, -οῦ (nom commun) (m)''' : rumeur.<br> '''θροῶ (verbe)''' : froisser.<br> '''θρυλικός, -ή -όν (adjectif)''' : légendaire.<br> '''θρῦλος, -ύλου (nom commun) (f)''' : légende. (Récit populaire, plus ou moins fabuleux.)<br> '''θρύπτω (verbe)''' : casser ; morceler.<br> '''θυγάτηρ, -ρός (nom commun) (f)''' : fille. (descendante)<br> '''θύλακος, -άκου (nom commun) (m)''' : bourse ; sac.<br> '''θῦμα, -ύματος (nom commun) (n)''' : victime.<br> '''θυμίαμα, -άματος (nom commun) (n)''' : encens.<br> '''θυμιάω (verbe)''' : brûler.<br> '''θυμίημα, -ήματος (nom commun) (n)''' : Forme ionienne de ''θυμίαμα''.<br> '''θυμολέων, -ων, -ον (adjectif)''' : Courageux ; cœur-de-lion.<br> '''θυμός, -οῦ (nom commun) (m)''' : Âme, souffle de vie. Esprit, cœur. Courage.<br> '''θύμος, -ου (nom commun) (m)''' : thym.<br> '''θύννος, -ου (nom commun) (m)''' : thon.<br> '''θύρα, -ας (nom commun) (f)''' : Porte, battant ; ouverture, entrée.<br> '''θυραωρός, -οῦ (nom commun) (m)''' : Forme homérique de ''θυρωρός''.<br> '''θυρωρεῖον, -ίου (nom commun) (n)''' : conciergerie.<br> '''θυρωρός, -οῦ (nom commun (m) : concierge.<br> '''θύρσος, -ου (nom commun) (m)''' : thyrse.<br> '''θύρωμα, -ώματος (nom commun) (n)''' : portail.<br> '''θυσία, -ας (nom commun) (f)''' : sacrifice.<br> '''θυσιάζω (verbe)''' : sacrifier.<br> '''θωή, -ῆς (nom commun) (f)''' : .<br> '''θῶμα, -ώματος (nom commun) (n)''' : Forme ionienne de ''θαῦμα''.<br> '''θωμαστός, -ή, -όν (adjectif)''' : Forme ionienne de ''θαυμαστός''.<br> '''θῶμιγξ, -ώμιγγος (nom commun) (f)''' : Corde ; ficelle.<br> '''θωπεία, -ας (nom commun) (f)''' : caresse.<br> '''θώπευμα, -ύματος (nom commun) (n)''' : caresse.<br> '''θωπευτικός, -ή, -όν (adjectif)''' : caressant.<br> '''θωπεύω (verbe)''' : caresser.<br> '''θώς, -ός (nom commun) (m/f)''' : chacal.<br> '''θώϋμα, -τος (nom commun) (n)''' : Autre forme ionienne de ''θαῦμα''.<br> '''θώψ, -πός (nom commun) (m)''' : adulateur.<br> '''Θαδδαῖος, -ίου (nom propre) (m)''' : Thadée.<br> '''Θαΐς, -δος (nom propre) (f)''' : [[wikt:Thaïs|Thaïs]].<br> '''Θάλεια, -ας (nom propre) (f)''' : Thalie. (muse)<br> '''Θαλῆς, -άλεω (nom propre) (m)''' : Thalès.<br> '''Θαλία, -ας (nom propre) (f)''' : Thalie. (Charite)<br> '''Θάνατος, -άτου (nom propre) (m)''' : [[wikt:Thanatos|Thanatos]].<br> '''Θαῦμας, -ύμαντος (nom propre) (m)''' : Thaumas.<br> '''Θάψος, -ου (nom propre) (f)''' : Thapsus. (ville de Tunisie)<br> '''Θέμις, -δος (nom propre) (f)''' : [[wikt:Thémis|Thémis]].<br> '''Θεμιστοκλῆς, -έους (nom propre) (m)''' : Thémistocle.<br> '''Θέτις, -δος (nom propre) (f)''' : [[wikt:Thétis|Thétis]].<br> '''Θέογνις, -δος (nom propre) (m)''' : Théognis.<br> '''Θεοδοσία, -ας (nom propre) (f)''' : Théodosia.<br> '''Θεοδόσιος, -ίου (nom propre) (m)''' : Théodose.<br> '''Θεόδουλος, -ύλος (nom propre) (m)''' : Théodule.<br> '''Θεόδωρος, -ώρου (nom propre) (m)''' : Théodore.<br> '''Θεόπομπος, -όμπου (nom propre) (m)''' : Théopompe.<br> '''Θεός, -οῦ (nom propre) (m)''' : Dieu.<br> '''Θεοφάνης, -ου (nom propre) (m)''' : Théophane.<br> '''Θεοφανία, -ας (nom propre) (f)''' : Théophanie.<br> '''Θεόφιλος, -ίλου (nom propre) (m)''' : Théophile.<br> '''Θεόφραστος, -άστου (nom propre) (m)''' : Théophraste.<br> '''Θερμοπύλαι, -ῶν (nom propre) (f)''' : Thermopyles.<br> '''Θέσπις, -εως (nom propre) (m)''' : Thespsis.<br> '''Θεσσαλία, -ας (nom propre) (f)''' : Thessalie.<br> '''Θεσσαλικός, -ή, -όν (adjectif)''' : thessalien.<br> '''Θεσσαλίς, -δος (nom commun) (f)''' : Thessalienne.<br> '''Θεσσαλονίκη, -ης (nom propre) (f)''' : Thessalonique.<br> '''Θεσσαλός, -οῦ (nom commun) (m)''' : Thessalien.<br> '''Θευδᾶς, -ᾶ (nom propre) (m)''' : Theudas.<br> '''Θευδέριχος, -ίχου (nom propre) (m)''' : Théodoric.<br> '''Θῆϐαι, -ῶν (nom propre) (f)''' : Thèbes.<br> '''Θησεύς, -έως (nom propre) (m)''' : Thésée.<br> '''Θίνη, -ης (nom propre) (f)''' : Synonyme de ''Σίνη''.<br> '''Θιός, -οῦ (nom propre) (m)''' : Forme béotienne de ''Ζεύς''.<br> '''Θίσϐη, -ης (nom propre) (f)''' : Thisbé.<br> '''Θόας, -αντος (nom propre) (m)''' : Thoas.<br> '''Θούθμωσις, -ώσιδος (nom propre) (m)''' : Thoutmôsis.<br> '''Θουκυδίδης, -ου (nom propre) (m)''' : Thucydide.<br> '''Θόωσα, -ης (nom propre) (f)''' : Thoosa.<br> '''Θρᾴκη, -ης (nom propre) (f)''' : Thrace.<br> '''Θρᾷξ, -ᾳκός (nom propre) (m)''' : Thrax.<br> '''Θρᾷξ, -ᾳκός (nom commun) (m)''' : Thrace.<br> '''Θρᾷσσα, -ᾴσσης (nom commun) (f)''' : Thrace.<br> '''Θρᾷττα, -ᾴττης (nom commun) (f)''' : Forme attique de ''Θρᾷσσα''.<br> '''Θρῄκη, -ης (nom propre) (f)''' : Forme poétique de ''Θρᾴκη''.<br> '''Θρῇξ, -ῃκός (nom commun) (m)''' : Forme poétique de ''Θρᾷξ''.<br> '''Θρῇσσα, -ῄσσης (nom commun) (f)''' : Forme poétique de ''Θρᾷσσα''.<br> '''Θωθ (nom propre) (m)''' : Thot.<br> '''Θωμᾶς, -ᾶ (prénom) (m)''' : Thomas.<br> ==Ι== '''ἴαμϐος, -άµϐου (nom commun) (m)''' : ïambe.<br> '''ἰάομαι (verbe)''' : soigner.<br> '''ἱαρός, -ά, -όν (adjectif)''' : Forme dorienne de ''ἱερός''.<br> '''ἴασις, -άσεως (nom commun) (f)''' : cure ; remède.<br> '''ἴασπις, -δος (nom commun) (f)''' : jaspe.<br> '''ἰατήρ, -ῆρος (nom commun) (m)''' : guérisseur.<br> '''ἰατός, -ός, -όν (adjectif)''' : curable ; soignable.<br> '''ἰατρεία, -ας (nom commun) (f)''' : médecine.<br> '''ἰατρικός, -ή, -όν (adjectif)''' : médical.<br> '''ἰατρικῶς (adverbe)''' : médicalement.<br> '''ἰατρικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἰατρικός''.<br> '''ἰατρικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἰατρικός''.<br> '''ἰατρικώτατα, -, - (adverbe)''' : Superlatif de ''ἰατρικῶς''.<br> '''ἰατρικώτερον, -, - (adverbe)''' : Comparatif de ''ἰατρικῶς''.<br> '''ἰατρός, -οῦ (nom commun) (m)''' : médecin.<br> '''ἱϐίσκος, -ου (nom commun) (m)''' : guimauve.<br> '''ἴγνης, -τος (nom commun) (m)''' : indigène.<br> '''ἰγνύα, -ας (nom commun) (f)''' : jarret.<br> '''ἰγνύη, -ης (suffixe) (f)''' : Forme hommérique et ionienne de ''ἰγνύα''.<br> '''ἰγνύς, -ος (nom commun) (f)''' : Forme de ''''.<br> '''ἴκτις, -δος (nom commun) (f)''' : martre.<br> '''ἱρός, -ά, -όν (adjectif)''' : Forme ionienne de ''ἱερός''.<br> '''ἷρος, -α, -ον (adjectif)''' : Forme éolienne de ''ἱερός''.<br> '''-ία, -ας (suffixe) (f)''' : marque nominale.<br> '''-ικός, -ή, -όν (suffixe)''' : marque adjectivale.<br> '''-ικῶς (adverbe)''' : Forme adverbiale de ''-ικός''.<br> '''-ικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''-ικός''.<br> '''-ικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''-ικός''.<br> '''-ικώτατα, -, - (adverbe)''' : Superlatif de ''-ικῶς''.<br> '''-ικώτερον, -, - (adverbe)''' : Comparatif de ''-ικῶς''.<br> '''-ίσκος, -ου (suffixe)''' : diminutif.<br> '''-ιμος, -ος, -ον (suffixe)''' : .<br> '''ἱαρεύς, -έως (nom commun) (m)''' : Forme dorienne de ''ἱερεύς''.<br> '''ἰαῦ (interjection)''' : hé, ho.<br> '''ἰαύω (verbe)''' : Dormir, se reposer.<br> '''ἶϐις, ἴϐιδος (nom commun) (f)''' : ibis.<br> '''ἰδίᾳ (adverbe)''' : en particulier, séparément, à part.<br> '''ἰδιοσυγκρασία, -ας (nom commun) (f)''' : tempérament particulier.<br> '''ἴδιος, -ία, -ιον (adjectif)''' : propre, particulier.<br> '''ἰδιοφυής, -ής, -ές (adjectif)''' : génial.<br> '''ἰδιοφυΐα, -ας (nom commun) (f)''' : génie (talent d’une personne).<br> '''ἰδιώτης, -ου (nom commun) (m)''' : individu, plébéien ; ignorant.<br> '''ἰδίω (verbe)''' : suer.<br> '''ἵδρυμα, -ύματος (nom commun) (n)''' : institution.<br> '''ἵδρυσις, -ύσεως (nom commun) (n)''' : fondation.<br> '''ἱδρύω (verbe)''' : .<br> '''ἱδρώς, -ῶτος (nom commun) (m)''' : sueur ; sudation. Sève ; jus, moisissure.<br> '''ἱέραξ, -κου (nom commun) (m)''' : faucon.<br> '''ἱερατεία, -ας (nom commun) (f)''' : tempérament particulier.<br> '''ἱεράτευμα, -ύματος (nom commun) (n)''' : .<br> '''ἱερατεύω (verbe)''' : .<br> '''ἱερατικός, -ή, -όν (adjectif)''' : sacerdotal.<br> '''ἱερατικῶς (adverbe)''' : sacerdotalement.<br> '''ἱερατικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἱερατικός''.<br> '''ἱερατικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἱερατικός''.<br> '''ἱέρεια, -ίας (nom commun) (f)''' : prêtresse.<br> '''ἱερεύς, -έως (nom commun) (m)''' : prêtre.<br> '''ἱεροκῆρυξ, -ήρυκος (nom commun) (m)''' : prêcheur.<br> '''ἱερόν, -οῦ (nom commun) (n)''' : sanctuaire.<br> '''ἱεροσυλία, -ας (nom commun) (m)''' : sacrilège (action).<br> '''ἱερόσυλος, -ύλου (nom commun) (m)''' : sacrilège (personne).<br> '''ἱερός, -ά, -όν (adjectif)''' : sacré.<br> '''ἱερῶς (adverbe)''' : sacrément.<br> '''ἱερώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἱερός''.<br> '''ἱερώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἱερός''.<br> '''ἱεροσύνη, -ης (nom commun) (f)''' : sacerdoce.<br> '''ἱερῶ (verbe)''' : .<br> '''ἰή (interjection)''' : Youpi, hourra. Aïe.<br> '''ἷημι (verbe)''' : envoyer, lancer.<br> '''ἰητρός, -οῦ (nom commun) (m)''' : Forme homérique et ionienne de ''ἰατρός''.<br> '''ἰθαγενής, -ής, -ές (adjectif)''' : indigène.<br> '''ἰθακήσιος, -ος, -ον (adjectif)''' : ithacien.<br> '''ἰθέως (adverbe)''' : Forme homérique et ionienne de ''εὐθέως''.<br> '''ἰθύς, -εῖα, -ύ (adjectif)''' : Forme homérique et ionienne de ''εὐθύς''.<br> '''ἰθύτατος, -άτη, -ύτατον (adjectif)''' : Superlatif de ''ἰθύς''.<br> '''ἰθύτερος, -έρα, -ύτερον (adjectif)''' : Comparatif de ''ἰθύς''.<br> '''ἰθύφαλλος, -άλλου (nom commun) (m)''' : ithyphalle.<br> '''ἱκεσία, -ας (nom commun) (f)''' : supplique.<br> '''ἱκετεύω (verbe)''' : supplier.<br> '''ἱκέτις, -δος (nom commun) (f)''' : pèlerine.<br> '''ἱκέτης, -ου (nom commun) (m)''' : pèlerin.<br> '''ἴκκος, -ου (nom commun) (m/f)''' : Forme éolienne de ''ἵππος''.<br> '''ἱκνέομαι (verbe)''' : aller à ; atteindre. Venir.<br> '''ἴκρια, -ας (nom commun) (f)''' : .<br> '''ἴκριον, -ου (nom commun) (n)''' : échafaudage.<br> '''ἰκρίωμα, -ώματος (nom commun) (n)''' : échafaudage.<br> '''ἰκριῶ (verbe)''' : .<br> '''ἴκτις, -δος (nom commun) (f)''' : fouine.<br> '''-ικός, -ή, -όν (adjectif)''' : -ique.<br> '''-ικῶς (adverbe)''' : -ment.<br> '''-ικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''-ικός''.<br> '''-ικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''-ικός''.<br> '''-ικώτατα, -, - (adverbe)''' : Superlatif de ''-ικῶς''.<br> '''-ικώτερον, -, - (adverbe)''' : Comparatif de ''-ικῶς''.<br> '''ἵκω (verbe)''' : venir.<br> '''ἵλαος, -ος, -ον (adjectif)''' : propice (en parlant des dieux). Gentil, aimable (en parlant des hommes).<br> '''ἱλαρός, -ά, -όν (adjectif)''' : joyeux, riant.<br> '''ἱλαρότης, -τος (nom commun) (f)''' : hilarité.<br> '''ἱλάσκομαι (verbe)''' : apaiser, calmer.<br> '''ἴλεξ, -κος (nom commun) (f)''' : houx.<br> '''ἰλιγγιωδέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''ἰλιγγιώδης''.<br> '''ἰλιγγιωδέστερος, -έρα, -έστερον (adjectif)''' : Comparatif de ''ἰλιγγιώδης''.<br> '''ἰλιγγιώδης, -ης, -ες (adjectif)''' : vertigineux.<br> '''ἰλιγγιωδῶς (adverbe)''' : vertigineusement.<br> '''ἰλιγγιωδώτατα, -, - (adverbe)''' : Superlatif de ''ἰλιγγιωδῶς''.<br> '''ἰλιγγιωδώτερον, -, - (adverbe)''' : Comparatif de ''ἰλιγγιωδῶς''.<br> '''ἴλιγγος, -ίγγου (nom commun) (m)''' : vertige.<br> '''ἰλλυρικός, -ή, -όν (adjectif)''' : illyrien.<br> '''ἰλλυρικῶς (adverbe)''' : illyriennement.<br> '''ἰλλυρικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἰλλυρικός''.<br> '''ἰλλυρικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἰλλυρικός''.<br> '''ἰλλυρικώτατα, -, - (adverbe)''' : Superlatif de ''ἰλλυρικῶς''.<br> '''ἰλλυρικώτερον, -, - (adverbe)''' : Comparatif de ''ἰλλυρικῶς''.<br> '''ἴλλω (verbe)''' : avoir le vertige.<br> '''ἰλύς, -ος (nom commun) (f)''' : Boue, sédiment. Impureté.<br> '''ἱμάς, -άντος (nom commun) (m)''' : courroie.<br> '''ἱμάσσω (verbe)''' : fouetter, flageller ; frapper.<br> '''ἱμάτιον, -ίου (nom commun) (n)''' : himation.<br> '''ἵμερος, -έρου (nom commun) (n)''' : désir amoureux.<br> '''ἱμῶ (verbe)''' : .<br> '''ἰξευτής, -οῦ (nom commun) (m)''' : oiseleur.<br> '''ἰξεύω (verbe)''' : oiseler.<br> '''ἰξός, -οῦ (nom commun) (m)''' : Glu ; gui.<br> '''ἰός, -οῦ (nom commun) (m)''' : Venin ; flèche.<br> '''ἰουδαῖος, -ία, -ῖον (adjectif)''' : juif.<br> '''ἴου (interjection)''' : beurk.<br> '''ἰπνός, -οῦ (nom commun) (m)''' : four.<br> '''ἱππάζομαι (verbe)''' : chevaucher.<br> '''ἱππαλεκτρυών, -όνος (nom commun) (m/f)''' : hippalectryon.<br> '''ἱππασία, -ας (nom commun) (f)''' : chevauchée.<br> '''ἱππαστί (adverbe)''' : à cheval.<br> '''ἱππεύς, -έως (nom commun) (m)''' : cavalier.<br> '''ἱππευτής, -οῦ (nom commun) (m)''' : cavalier.<br> '''ἱππεύω (verbe)''' : monter à cheval.<br> '''ἱππικός, -ή, -όν (adjectif)''' : équin.<br> '''ἱππικῶς (adverbe)''' : équinement.<br> '''ἱππικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἱππικός''.<br> '''ἱππικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἱππικός''.<br> '''ἱππικώτατα, -, - (adverbe)''' : Superlatif de ''ἱππικῶς''.<br> '''ἱππικώτερον, -, - (adverbe)''' : Comparatif de ''ἱππικῶς''.<br> '''ἵππος, -ου (nom commun) (m/f)''' : cheval, jument.<br> '''ἱππόκαμπος, -άμπου (nom commun) (m)''' : hippocampe.<br> '''ἱπποσύνη, -ης (nom commun) (f)''' : Équitation. (Militaire) Cavalerie.<br> '''ἱπποπόταμος, -άμου (nom commun) (m)''' : hippopotame.<br> '''ἱππο- (préfixe)''' : relatif au cheval.<br> '''ἱππότης, -ου (nom commun) (m)''' : cavalier.<br> '''ἴορκος, -όρκος (nom commun) (m)''' : Forme de ''δορκάς''.<br> '''ἰός, -οῦ (nom commun) (m)''' : Flèche ; venin.<br> '''ἰοῦ (interjection)''' : hourra.<br> '''ἱρεύς, -έως (nom commun) (m)''' : Forme ionienne de ''ἱερεύς''.<br> '''ἵρηξ, -κος (nom commun) (m)''' : Forme ionienne de ''ἱέραξ''.<br> '''ἶρις, ἴριδος (nom commun) (f)''' : (anatomie) iris (météorologie) arc-en-ciel.<br> '''ἰσαίτατα, -, - (adverbe)''' : Superlatif de ''ἴσως''.<br> '''ἰσαίτερον, -, - (adverbe)''' : Comparatif de ''ἴσως''.<br> '''ἴσατις, -δος (nom commun) (f)''' : guède.<br> '''ἰσημερία, -ας (nom commun) (f)''' : équinoxe.<br> '''ἰσορροπία, -ας (nom commun) (f)''' : équilibre.<br> '''ϝίσϝος, -η, -ον (adjectif)''' : Forme arcado-chypriote et crétoise de ''ἴσος''.<br> '''ἰσθμός, -οῦ (nom commun) (m)''' : isthme.<br> '''ἴσοξ, -κου (nom commun) (m)''' : brochet.<br> '''ἶσος, -η, -ον (adjectif)''' : Forme homérique de ''ἴσος''.<br> '''ἴσος, -η, -ον (adjectif)''' : égal.<br> '''ἴς, -νός (nom commun) (f)''' : force, puissance ; muscle.<br> '''ἵστημι (verbe)''' : Placer ; mettre debout.<br> '''ἱστίον, -ου (nom commun) (n)''' : os de la hanche.<br> '''ἱστόρημα, -ήματος (nom commun) (n)''' : narration.<br> '''ἱστορία, -ας (nom commun) (f)''' : Enquête, examination ; observation, étude.<br> '''ἱστορικός, -ή, -όν (adjectif)''' : D’enquête, bien informé.<br> '''ἱστορῶ (verbe)''' : enquêter.<br> '''ἱστός, -οῦ (nom commun) (m)''' : mât.<br> '''ἵστωρ, -ορος (nom commun) (m/f)''' : Individu sachant. Personne connaissant la loi. Juge.<br> '''ἰσχίον, -ου (nom commun) (n)''' : os de la hanche.<br> '''ἰσχνός, -ή, -όν (adjectif)''' : Desséché, sec. Maigre, grêle ; frêle.<br> '''ἰσχνότατα, -, - (adverbe)''' : Superlatif de ''ἰσχνῶς''.<br> '''ἰσχνότερον, -, - (adverbe)''' : Comparatif de ''ἰσχνῶς''.<br> '''ἰσχνότατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ἰσχνός''.<br> '''ἰσχνότερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ἰσχνός''.<br> '''ἰσχνῶς (adverbe)''' : maigrement.<br> '''ἴσχω (verbe)''' : tenir.<br> '''ἴσως (adverbe)''' : également.<br> '''ἰσαίτατος, -άτη, -ίτατον (adjectif)''' : Superlatif de ''ἴσος''.<br> '''ἰσαίτερος, -έρα, -ίτερον (adjectif)''' : Comparatif de ''ἴσος''.<br> '''ἰταλός, -οῦ (nom commun) (m)''' : Bouvillon, taurillon.<br> '''ἰταμός, -ή, -όν (adjectif)''' : effronté.<br> '''ἰταμότατα, -, - (adverbe)''' : Superlatif de ''ἰταμῶς''.<br> '''ἰταμότερον, -, - (adverbe)''' : Comparatif de ''ἰταμῶς''.<br> '''ἰταμότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ἰταμός''.<br> '''ἰταμότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ἰταμός''.<br> '''ἰταμότης, -ητος (nom commun) (f)''' : effronterie.<br> '''ἰταμῶς (adverbe)''' : effrontément.<br> '''-ίτης, -ου (suffixe) (m)''' : Suffixe nominal masculin.<br> '''-ῖτις, -ίτιδος (suffixe) (f)''' : Suffixe nominal féminin.<br> '''ἴυγξ, -γγος (nom commun) (f)''' : torcol.<br> '''ἰύζω (verbe)''' : crier de peine ou de joie.<br> '''ἴφυον, -ου (nom commun) (n)''' : .<br> '''ἰχθυοέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''ἰχθυόεις''.<br> '''ἰχθυοέστερος, -έρα, -ερον (adjectif)''' : Comparatif de ''ἰχθυόεις''.<br> '''ἰχθυόεις, -εσσα, -εν (adjectif)''' : poissonneux.<br> '''ἰχθύς, -ος (nom commun) (m)''' : poisson.<br> '''ἴχνος, -ους (nom commun) (n)''' : trace de pas.<br> '''ἰώϐηλος, -ήλου (nom commun) (m)''' : jubilé.<br> '''ἰῶτα (nom commun) (n)''' : iota.<br> '''ἰωτακισμός, -οῦ (nom commun) (m)''' : iotacisme.<br> '''Ἰάκωϐος, -ώϐου (nom propre) (m)''' : Jacob, Jacques.<br> '''Ἰαπετός, -οῦ (nom propre) (m)''' : Japet.<br> '''Ἴασος, -άσου (nom propre) (f)''' : Iasos (ville).<br> '''Ἰάσων, -ονος (nom propre) (m)''' : Jason. (chef des Argonautes)<br> '''Ἴδας, -α (nom propre) (m)''' : Idas.<br> '''Ἰδομενεύς, -έως (nom propre) (m)''' : Idoménée.<br> '''Ἰάμϐλιχος, -ίχου (nom propre) (m)''' : Jamblique.<br> '''Ἰαω (nom propre) (m)''' : Yahweh.<br> '''Ἰϐηρία, -ας (nom propre) (m)''' : Ibérie.<br> '''Ἴϐηρ, -ος (nom commun) (m)''' : Ibère.<br> '''Ἰγνάτιος, -ίου (nom propre) (m)''' : Ignace.<br> '''Ἰεριχώ (nom propre) (f)''' : Jéricho.<br> '''Ἰερειχώ (nom propre) (f)''' : Forme alternative de ''Ἰεριχώ''.<br> '''Ἱερειχώ (nom propre) (f)''' : Forme alternative de ''Ἰεριχώ''.<br> '''Ἱεριχοῦς (nom propre) (f)''' : Forme alternative de ''Ἰεριχώ''.<br> '''Ἱεριχώ, -οῦς (nom propre) (f)''' : Forme alternative de ''Ἰεριχώ''.<br> '''Ἰέρνη, -ης (nom propre) (f)''' : Irlande.<br> '''Ἱεροκλῆς, -έους (nom propre) (m)''' : Hiéroclès.<br> '''Ἱεροσάλημα (nom propre) (f)''' : Forme alternative de ''Ἱερουσαλήμ''.<br> '''Ἱεροσόλυμα (nom propre) (f/n)''' : Forme alternative de ''Ἱερουσαλήμ''.<br> '''Ἱερουσαλήμ (nom propre) (f)''' : Jérusalem (ville).<br> '''Ἰερουσαλήμ (nom propre) (f)''' : Forme alternative de ''Ἱερουσαλήμ''.<br> '''Ἱερώνυμος, -ύμου (prénom) (m)''' : Jérôme.<br> '''Ἰεσσαί (nom propre) (m)''' : Jessé.<br> '''Ἰεσσαῖος, -ίου (nom propre) (m)''' : Forme alternative de ''Ἰεσσαί''.<br> '''Ἰησαΐας, -ου (nom propre) (m)''' : Forme alternative de ''Ἠσαΐας''.<br> '''Ἰησοῦς, -οῦ (nom propre) (m)''' : Jésus, Josué.<br> '''Ἰησαΐας, -ου (nom propre) (m)''' : Forme alternative de ''Ἠσαΐας''.<br> '''Ἰησοῦς, -οῦ (nom propre) (m)''' : Jésus, Josué.<br> '''Ἰθάκα, -ης (nom propre) (f)''' : Forme dorienne de ''Ἰθάκη''.<br> '''Ἰθάκη, -ης (nom propre) (f)''' : Ithaque.<br> '''Ἴθακος, -άκου (nom commun) (m)''' : Ithacien.<br> '''Ἰκάριος, -ίου (nom propre) (m)''' : Icarios.<br> '''Ἴκαρος, -άρου (nom propre) (m)''' : Icare.<br> '''Ἴκελος, -έλου (nom propre) (m)''' : Icélos.<br> '''Ἰλιάς, -δος (nom propre) (f)''' : Iliade.<br> '''Ἴλιον, -ίου (nom propre) (n)''' : Ilion.<br> '''Ἰλιάς, -δος (nom propre) (f)''' : Iliade.<br> '''Ἴλιον, -ίου (nom propre) (n)''' : Ilion, Troie.<br> '''Ἰλλυρία, -ας (nom propre) (f)''' : Illyrie.<br> '''‎Ἰλλυρίς, -δος (nom commun) (f)''' : Illyrienne.<br> ‎'''Ἰλλυριός, -οῦ (nom commun) (m)''' : Illyrien.<br> '''Ἶλος, Ἴλου (nom propre) (m)''' : Ilos (fils de Tros et de Callirrhoé).<br> '''Ἵμερος, -έρου (nom propre) (m)''' : Himéros.<br> '''Ἰμούθης, -ου (nom propre) (m)''' : Imhotep.<br> '''Ἰξίων, -ονος (nom propre) (m)''' : Ixion.<br> '''Ἰόλαος, -άου (nom propre) (m)''' : Iolaos.<br> '''Ἰόλεως, -ώ (nom propre) (m)''' : Forme de ''Ἰόλαος''.<br> '''Ἰουδαῖα, -ίας (nom propre) (f)''' : Judée.<br> '''Ἰουδαῖα, -ίας (nom commun) (f)''' : Juive.<br> '''Ἰουδαῖος, -ίου (nom commun) (m)''' : Juif.<br> '''Ἰούδας, -α (nom propre) (m)''' : Judas.<br> '''Ἰουδίθ (nom propre) (f)''' : Judith.<br> '''Ἵππαρχος, -άρχου (nom commun) (m)''' : Hipparque (Fils cadet de Pisistrate, il fut assassiné par Harmodios et Aristogiton en −514 av. J.-C.).<br> '''Ἶρις, Ἴριδος (nom propre) (f)''' : [[wikt:Iris|Iris]].<br> '''Ἰσαάκ (nom propre) (m)''' : Issac.<br> '''Ἴσακος, - (nom propre) (m)''' : Forme alternative de ''Ἰσαάκ''.<br> '''Ἴσαυρα, -ας (nom propre) (f)''' : Isaura.<br> '''Ἰσαυρία, -ας (nom propre) (f)''' : Isaurie.<br> '''Ἴσαχος, - (nom propre) (m)''' : Forme alternative de ''Ἰσαάκ''.<br> '''Ἰσίδωρος, -ώρου (nom propre) (m)''' : Isidore.<br> '''Ἶσις, Ἴσιδος (nom propre) (f)''' : [[wikt:Isis|Isis]].<br> '''Ἰσθμός, -οῦ (nom propre) (m)''' : Isthmos.<br> '''Ἱσπανία, -ας (nom propre) (f)''' : Espagne.<br> '''Ἱσπανίς, -δος (nom commun) (f)''' : Espagnole.<br> '''Ἱσπανός, -οῦ (nom commun) (m)''' : Espagnol.<br> '''Ἰσμαήλ (nom propre) (m)''' : Ismaël.<br> '''Ἰσραήλ (nom propre) (m)''' : Israël.<br> '''Ἴστρος, -ου (nom propre) (f)''' : Danube inférieur.<br> '''Ἰταλία -ας (nom propre) (f)''' : Italie.<br> '''Ἰταλίς, -δος (nom commun) (f)''' : Italienne.<br> '''Ἰταλιώτης, -ου (nom commun) (m)''' : Italiote.<br> '''Ἱταλιῶτις, -ώτιδος (nom commun) (f)''' : Italiote.<br> '''Ἰταλός, -οῦ (nom commun) (m)''' : Italien.<br> '''Ἴτυς, -ος (nom propre) (m)''' : Itys.<br> '''Ἴϋγξ, -γγος (nom propre) (f)''' : [[wikt:Jynx|Jynx]].<br> '''Ἰφθίμη, -ης (nom propre) (f)''' : Iphtimé (sœur de Pénélope).<br> '''Ἰφιάνασσα, -ας (nom propre) (f)''' : Forme homérique de ''Ἰφιγένεια''.<br> '''Ἰφιγένεια, -ίας (nom propre) (f)''' : Iphigénie.<br> '''Ἰφικλῆς, -έους (nom propre) (m)''' : Iphiclès (demi-frère jumeau d'Héraclès).<br> '''Ἰχθύες, -ων (nom propre) (m)''' : Poissons.<br> '''Ἰωάννα, -ας (prénom) (f)''' : Jeanne.<br> '''Ἰωάννης ὁ Χρυσόστομος (nom propre) (m)''' : Jean Chrysostome.<br> '''Ἰωήλ (nom propre) (m)''' : Joël.<br> '''Ἰωνάθαν (nom propre) (m)''' : Jonathan.<br> '''Ἰωνᾶς, -ᾶ (nom propre) (m)''' : Jonas.<br> '''Ἰωνία, -ας (nom propre) (f)''' : Ionie.<br> '''Ἴων, -ος (nom propre) (m)''' : Ion (fils de Xouthos).<br> '''Ἴων, -ος (nom commun) (m)''' : Ionien.<br> '''Ἰωσήφ (nom propre) (m)''' : Joseph.<br> '''Ἰωσίας, -ου (nom propre) (m)''' : Josias.<br> '''Ἰώ, -οῦς (nom propre) (f)''' : [[wikt:Io|Io]].<br> ==Κ== '''ϗ (symbole)''' : Et. (Abréviation graphique valant ''καί'' en grec comme ''&'' valant ''et'' en français.)<br> '''καδεμών, -όνος (nom commun) (m)''' : Forme dorienne de ''κηδεμών''.<br> '''καδιμών, -όνος (nom commun) (m)''' : Forme éolienne de ''κηδεμών''.<br> '''κάδος, -ου (nom commun) (m)''' : seau.<br> '''καθαίρω (verbe)''' : Purger, nettoyer ; laver. Étriller.<br> '''καθαρεύω (verbe)''' : purifier.<br> '''καθαρίζω (verbe)''' : Nettoyer, purifier. (Médecine) Guérir d’une infection.<br> '''καθαρός, -ά, -όν (adjectif)''' : pur.<br> '''καθαρῶς (adverbe)''' : purement.<br> '''καθαρώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''καθαρός''.<br> '''καθαρώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''καθαρός''.<br> '''καθέδρα, ας (nom commun) (f)''' : Ce qui sert à s'asseoir. Action d'être ou de demeurer assis.<br> '''καθετήρ, -ῆρος (nom commun) (m)''' : Ligne pour pêcher. Collier, pendant ; ornement de femme.<br> '''καθεύδω (verbe)''' : dormir.<br> '''καθηγέομαι (verbe)''' : professer.<br> '''καθηγήτειρα, -ίρας (nom commun) (f)''' : professeure.<br> '''καθηγητής, -οῦ (nom commun) (m)''' : professeur.<br> '''καθηγητικός, -ή , -όν (adjectif)''' : professoral.<br> '''καθηγητικῶς (adverbe)''' : professoralement.<br> '''καθηγητικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''καθηγητικός''.<br> '''καθηγητικώτερος, -έρη, -ώτερον (adjectif)''' : Comparatif de ''καθηγητικός''.<br> '''καθηγητικώτατα, -, - (adverbe)''' : Superlatif de ''καθηγητικῶς''.<br> '''καθηγητικώτερον, -, - (adverbe)''' : Comparatif de ''καθηγητικῶς''.<br> '''καθήλωσις, -ώσεως (nom commun) (f)''' : détention.<br> '''καθηλῶ (verbe)''' : détenir.<br> '''καθίημι (verbe)''' : descendre.<br> '''κάθημαι (verbe)''' : siéger.<br> '''καθολικός, -ή, -όν (adjectif)''' : Général ; universel.<br> '''καθολικῶς (adverbe)''' : Généralement ; universellement.<br> '''καθολικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''καθολικός''.<br> '''καθολικώτερος, -έρη, -ώτερον (adjectif)''' : Comparatif de ''καθολικός''.<br> '''καθολικώτατα, -, - (adverbe)''' : Superlatif de ''καθολικῶς''.<br> '''καθολικώτερον, -, - (adverbe)''' : Comparatif de ''καθολικῶς''.<br> '''καθοράω (verbe)''' : regarder.<br> '''καί (conjonction)''' : Et ; Et même, même. Et en outre. Et ensuite, puis. Ou.<br> '''καινός, -ή, -όν (adjectif)''' : nouveau.<br> '''καινότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''καινός''.<br> '''καινότερος, -έρη, -ότερον (adjectif)''' : Comparatif de ''καινός''.<br> '''καινότατα, -, - (adverbe)''' : Superlatif de ''καινῶς''.<br> '''καινότερον, -, - (adverbe)''' : Comparatif de ''καινῶς''.<br> '''καίνωσις, -ώσεως (nom commun) (f)''' : renouvellement.<br> '''καινῶς (adverbe)''' : nouvellement.<br> '''καῖρος, -ίρου (nom commun) (m)''' : embrouille.<br> '''καιρός, -οῦ (nom commun) (m)''' : temps (durée, époque).<br> '''καιρόω (verbe)''' : embrouiller.<br> '''καίρωσις, -ώσεως (nom commun) (f)''' : embrouillage.<br> '''καίω (verbe)''' : brûler.<br> '''κάκιον, -, - (adverbe)''' : Comparatif de ''κακῶς''.<br> '''κάκιστα, -, - (adverbe)''' Superlatif de ''κακῶς''.<br> '''κακοδαίμων, -ων, -ον (adjectif)''' : malheureux.<br> '''κακοδαιμόνως (adverbe)''' : malheureusement.<br> '''κακοδαιμονέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''κακοδαίμων''.<br> '''κακοδαιμονέστερος, -έρα, -έρερον (adjectif)''' : Comparatif de ''κακοδαίμων''.<br> '''κακοήθης, -ης, -ες (adjectif)''' : malin.<br> '''κακοῦργος, -ύργα, -ῦργον (adjectif)''' : Dérangé ; malfaisant.<br> '''κακός, -ή, όν (adjectif)''' : Mauvais ; laid.<br> '''κακο- (préfixe)''' : mauvais.<br> '''κακοφωνία, -ας (nom commun) (f)''' : mauvaise sonorité.<br> '''κακκῶ (verbe)''' : déféquer ; chier.<br> '''κακῶς (adverbe)''' : mal.<br> '''κάλαθος, -άθου (nom commun) (m)''' : corbeille, panier.<br> '''κάλαϊς, -, - (adjectif)''' : bleu ciel.<br> '''κάλιον, -, - (adverbe)''' : Comparatif de ''καλῶς''.<br> '''κάλιστα, -, - (adverbe)''' Superlatif de ''καλῶς''.<br> '''καλλι- (préfixe)''' : beau.<br> '''καλλίπυγοσις, -όσεως (nom commun) (f)''' : .<br> '''καλλίπυγος, -ος, -ον (adjectif)''' : Qui a de belles fesses.<br> '''κάλλιστος, -, - (adjectif)''' : Superlatif de ''καλός''.<br> '''καλλίων, -, - (adjectif)''' : Comparatif de ''καλός''.<br> '''κάλλος, -ους (nom commun) (n)''' : beauté.<br> '''καλοήθης, -ης, -ες (adjectif)''' : bénin.<br> '''καλός, -ή, -όν (adjectif)''' : Beau ; bon.<br> '''κάλος, -η, -ον (adjectif)''' : Forme éolienne de ''καλός''.<br> '''καλϝός, -ή, -όν (adjectif)''' : Forme béotienne de ''καλός''.<br> '''κάλυμμα, -ύμματος (nom commun) (n)''' : couverture.<br> '''κάλυξ, -κος (nom commun) (m/f)''' : (Botanique) Calice des fleurs ; écale ou peau des fruits.<br> '''καλύπτω (verbe)''' : Couvrir ; envelopper, cacher.<br> '''καλῶς (adverbe)''' : Bien ; d’une belle manière.<br> '''καλῶ (verbe)''' : appeler.<br> '''καμάρα, -ας (nom commun) (f)''' : Voûte ; chambre voûtée.<br> '''καμάρη, -ης (nom commun) (f)''' : Forme ionienne de ''καμάρα''.<br> '''κάμαξ, -κος (nom commun) (m/f)''' : Perche. Hampe de la lance. (Marine) Gouvernail, manche de la rame.<br> '''κάμηλος, -ήλου (nom commun) (m/f)''' : chameau.<br> '''καμηλοπάρδαλις, -άλεως (nom commun) (f)''' : girafe.<br> '''κάμινος, -ίνου (nom commun) (m)''' : cheminée.<br> '''κάμπη, -ης (nom commun) (f)''' : chenille.<br> '''καμπή, -ῆς (nom commun) (f)''' : articulation.<br> '''κάμπος, -ους (nom commun) (n)''' : poisson marin.<br> '''κάπρος, -ου (nom commun) (n)''' : sanglier.<br> '''κάμπτω (verbe)''' : courber.<br> '''καμπύλη, -ης (nom commun) (f)''' : courbure.<br> '''καμπύλος, -η, -ον (adjectif)''' : Courbé, tordu. Voilé (en parlant d’une roue.)<br> '''καμπυλότης, -τος (nom commun) (f)''' : courbure.<br> '''κανδάκη, -ης (nom commun) (f)''' : candace.<br> '''κανάσσω (verbe)''' : cliquer.<br> '''καναχή, -ῆς (nom commun) (f)''' : clic.<br> '''καναχίζω (verbe)''' : claquer.<br> '''καναχηδά (adverbe)''' : .<br> '''καναχής, -ής, -ές (adjectif)''' : .<br> '''καναχῶ (verbe)''' : cliquer.<br> '''κἄν (conjonction)''' : .<br> '''κάνθαρος, -άρου (nom commun) (m)''' : cafard.<br> '''κανονικός, -ή, -όν (adjectif)''' : régulier.<br> '''κανονικῶς (adverbe)''' : régulièrement.<br> '''κανονικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''κανονικός''.<br> '''κανονικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''κανονικός''.<br> '''κανονικώτατα, -, - (adverbe)''' : Superlatif de ''κανονικῶς''.<br> '''κανονικώτερον, -, - (adverbe)''' : Comparatif de ''κανονικῶς''.<br> '''κανών, -όνος (nom commun) (m)''' : Tige de roseau, règle de maçon ou de charpentier. (Figuré) Règle, modèle ; principe.<br> '''κάνωπον, -ώπου (nom commun) (n)''' : chou-fleur.<br> '''καπηλεῖον, -ίου (nom commun) (n)''' : taverne.<br> '''καπηλεύω (verbe)''' : tenir une taverne.<br> '''καπηλικός, -ή, -όν (adjectif)''' : tavernier.<br> '''καπηλίς, -δος (nom commun) (f)''' : tavernière.<br> '''κάπηλος, -ήλου (nom commun) (m)''' : tavernier.<br> '''κάππα (nom commun) (n)''' : kappa.<br> '''κάπτω (verbe)''' : Avaler, prendre (une bouffée d’air).<br> '''κάρα, -τος (nom commun) (n)''' : Tête ; visage.<br> '''κάραϐος, -άϐου (nom commun) (m)''' : Crabe ; langouste. Scarabée ; escarbot.<br> '''κάρδαμον, -ου (nom commun) (n)''' : cresson.<br> '''καρδία, -ας (nom commun) (f)''' : cœur.<br> '''καρδιακός, -ή, -ός (adjectif)''' : cardiaque.<br> '''καρδιακῶς (adverbe)''' : cardiaquement.<br> '''καρδιακώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''καρδιακός''.<br> '''καρδιακώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''καρδιακός''.<br> '''καρδούχιος, -ος, -ον (adjectif)''' : kurde.<br> '''καρηϐάρεια, -ίας (nom commun) (f)''' : mal de tête.<br> '''κάρη, -τος (nom commun) (n)''' : Forme homérique et ionienne de ''κάρα''.<br> '''καρίς, -δος (nom commun) (f)''' : crevette.<br> '''καρκίνος, -ίνου (nom commun) (m)''' : (Zoologie) Crabe. (Astronomie) Constellation du Cancer. (Médecine) Chancre, tumeur, cancer. Pince pour saisir ou tenir les objets dans le feu. Compas. Sorte de bandage. (Habillement) Sorte de chaussure.<br> '''καρπάλιμος, -ος, -ον (adjectif)''' : rapide.<br> '''καρπός, -οῦ (nom commun) (m)''' : (Sens propre) Fruit, graine ; produit, récolte. (Sens figuré) Produit de quelque chose : enfant (produit du corps), poésie (produit de l'esprit), profit. (Anatomie) Poignet.<br> '''καρύκιον, -ίου (nom commun) (m)''' : Forme dorienne de ''κηρύκειον''.<br> '''κᾶρυξ, -άρυκος (nom commun) (m)''' : Forme dorienne de ''κῆρυξ''.<br> '''καρυόφυλλον, -ύλλου (nom commun) (n)''' : œillet.<br> '''καρύσσω (verbe)''' : Forme dorienne de ''κηρύσσω''.<br> '''κάρφος, -ους (nom commun) (n)''' : brindille.<br> '''κάρχαρος, -α, -ον (adjectif)''' : aiguisé.<br> '''καρχηδονιακός, -ή, -όν (adjectif)''' : carthaginois.<br> '''καρῶτον, -ώτου (nom commun) (n)''' : carotte.<br> '''κατά (adverbe ; préposition)''' (Devient ''κατ᾽'' devant un mot commençant par une voyelle à esprit doux, et ''καθ᾽'' devant un mot commençant par une voyelle à esprit rude.) : De haut en bas. En bas. En dessous, au fond. (Par extension) À fond, complètement. (Avec le génitif) marque l’origine, le point de départ ou le point d’arrivée. Contre, idée d’hostilité. (Avec l’accusatif) suivant, selon. Par, avec l'idée de succession (un par un). Pendant, avec l’idée de temps. Après, avec l’idée de succession temporelle (jour après jour). À travers, idée de transpercement, de part en part, d’un bout à l’autre.<br> '''καταϐιϐρώσκω (verbe)''' : .<br> '''καταγέλαστος, -ος, -ον (adjectif)''' : ridicule.<br> '''καταγλώττισμα, -ίσματος (nom commun) (n)''' : baiser intrabuccal.<br> '''καταγράφω (verbe)''' : condamner.<br> '''καταδικάζω (verbe)''' : condamner.<br> '''καταδίκη, -ης (nom commun) (f)''' : condamnation.<br> '''καταδικαστικός, -ή, -όν (adjectif)''' : condamnable.<br> '''κατάδικος, -ίκου (nom commun) (m/f)''' : condamné.<br> '''κατάδυσις, -ύσεως (nom commun) (f)''' : émergence.<br> '''καταδύομαι (verbe)''' : plonger.<br> '''κατακλύζω (verbe)''' : inonder.<br> '''κατάκλυσις, -ύσεως (nom commun) (f)''' : inondation.<br> '''κατακλυσμιαίος, -α, -ον (adjectif)''' : diluvien.<br> '''κατακλυσμικός, -ή, -όν (adjectif)''' : diluvien.<br> '''κατακλυσμικότατα, -, - (adverbe)''' : Superlatif de ''κατακλυσμικῶς''.<br> '''κατακλυσμικότερον, -, - (adverbe)''' : Comparatif de ''κατακλυσμικῶς''.<br> '''κατακλυσμικῶς (adverbe)''' : désastreusement.<br> '''κατακλυσμικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''κατακλυσμικός''.<br> '''κατακλυσμικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''κατακλυσμικός''.<br> '''κατακλυσμός, -οῦ (nom commun) (m)''' : déluge.<br> '''κατακτητής, -οῦ (nom commun) (m)''' : conquérant.<br> '''κατακτῶμαι (verbe)''' : conquérir.<br> '''καταλαμϐάνω (verbe)''' : saisir.<br> '''κατάλαψις, -άψεως (nom commun) (f)''' : Forme dorienne de ''κατάληψις''.<br> '''κατάληψις, -ήψεως (nom commun) (f)''' : Saisissement. Prise de possession, occupation.<br> '''κατάλογος, -όγου (nom commun) (m)''' : liste.<br> '''καταλογογράφησις, -ήσεως (nom commun) (f)''' : listage.<br> '''καταλογογραφῶ (verbe)''' : lister.<br> '''κατάπλασμα, -άσματος (nom commun) (n)''' : cataplasme.<br> '''κατάπτωσις, -ώσεως (nom commun) (f)''' : décadence.<br> '''κατάπυγον, -ύγου (nom commun) (n)''' : doigt d'honneur.<br> '''κατάρα, -ας (nom commun) (f)''' : malédiction.<br> '''καταριέμαι (verbe)''' : maudire.<br> '''καταστροφικός, -ή, -όν (adjectif)''' : désastreux.<br> '''καταστροφικότατα, -, - (adverbe)''' : Superlatif de ''καταστροφικῶς''.<br> '''καταστροφικότερον, -, - (adverbe)''' : Comparatif de ''καταστροφικῶς''.<br> '''καταστροφικῶς (adverbe)''' : désastreusement.<br> '''καταστροφικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''καταστροφικός''.<br> '''καταστροφικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''καταστροφικός''.<br> '''καταστροφή, -ῆς (nom commun) (f)''' : Désastre, destruction ; renversement.<br> '''κατάσχεσις, -έσεως (nom commun) (f)''' : confiscation.<br> '''κατάταξις, -άξεως (nom commun) (f)''' : mise en ordre.<br> '''κατατάσσω (verbe)''' : mettre en ordre.<br> '''καταφυγή, -ῆς (nom commun) (f)''' : .<br> '''καταφύγιον, -ίου (nom commun) (n)''' : abri.<br> '''κάτεργον, -έργου (nom commun) (n)''' : bagne.<br> '''κατηγορῶ (verbe)''' : accuser.<br> '''κατηγορία, -ας (nom commun) (f)''' : Charge ; accusation.<br> '''κατηγορίη, -ης (nom commun) (f)''' : Forme ionienne de ''κατηγορία''.<br> '''κατήχησις, -ήσεως (nom commun) (f)''' : .<br> '''κατηχίζω (verbe)''' : .<br> '''κατηχισμός, -οῦ (nom commun) (m)''' : .<br> '''κατηχιστής, -οῦ (nom commun) (m)''' : .<br> '''κατηχούμενος, -ένου (nom commun) (m)''' : .<br> '''κατηχῶ (verbe)''' : .<br> '''κάτοπτρον, -όπτρου (nom commun) (m)''' : miroir.<br> '''κατώτατος, -άτη, -ώτατον (adjectif)''' : .<br> '''κατώτερος, -έρα, -ώτερον (adjectif)''' : inférieur.<br> '''κατωτερότης, -τος (nom commun) (f)''' : infériorité.<br> '''κάτω (adverbe)''' : sous.<br> '''καῦκος, -ύκου (nom commun) (m)''' : .<br> '''καῦµα, -ύματος (nom commun) (n)''' : chaleur de l’été.<br> '''καύσις, -εως (nom commun) (f)''' : combustion.<br> '''καυστός, -ή, -όν (adjectif)''' : torride.<br> '''καυστῶς (adverbe)''' : torridement.<br> '''καυστώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''καυστός''.<br> '''καυστώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''καυστός''.<br> '''καυστώτατα, -, - (adverbe)''' : Superlatif de ''καυστῶς''.<br> '''καυστώτερον, -, - (adverbe)''' : Comparatif de ''καυστῶς''.<br> '''καύχημα, -ήματος (nom commun) (n)''' : vantardise.<br> '''καυχός, -οῦ (nom commun) (m)''' : Forme crétoise de ''χαλκός''.<br> '''καυχῶμαι (verbe)''' : .<br> '''κεγχριαῖος, -ία, -ῖον (adjectif)''' : granuleux.<br> '''κέγχρος, -ου (nom commun) (m)''' : (Botanique) Millet. Grain.<br> '''κεῖμαι (verbe)''' : être couché, se reposer ; être situé.<br> '''κείμενον, -ένου (nom commun) (n)''' : texte.<br> '''κεινός, -ή, -όν (adjectif)''' : Forme ionienne de ''κενός''.<br> '''κείρω (verbe)''' : .<br> '''κελαινός, -ή, -όν (adjectif)''' : obscur.<br> '''κελτικός, -ή, -όν (adjectif)''' : celte.<br> '''κελτικῶς (adverbe)''' : .<br> '''κελτικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''κελτικός''.<br> '''κελτικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''κελτικός''.<br> '''κελτιστί (adverbe)''' : en grec.<br> '''κενός, -ή, -όν (adjectif)''' : Vide. Vain, frivole.<br> '''κενϝός, -ή, -όν (adjectif)''' : Forme ancienne de ''κενός''.<br> '''κενεός, -ή, -όν (adjectif)''' : Forme poétique de ''κενός''.<br> '''κεντρικός, -ή, -όν (adjectif)''' : central.<br> '''κέντρον, -ου (nom commun) (n)''' : Aiguillon, dard. Pointe du compas, d’où centre du cercle.<br> '''κεντῶ (verbe)''' : piquer.<br> '''κενῶς (adverbe)''' : Habilement, sagement. Ingénieusement, finement.<br> '''κενώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''κενός''.<br> '''κενώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''κενός''.<br> '''κεραμεύς, -έως (nom commun) (m)''' : potier.<br> '''κεραμικός, -ή, -όν (adjectif)''' : d’argile.<br> '''κέραμος, -άμου (nom commun) (m)''' : argile.<br> '''κεράννυμι (verbe)''' : mélanger.<br> '''κέρας, -τος (nom commun) (n)''' : Corne. (Par analogie) Bras d’un fleuve ; aile d’une armée ou d’une flotte ; antenne ou vergue d’un navire ; pic d’une montagne. (Sophisme) argument cornu.<br> '''κεραός, -ά, -όν (adjectif)''' : Cornu ; fait de corne.<br> '''κεραϝός, -ά, -όν (adjectif)''' : Forme ancienne de ''κεραός''.<br> '''κερασός, -οῦ (nom commun) (m)''' : cerise.<br> '''κεραυνός, -οῦ (nom commun) (m)''' : foudre.<br> '''κέρκηρις, -ήρεως (nom commun) (m)''' : sarcelle.<br> '''κερκοπίθακος, -άκου (nom commun) (m)''' : Forme dorienne de ''κερκοπίθηκος''.<br> '''κερκοπίθηκος, -ήκου (nom commun) (m)''' : cercopithèque.<br> '''κέρκος, -ου (nom commun) (f)''' : queue.<br> '''κέρκωψ, -πος (nom commun) (m)''' : singe à longue queue.<br> '''κεστός, -ή, -όν (adjectif)''' : brodé.<br> '''κεστότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''κεστός''.<br> '''κεστότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''κεστός''.<br> '''κεστῶς (adverbe)''' : .<br> '''κεφαλαία, -ας (nom commun) (f)''' : mal de tête.<br> '''κεφαλή, -ῆς (nom commun) (f)''' : tête.<br> '''κεφάλιον, -ίου (nom commun) (n)''' : petite tête.<br> '''κεφαλίς, -δος (nom commun) (f)''' : bonnet, chapeau.<br> '''κηδεμών, -όνος (nom commun) (m)''' : .<br> '''κηκίς, -ῖδος (nom commun) (f)''' : Jet. Teinture tiré de la galle.<br> '''κηλίς, -ῖδος (nom commun) (f)''' : .<br> '''κνημίς, -ῖδος (nom commun) (f)''' : .<br> '''κρηπίς, -ῖδος (nom commun) (f)''' : .<br> '''κῆπος, -ήπου (nom commun) (m)''' : jardin ; sorte de singe.<br> '''κηρός, -οῦ (nom commun) (m)''' : cire.<br> '''κῆρ, -ος (nom commun) (n)''' : cœur.<br> '''κῆρυγμα, -ύγματος (nom commun) (n)''' : proclamation à voix haute.<br> '''κηρύκειον, -ίου (nom commun) (m)''' : caducée.<br> '''κῆρυξ, -ήρυκος (nom commun) (m)''' : héraut.<br> '''κηρύσσω (verbe)''' : annoncer.<br> '''κηρύττω (verbe)''' : Forme attique de ''κηρύσσω''.<br> '''κηφήν, -ῆνος (nom commun) (m)''' : bourdon.<br> '''κηφηνώδης, -ης, -ες (adjectif)''' : .<br> '''κιϐδηλεύω (verbe)''' : falsifier.<br> '''κιϐδηλία, -ας (nom commun) (f)''' : falsification.<br> '''κίϐδηλος, -ος, -ου (adjectif)''' : falsifié ; frauduleux.<br> '''κιϐδηλότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''κίϐδηλος''.<br> '''κιϐδηλότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''κίϐδηλος''.<br> '''κιϐδήλως (adverbe)''' : frauduleusement.<br> '''κιϐωτός, -οῦ (nom commun) (f)''' : arche.<br> '''κιγκλίς, -δος (nom commun) (f)''' : bergeronnette.<br> '''κιδαφεύω (verbe)''' : ruser.<br> ''' κίδαφος, -άφη, -ίδαφον (adjectif)''' : rusé.<br> '''κίδαφότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''κίδαφος''.<br> '''κίδαφότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''κίδαφος''.<br> '''κιδάφως (adverbe)''' : frauduleusement.<br> '''κικκάϐη, -ης (nom commun) (f)''' : .<br> '''κῖκυς, -ίκυος (nom commun) (f)''' : force ; vigueur.<br> '''κιθάρα, -ας (nom commun) (f)''' : cithare.<br> '''κιθάρη, -ης (nom commun) (f)''' : Forme ionienne de ''κιθάρα''.<br> '''κιθών, -ῶνος (nom commun) (m)''' : Forme ionienne de ''χιτών''.<br> '''κίνδυνος, -ύνου (nom commun) (m)''' : Danger, risque ; entreprise hasardeuse.<br> '''κινηθμός, -οῦ (nom commun) (m)''' : .<br> '''κίνημα, -ήματος (nom commun) (n)''' : mouvement.<br> '''κίνησις, -ήσεως (nom commun) (f)''' : mouvement.<br> '''κινητέον, -ου (nom commun) (n)''' : .<br> '''κινητήρ, -ῆρος (nom commun) (m)''' : .<br> '''κινητής, -οῦ (nom commun) (m)''' : .<br> '''κινητήριος, -α, -ον (adjectif)''' : .<br> '''κινητικός, -ή, -όν (adjectif)''' : .<br> '''κινητός, -ή, -όν (adjectif)''' : .<br> '''κίνητρον, -ήτρου (nom commun) (n)''' : .<br> '''κίνναμον, -άμου (nom commun) (n)''' : cannelle.<br> '''κινῶ (verbe)''' : bouger.<br> '''κιξάλλης, -ου (nom commun) (m)''' : voleur de grand chemin.<br> '''κίρκος, -ου (nom commun) (m)''' : (ornithologie) Faucon. Anneau.<br> '''κιρρός, -ά, -όν (adjectif)''' : brun-roux.<br> '''κισσαϐίζω (verbe)''' : .<br> '''κῖσσα, -ης (nom commun) (f)''' : geai des chênes.<br> '''κίσσα, -ης (nom commun) (f)''' : pie.<br> '''κισσός, -οῦ (nom commun) (m)''' : lierre.<br> '''κισσοστεφής, -ής, -ές (adjectif)''' : couronné de lierre.<br> '''κισσῶ (verbe)''' : .<br> '''κίττα, -ης (nom commun) (f)''' : Forme attique de ''κίσσα''.<br> '''κιτών, -ῶνος (nom commun) (m)''' : Forme dorienne de ''χιτών''.<br> '''κιχόρη, -ης (nom commun) (f)''' : chicorée.<br> '''κλάδος, -ου (nom commun) (m)''' : Branche (d'arbre), rameau.<br> '''κλαΐς, -δός (nom commun) (f)''' : Forme dorienne de ''κλείς''.<br> '''κλᾶϊς, -άϊδος (nom commun) (f)''' : Forme éolienne de ''κλείς''.<br> '''κλαίω (verbe)''' : Pleurer sur, déplorer. Appeler en criant. Se mettre en pleurs.<br> '''κλᾶμμα, -άμματος (nom commun) (f)''' : Forme éolienne de ''κλῆμα''.<br> '''κλαστός, -ή, -όν (adjectif)''' : brisé, cassé.<br> '''κλαυθμυρίζω (verbe)''' : faire pleurer.<br> '''κλαῦμα, -ύματος (nom commun) (n)''' : pleur.<br> '''κλαυσίγελως, -τος (nom commun) (m)''' : .<br> '''κλαυστός, -ή, -όν (adjectif)''' : Pleuré. Funèbre, triste.<br> '''κλάω (verbe)''' : Briser, casser.<br> '''κλεῖθρον, -ίθρου (nom commun) (n)''' : serrure.<br> '''κλειθροποιός, -οῦ (nom commun) (m)''' : serrurier.<br> '''κλείς, -δός (nom commun) (f)''' : clé.<br> '''κλειτορίς, -δος (nom commun) (f)''' : clitoris.<br> '''κλείω (verbe)''' : fermer.<br> '''κλέπτης, -ου (nom commun) (m)''' : voleur.<br> '''κλέπτω (verbe)''' : voler. (dérober)<br> '''κληΐς, -δός (nom commun) (f)''' : Forme ionienne de ''κλείς''.<br> '''κλῄς, -δός (nom commun) (f)''' : Forme attique de ''κλείς''.<br> '''κλέος, -ους (nom commun) (n)''' : gloire.<br> '''κλεψύδρα, -ας (nom commun) (m)''' : clepsydre.<br> '''κλέω (verbe)''' : être célèbre.<br> '''κλῆμα, -ήματος (nom commun) (n)''' : pampre.<br> '''κληματίζω (verbe)''' : .<br> '''κληματικός, -ή, -όν (adjectif)''' : .<br> '''κλημάτινος, -η, ον (adjectif)''' : .<br> '''κληματίς, -δος (nom commun) (f)''' : Diminutif de ''κλῆμα''.<br> '''κληματῖτις, -ίτιδος (nom commun) (f)''' : .<br> '''κληματόδεσις, -εως (nom commun) (f)''' : .<br> '''κληματοειδής, -ής, -ές (adjectif)''' : .<br> '''κληματόεις, -εσσα, εν (adjectif)''' : .<br> '''κληματόομαι (verbe)''' : .<br> '''κληματώδης, -ης, -ες (adjectif)''' : .<br> '''κλήρωσις, -ώσεως (nom commun) (f)''' : .<br> '''κληρονομία, -ας (nom commun) (f)''' : héritage.<br> '''κληρονομικότης, -τος (nom commun) (f)''' : hérédité.<br> '''κληρονομικός, -ή, -όν (adjectif)''' : héréditaire.<br> '''κληρονόμος, -ου (nom commun) (m)''' : héritier.<br> '''κληρονομῶ (verbe)''' : hériter.<br> '''κλῆρος, -ήρου (nom commun) (m)''' : .<br> '''κληρόω (verbe)''' : .<br> '''κλητήρ, -ῆρος (nom commun) (m)''' : Témoin ; héraut.<br> '''κλίμα, -τος (nom commun) (n)''' : Inclinaison, pente. Inclinaison de la Terre, latitude, climat.<br> '''κλῖμαξ, -ίμακος (nom commun) (f)''' : Escalier ; échelle.<br> '''κλίνη, -ης (nom commun) (f)''' : lit.<br> '''κλίνω (verbe)''' : Pencher. Pencher sur, s’appuyer sur. Coucher, allonger, étendre.<br> '''κλίννω (verbe)''' : Forme éolienne de ''κλίνω''.<br> '''κλίσις, -εως (nom commun) (f)''' : déclinaison.<br> '''κλίτος, -ους (nom commun) (n)''' : allée.<br> '''κλῖτος, -ίτους (nom commun) (n)''' : .<br> '''κλιτύς, -ος (nom commun) (n)''' : Forme béotienne de ''κλῖτος''.<br> '''κλόνις, -ος (nom commun) (f)''' : sacrum.<br> '''κλόνος, -ου (nom commun) (m)''' : Confusion ; excitation.<br> '''κλύδων, -ος (nom commun) (m)''' : Vague. Trouble, agitation, mouvement tumultueux.<br> '''κλύζω ‎(verbe)''' : Laver, nettoyer. Battre de ses flots, baigner de ses flots.<br> '''κλυστήρ, -έρος (nom commun) (m)''' : seringue.<br> '''κλύω (verbe)''' : entendre.<br> '''κλωβός, -ϐοῦ (nom commun) (m)''' : cage à oiseau.<br> '''κλών, -ός (nom commun) (m)''' : .<br> '''κλώψ, -πός (nom commun) (m)''' : voleur.<br> '''κλῶ (verbe)''' : S’entendre nommer ; entendre parler de soi.<br> '''κνέφας, -ους (nom commun) (n)''' : Aube ; crépuscule, obscurité.<br> '''κνῆκος, -ήκου (nom commun) (f)''' : carthame des teinturiers.<br> '''κνήμη, -ης (nom commun) (f)''' : jambe.<br> '''κνίδη, -ης (nom commun) (f)''' : ortie.<br> '''κνίδωσις, -ώσεως (nom commun) (f)''' : urticaire.<br> '''κνίζω (verbe)''' : Gratter. ; taillader.<br> '''κοϐαλεία, -ας (nom commun) (f)''' : .<br> '''κοϐαλεύω (verbe)''' : .<br> '''κοϐαλίκευμα, -ύματος (nom commun) (n)''' : .<br> '''κοϐαλισμός, -οῦ (nom commun) (m)''' : .<br> '''κόϐαλος, -άλου (nom commun) (m)''' : Chenapan ; garnement. Gobelin.<br> '''κοθαρός, -ά, -όν (adjectif)''' : Forme dorienne de ''καθαρός''.<br> '''κόθαρος, -ά, -όν (adjectif)''' : Forme éolienne de ''καθαρός''.<br> '''κοιλάς, -δος (nom commun) (f)''' : vallée.<br> '''κοῖλος, -ίλη, -ῖλον (adjectif)''' : creux.<br> '''κοῖλος, -ίλου (nom commun) (m)''' : creux.<br> '''κοιμάω (verbe)''' : (Actif) Mettre sur une couche, mettre au lit. (Passif) Faire reposer, faire dormir. (Passif, par euphémisme) Faire mourir. (Figuré) Assoupir, apaiser, calmer.<br> '''κοιμέω (verbe)''' : Forme ionienne de ''κοιμάω''.<br> '''κοιμητήριον, -ου (nom commun) (n)''' : Dortoir ; cimetière.<br> '''κοιμίζω (verbe)''' : endormir.<br> '''κοινοϐουλευτικός, -ή, -όν (adjectif)''' : parlementaire.<br> '''κοινοϐούλιον, -ίου (nom commun) (n)''' : parlement.<br> '''κοινός, -ή, -όν (adjectif)''' : commun.<br> '''κοινότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''κοινός''.<br> '''κοινότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''κοινός''.<br> '''κοινωνία, -ας (nom commun) (f)''' : société.<br> '''κοίνωσις, -ώσεως (nom commun) (f)''' : .<br> '''κοινῶς (adverbe)''' : communément.<br> '''κοινῶ (verbe)''' : Communiquer. Rendre commun à, faire savoir. Mettre en communication, unir. Rendre commun à tous, prostituer, profaner, souiller. Unir, assembler, ajuster (une pièce d'une construction). (Moyen) Communiquer, mettre en commun. <br> '''κοῖος, -ίη, -ῖον (adjectif)''' : Forme ionienne de ''ποῖος''.<br> '''κοῖτος, -ίτου (nom commun) (m)''' : Lit, couche.<br> '''κόκκος, -ου (nom commun) (m)''' : Graine, grain, pépin. (Entomologie) Cochenille, kermès, galle du chêne kermès. (par analogie) Pilule. (par analogie) Testicules.<br> '''κόλλαθον, -άθου (nom commun) (n)''' : .<br> '''κολοιός, -οῦ (nom commun) (m)''' : choucas.<br> '''κόκκυξ, -υγος (nom commun) (m)''' : coucou, coccyx.<br> '''κόκκυ (onomatopée)''' : cri du coucou.<br> '''κωκύω (verbe)''' : crier, se lamenter.<br> '''κολακεία, -ας (nom commun) (f)''' : flatterie.<br> '''κολακευτικός, -ή, -όν (adjectif)''' : flatteur.<br> '''κολακευτικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''κολακευτικός''.<br> '''κολακευτικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''κολακευτικός''.<br> '''κολακευτικῶς (adverbe)''' : flatteusement.<br> '''κολακεύω (verbe)''' : flatter.<br> '''κόλαξ, -κος (nom commun) (m)''' : flatteur.<br> '''κολάπτω (verbe)''' : frapper.<br> '''κόλασις, -άσεως (nom commun) (f)''' : punition.<br> '''κολαφίζω (verbe)''' : gifler.<br> '''κόλαφος, -άφου (nom commun) (m)''' : gifle.<br> '''κολεός, -οῦ (nom commun) (m)''' : Fourreau ; vagin.<br> '''κόλλα, -ης (nom commun) (f)''' : colle.<br> '''κόλλαϐος, -άϐου (nom commun) (m)''' : Gâteau, petit pain. Cheville qui attache les cordes de la lyre.<br> '''κολλάω (verbe)''' : coller.<br> '''κόλλιξ, -κος (nom commun) (m)''' : petit pain.<br> '''κολλύρα, -ας (nom commun) (f)''' : petit pain.<br> '''κολλῶ (verbe)''' : .<br> '''κολοϐός, -ή, -όν (adjectif)''' : écorné, tronqué ; mutilé.<br> '''κολοιός, -οῦ (nom commun) (m)''' : geai.<br> '''κόλον, -ου (nom commun) (n)''' : membre, extrémité ; côlon.<br> '''κολοκύνθη, - (nom commun) (f)''' : .<br> '''κολοκυνθίς, - (nom commun) (f)''' : .<br> '''κολοσσός, -οῦ (nom commun) (m)''' : colosse.<br> '''κολοττός, -οῦ (nom commun) (m)''' : Forme attique de ''κολοσσός''.<br> '''κολοφών, -ῶνος (nom commun) (m)''' : Sommet. (Figuré) Achèvement, couronnement. Balle de jeu.<br> '''κόλπος, -ου (nom commun) (m)''' : (Anatomie) Sein (de la mère ou de la nourrice). Utérus. Pli, creux d’un vêtement. Repli, renfoncement de la mer entre deux vagues. Sein de la terre, d’où Enfers. Golfe. Gouffre, cavité ; vallée profonde.<br> '''κολχικός, -ή, -όν (adjectif)''' : colchien.<br> '''κολώνη, -ης (nom commun) (f)''' : monticule, tertre ; tumulus.<br> '''κόμϐος, ου (nom commun) (m)''' : bande.<br> '''κοµικός, -ή, -όν (adjectif)''' : comique.<br> '''κοµικότατα, -, - (adverbe)''' : Superlatif de ''κοµικῶς''.<br> '''κοµικότερον, -, - (adverbe)''' : Comparatif de ''κοµικῶς''.<br> '''κοµικῶς (adverbe)''' : comiquement.<br> '''κοµικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''κοµικός''.<br> '''κοµικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''κοµικός''.<br> '''κομπάζω (verbe)''' : hâbler.<br> '''κομπαστής, -οῦ (nom commun) (m)''' : hâbleur.<br> '''κομψός, -ή, -όν (adjectif)''' : élégant.<br> '''κομψότατα, -, - (adverbe)''' : Superlatif de ''κομψῶς''.<br> '''κομψότερον, -, - (adverbe)''' : Comparatif de ''κομψῶς''.<br> '''κομψότης, -τος (nom commun) (f)''' : élégance.<br> '''κομψῶς (adverbe)''' : élégamment.<br> '''κομψώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''κομψός''.<br> '''κομψώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''κομψός''.<br> '''κονδυλισμίς, -δος (nom commun) (f)''' : chiquenaude ; pichenette.<br> '''κόνδυ, -ος (nom commun) (n)''' : somm e.<br> '''κονία, -ας (nom commun) (f)''' : poussière.<br> '''κονίη, -ης (nom commun) (f)''' : Forme homérique et ionienne de ''κονία''.<br> '''κόνικλος, -ίκλου (nom commun) (m)''' : lapin.<br> '''κόνις, -εως (nom commun) (f)''' : cendre ; poussière.<br> '''κονίς, -δος (nom commun) (f)''' : lente.<br> '''κοντά (adverbe)''' : près ; à proximité.<br> '''κοντινός, -ή, -όν (adjectif)''' : proche.<br> '''κοντινῶς (adverbe)''' : .<br> '''κοντινώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''κοντινός''.<br> '''κοντινώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''κοντινός''.<br> '''κογχύλιον, -ίου (nom commun) (n)''' : coquillage.<br> '''κοπριά, -ᾶς (nom commun) (f)''' : fumier.<br> '''κόπρος, -ου (nom commun) (m)''' : excrément.<br> '''κόρα, -ας (nom commun) (f)''' : Forme éolienne de ''κόρη''.<br> '''κόραξ, -κος (nom commun) (m)''' : corbeau.<br> '''κορέννυμι (verbe)''' : rassasier ; (Au passif et au moyen) Être rassasié. Avoir le dégoût de.<br> '''κόρευμα, -ύματος (nom commun) (n)''' : virginité.<br> '''κορεύομαι (verbe)''' : être vierge.<br> '''κόρη, -ης (nom commun) (f)''' : jeune fille.<br> '''κορίαννον, -άννου (nom commun) (n)''' : coriandre.<br> '''κορίζομαι (verbe)''' : caresser.<br> '''κορμός, -οῦ (nom commun) (m)''' : .<br> '''κόρος, -ου (nom commun) (m)''' : Jeune garçon ; satiété, dédain.<br> '''κόρυζα, -ης (nom commun) (f)''' : coryza.<br> '''κόρυς, -θος (nom commun) (f)''' : Tête ; casque.<br> '''κορώνη, -ης (nom commun) (f)''' : corneille.<br> '''κορωνός, -ή, -όν (adjectif)''' : courbe ; recourbé.<br> '''κόσμημα, -ήματος (nom commun) (n)''' : bijou.<br> '''κοσμητικός, -ή, -όν (adjectif)''' : Décoratif ; ordonné.<br> '''κοσμητής, -οῦ (nom commun) (m)''' : Ordonnateur ; arrangeur.<br> '''κόσμος, -ου (nom commun) (m)''' : Ordre. Monde ; univers.<br> '''κόσσυκος, -ύκου (nom commun) (m)''' : Forme de ''κόσσυϕος''.<br> '''κόσσυϕος, -ύϕου (nom commun) (m)''' : merle.<br> '''κόσος, -η, -ον (adjectif)''' : Forme ionienne de ''πόσος''.<br> '''κόττος, -ου (m)''' : coq.<br> '''κόττυϕος, -ύϕου (nom commun) (m)''' : Forme attique de ''κόσσυϕος''.<br> '''κοτύλη, -ης (nom commun) (f)''' : écuelle.<br> '''κουρεύς, -έως (nom commun) (m)''' : barbier.<br> '''κουρεῖον, -ίου (nom commun) (n)''' : boutique du barbier.<br> '''κούρη, -ης (nom commun) (f)''' : Forme ionienne de ''κόρη''.<br> '''κοῦρος, -ύρου (nom commun) (m)''' : Forme ionienne de ''κόρος''.<br> '''κοῦ (adverbe interrogatif)''' : Forme ionienne de ''ποῦ''.<br> '''κοῦφος, -ύφη, -ῦφον (adjectif)''' : léger.<br> '''κουφότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''κοῦφος''.<br> '''κουφότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''κοῦφος''.<br> '''κούφως (adverbe)''' : légèrement.<br> '''κόφινος, -ίνου (nom commun) (m)''' : corbeille.<br> '''κοχλιάριον, -ίου (nom commun) (n)''' : cuillère.<br> '''κοχλίας, -ου (nom commun) (m)''' : escargot.<br> '''κρα (onomatopée)''' : croa.<br> '''κράϐατος, -άτου (nom commun) (m)''' : Forme macédonienne de ''κράϐϐατος''.<br> '''κράϐϐατος, -άτου (nom commun) (m)''' : grabat.<br> '''κραιπάλη, -ης (nom commun) (f)''' : ivresse.<br> '''κραίνω (verbe)''' : Commander, gouverner.<br> '''κράμϐη, -ης (nom commun) (f)''' : chou.<br> '''κράμϐος, -η, -ον (f)''' : fort (en parlant de la voix ou du son).<br> '''κρανίον, -ου (nom commun) (n)''' : crâne.<br> '''κρανοκοπέω (verbe)''' : décapiter.<br> '''κράνος, -ους (nom commun) (n)''' : casque.<br> '''κρᾶσις, -άσεως (nom commun) (n)''' : mélange de deux ou plusieurs choses.<br> '''κράτειρα, -ίρας (nom commun) (f)''' : dirigeante.<br> '''κράτος, -ους (nom commun) (n)''' : Force du corps, vigueur, solidité. Domination, puissance.<br> '''κράτωρ, -ορος (nom commun) (m)''' : dirigeant.<br> '''κραυγάζω (verbe)''' : crier.<br> '''κραυγή, -ῆς (nom commun) (f)''' : cri.<br> '''κρέας, -ατος (nom commun) (n)''' : viande.<br> '''κρεῖας, -ίατος (nom commun) (n)''' : Forme homérique de ''κρέας''.<br> '''κρείουσα, -ας (nom commun) (f)''' : cri.<br> '''κρείσσων, -ων, -ον (adjectif)''' : maîtresse ; souveraine.<br> '''κρείων, -οντος (nom commun) (m)''' : seigneur, maître ; souverain.<br> '''κρέξ, -κου (nom commun) (m)''' : râle (oiseau).<br> '''κρέων, -οντος (nom commun) (m)''' : Forme homérique de ''κρείων''.<br> '''κρημνός, -οῦ (nom commun) (m)''' : falaise, précipice.<br> '''κρηναῖος, -ία, -ῖον (adjectif)''' : .<br> '''κρήνη, -ης (nom commun) (m)''' : Source, puits ; fontaine. (Poétique) (Au pluriel) Eau.<br> '''κρηπίς, -ῖδος (nom commun) (f)''' : pantoufle.<br> '''κρῆσις, -ήσεως (nom commun) (n)''' : Forme ionienne de ''κρᾶσις''.<br> '''κρῆς, -ήτος (nom commun) (n)''' : Forme dorienne de ''κρέας''.<br> '''κρίϐανος, -άνου (nom commun) (m)''' : braséro ; four à pain.<br> '''κρίκος, -ου (nom commun) (m)''' : anneau.<br> '''κρῖμα, -ίματος (nom commun) (n)''' : Objet de contestation, contestation, querelle. (Par suite) Jugement, décision judiciaire. Condamnation, peine. (Par extension) Jugement, Décision. Action de juger.<br> '''κριός, -οῦ (nom commun) (m)''' : bélier.<br> '''κρίνω (verbe)''' : décider.<br> '''κρίσις, -ίσεως (nom commun) (f)''' : décision.<br> '''κριτήριον, -ίου (nom commun) (n)''' : test.<br> '''κριτήρ, -ῆρος (nom commun) (m)''' : interprète.<br> '''κριτής, -οῦ (nom commun) (m)''' : juge.<br> '''κριτικός, -ή, -όν (adjectif)''' : décisif.<br> '''κριτικῶς (adverbe)''' : décisivement.<br> '''κριτικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''κριτικός''.<br> '''κριτικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''κριτικός''.<br> '''κροκόδειλος, -ίλου (nom commun) (m)''' : crocodile.<br> '''κρόμμυον, -ύου (nom commun) (n)''' : ognon.<br> '''κρόμυον, -ύου (nom commun) (n)''' : Variante de ''κρόμμυον''.<br> '''κρόταφος, -άφου (nom commun) (m)''' : tempe.<br> '''κροῦσις, -ύσεως (nom commun) (f)''' : Choc, collision ; impact, percussion.<br> '''κρούω (verbe)''' : heurter, choquer. Frapper l’un contre l’autre. Frapper les cordes d’un instrument. Heurter ou pousser pour mettre en mouvement. Heurter avec le doigt pour l’éprouver et le faire résonner. (Figuré) Piquer, chatouiller en parlant de sensations physiques.<br> '''κρυμός, -οῦ (nom commun) (m)''' : gel.<br> '''κρύος, -ους (nom commun) (n)''' : froid glacial. Frisson (de crainte).<br> '''κρύσταλλος, -άλλου (nom commun) (m)''' : Eau congelée ; verre transparent.<br> '''κροκόδειλος, -ίλου (nom commun) (m)''' : crocodile.<br> '''κρόκος, -ου (nom commun) (m)''' : safran.<br> '''κρυπτός, -ός, -όν (adjectif)''' : caché, secret.<br> '''κρύπτω (verbe)''' : cacher.<br> '''κρυφᾷ (adverbe)''' : Forme dorienne de ''κρυφῇ''.<br> '''κρυφῇ (adverbe)''' : secrètement.<br> '''κρύφος, -ου (nom commun) (f)''' : Action de cacher ; cachette.<br> '''κρωγμός, -οῦ (nom commun) (m)''' : croassement.<br> '''κρώζω (verbe)''' : croasser.<br> '''κρωσσίον, -ου (nom commun) (n)''' : cruche.<br> '''κρωσσός, -οῦ (nom commun) (m)''' : jarre ; urne.<br> '''κτείνω (verbe)''' : tuer.<br> '''κτείς, -ενός (nom commun) (m)''' : Peigne. Râteau. (Au pluriel) Doigts.<br> '''κτένιον, -ίου (nom commun) (m)''' : Diminutif de ''κτείς''.<br> '''κτῆνος, -ήνους (nom commun) (n)''' : (Au pluriel) Bétail. (Au singulier) Bête domestique.<br> '''κτίριον, -ίου (nom commun) (n)''' : bâtiment.<br> '''κτυπέω (verbe)''' : claquer.<br> '''κτύπημα, -ήματος (nom commun) (n)''' : claquement.<br> '''κτῶμαι (verbe)''' : acquérir.<br> '''κυανός, -ή, -όν (adjectif)''' : bleu.<br> '''κυϐέρνησις, -ήσεως (nom commun) (f)''' : pilotage ; gouvernement.<br> '''κυϐερνήτης, -ου (nom commun) (m)''' : pilote ; gouverneur.<br> '''κυϐερνητικός, -ή, -όν (adjectif)''' : pilotable ; gouvernemental.<br> '''κυϐερνισμός, -οῦ (nom commun) (m)''' : pilotage ; gouvernement.<br> '''κυϐερνῶ (verbe)''' : piloter ; gouverner.<br> '''κῦδος, -ύδους (nom commun) (n)''' : gloire ; renommée.<br> '''κυῶ (verbe)''' : .<br> '''κύημα, -ήματος (nom commun) (n)''' : vague.<br> '''κύησις, -ήσεως (nom commun) (f)''' : grossesse.<br> '''κύκλος, -ου (nom commun) (m)''' : cercle ; rond.<br> '''κυκλῶ (verbe)''' : Tourner, rouler. Envelopper, cerner.<br> '''κύκλωμα, -ώματος (nom commun) (n)''' : circuit.<br> '''κυκλών, -ῶνος (nom commun) (m)''' : cyclone.<br> '''κύκνος, -ου (nom commun) (m)''' : cygne.<br> '''κυλινδρικός, -ή, -όν (adjectif)''' : cylindrique.<br> '''κύλινδρος, -ίνδρου (nom commun) (m)''' : cylindre.<br> '''κυλίνδω (verbe)''' : rouler.<br> '''κύλιξ, -κος (nom commun) (f)''' : coupe (récipient).<br> '''κυλλός, -ή, -όν (adjectif)''' : Forme chypriote de ''χωλός''.<br> '''κῦμα, -ύματος (nom commun) (n)''' : onde ; vague.<br> '''κυναλώπηξ, -εκος (nom commun) (f)''' : .<br> '''κυνηγός, -οῦ (nom commun) (m)''' : chasseur.<br> '''κυνηγῶ (verbe)''' : chasser.<br> '''κύνικλος, -ίκλου (nom commun) (m)''' : Forme de ''κόνικλος''.<br> '''κυνικός, -ή, -όν (adjectif)''' : canin ; (Philosophie) cynique.<br> '''κυπάρισσος, -ίσσου (nom commun) (f)''' : cyprès.<br> '''κυπάριττος, -ίττου (nom commun) (f)''' : Forme attique de ''κυπάρισσος''.<br> '''κυπρῖνος, -ίνου (nom commun) (m)''' : carpe.<br> '''κύπτω (verbe)''' : se baisser en avant. Baisser la tête (ou les yeux) de honte.<br> '''κυρία, -ας (nom commun) (f)''' : maîtresse ; souveraine.<br> '''κυριακός, -ή, -όν (adjectif)''' : seigneurial.<br> '''κύριος, -ίου (nom commun) (m)''' : maître ; souverain.<br> '''κύρος, -ους (nom commun) (n)''' : prestige.<br> '''κῦρος, -ύρου (nom commun) (m)''' : décret.<br> '''κῦρρος, -ύρρου (nom commun) (m)''' : Forme thessalienne de ''κύριος''.<br> '''κύρωσις, -ώσεως (nom commun) (f)''' : sanction.<br> '''κυρῶ (verbe)''' : confirmer, ratifier ; sanctionner.<br> '''κυσός, -οῦ (nom commun) (m)''' : sexe de la femme.<br> '''κύστιγξ, -γος (nom commun) (f)''' : vésicule.<br> '''κύστις, -εως (nom commun) (f)''' : sac ; (Au pluriel) Poches sous les yeux.<br> '''κύσσω (verbe)''' : Forme poétique de ''κύσω''.<br> '''κύσω (verbe)''' : donner un baiser.<br> '''κύτος, -ους (nom commun) (n)''' : Creux d'un navire, d'un bouclier, d'une cuirasse. Objet creux. Qui recouvre ou enveloppe.<br> '''κυφός, -ή, -όν (adjectif)''' : Arqué, bossu. Courbé.<br> '''κυφότατος, -έρα, -ότερον (adjectif)''' : Comparatif de ''κυφός''.<br> '''κυφότερος, -άτη, -ότατον (adjectif)''' : Superlatif de ''κυφός''.<br> '''κύφων, -ονος (nom commun) (m)''' : pilori.<br> '''κύφωσις, -ώσεως (nom commun) (f)''' : .<br> '''κυφῶς (adverbe)''' : .<br> '''κύψελος, -έλου (nom commun) (m)''' : martinet (oiseau).<br> '''κύων, -ός (nom commun) (m/f)''' : chien(ne).<br> '''κωδωνίζω (verbe)''' : sonner les cloches.<br> '''κωδώνιον, -ίου (nom commun) (n)''' : clochette.<br> '''κωδωνόκροτος, - ()''' : .<br> '''κωδωνοφαλαρόπωλος, - ()''' : .<br> '''κωδωνοφορέω (verb)''' : .<br> '''κώδων, -ος (nom commun) (m)''' : cloche.<br> '''κωκύω (verbe)''' : .<br> '''κώληψ, -πος (nom commun) (f)''' : jarret.<br> '''κωλοϐαθριστής, -οῦ (nom commun) (m)''' : Acrobate marchant sur des échasses.<br> '''κωλόϐαθρον, -άθρου (nom commun) (n)''' : échasse.<br> '''κῶλον, -ώλου (nom commun) (n)''' : .<br> '''κώμη, -ης (nom commun) (f)''' : village ; quartier.<br> '''κωμικός, -ή -όν (adjectif)''' : comique.<br> '''κωµικότατα, -, - (adverbe)''' : Superlatif de ''κωµικῶς''.<br> '''κωµικότερον, -, - (adverbe)''' : Comparatif de ''κωµικῶς''.<br> '''κωµικῶς (adverbe)''' : comiquement.<br> '''κωµικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''κωµικός''.<br> '''κωµικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''κωµικός''.<br> '''κῶμος, -ώμου (nom commun) (m)''' : Festin, banquet. (Par extension) Troupe impétueuse (en parlant des Érinyes), bande.<br> '''κωμόπολις, -όλεως (nom commun) (n)''' : bourgade.<br> '''κωμῳδία, -ας (nom commun) (f)''' : poésie satirique.<br> '''κωνωπεῖον, -ίου (nom commun) (n)''' : moustiquaire.<br> '''κώνωψ, -ωπος (nom commun) (m)''' : cousin (genre de moustique) ; moucheron.<br> '''κώπα, -ας (nom commun) (f)''' : Forme dorienne de ''κώπη''.<br> '''κωπέω (f)''' : ramer.<br> '''κώπη, -ης (nom commun) (f)''' : Anse, poignée (d’une rame), manche. Rame.<br> '''κωπίον, -ίου (nom commun) (n)''' : Diminutif de ''κώπη''.<br> '''κώρα, -ας (nom commun) (f)''' : Forme dorienne de ''κόρη''.<br> '''κῶρος, -ώρου (nom commun) (m)''' : Forme dorienne de ''κόρος''.<br> '''κῶς (adverbe)''' : Forme ionienne de ''πῶς''.<br> '''κώταλις, - (nom commun) (f)''' : cuillère.<br> '''κωφός, -ή -όν (adjectif)''' : sourd.<br> '''Καικιλία, -ας (nom propre) (f)''' : Cécile.<br> '''Καικίλιος, -ίου (nom propre) (m)''' : Cécilius.<br> '''Κάϊν (nom propre) (m)''' : Caïn.<br> '''Καινὴ Διαθήκη (locution nominale) (f)''' : Nouveau Testament.<br> '''Καῖσαρ, -ίσαρος (nom propre) (m)''' : César.<br> '''Καλλίας, -ου (nom propre) (m)''' : Callias.<br> '''Καλλικρατίδας, -ου (nom propre) (m)''' : Callicratidas.<br> '''Καλλίμαχος, -άχου (nom propre) (m)''' : Callimaque.<br> '''Καλλιόπη, -ης (nom propre) (f)''' : Calliope.<br> '''Καλλιρόη, -ης (nom propre) (f)''' : Callirhoé.<br> '''Καλλιστώ, -οῦς (nom propre) (f)''' : Callisto.<br> '''Καλυψώ, -οῦς (nom propre) (f)''' : Calypso.<br> '''Καμϐύσης, -ου (nom propre) (m)''' : Cambyse.<br> '''Κανδάκη, -ης (nom propre) (f)''' : Candace.<br> '''Καρδοῦχος, -ύχου (nom commun) (m)''' : Kurde.<br> '''Καρκίνος, -ου (nom propre) (m)''' : Cancer.<br> '''Κᾶρ, -άρος (nom propre) (f)''' : Forme éolienne de ''Κήρ''.<br> '''Καρχηδόνιος, -ίου (nom commun) (m)''' : Carthaginois.<br> '''Καρχηδών, -όνος (nom propre) (f)''' : Carthage.<br> '''Κασσάνδρα, -ας (nom propre) (f)''' : Cassandre.<br> '''Κάσσανδρος, -άνδρου (nom commun) (m)''' : Cassandre.<br> '''Κελτίς, -δος (nom commun) (f)''' : Celte.<br> '''Κελτός, -οῦ (nom commun) (m)''' : Celte.<br> '''Κερασούντιος, -α, -ον (adjectif)''' : cérasien.<br> '''Κερασοῦς, -ῦντος (nom commun) (m)''' : Cérasus.<br> '''Κέρϐερος, -έρου (nom propre) (m)''' : Cerbère.<br> '''Κέρκωψ, -πος (nom propre) (m)''' : Cercops.<br> '''Κήρ, -ός (nom propre) (f)''' : Une des Kères.<br> '''Κηφισιά, -ᾶς (nom propre) (f)''' : Céphisia.<br> '''Κικέρων, -ος (nom propre) (m)''' : Cicéron.<br> '''Κιλικία, -ας (nom propre) (f)''' : Cilicie.<br> '''Κίρκη, -ης (nom propre) (f)''' : Circé.<br> '''Κλεάνθης, -ου (nom propre) (m)''' : Cléante.<br> '''Κλεισθένης, -ους (nom propre) (m)''' : Clisthène.<br> '''Κλείτανδρος, -άνδρου (nom propre) (m)''' : Clitandre.<br> '''Κλειτόμαχος, -άχου (nom propre) (m)''' : Clitomaque.<br> '''Κλεῖτος, -ίτου (nom propre) (m)''' : Cleithos.<br> '''Κλειτοφῶν, -τος (nom propre) (m)''' : Clitophon.<br> '''Κλειώ, -οῦς (nom propre) (f)''' : Clio.<br> '''Κλεoμήδης, -ους (nom propre) (m)''' : Cléomède.<br> '''Κλεοπᾶς, -ᾶ (nom propre) (m)''' : Cléopas.<br> '''Κλεοπάτρα, -ας (nom propre) (f)''' : Cléopâtre.<br> '''Κλεόπατρος, -άτρου (nom propre) (m)''' : Cléopatros.<br> '''Κλεώνυμος, -ύμου (nom propre) (m)''' : Cléonyme.<br> '''Κλωθώ, -οῦς (nom propre) (f)''' : Clotho (première Moire).<br> '''Κόϊντος, -ΐντου (nom propre) (m)''' : Quentin.<br> '''Κοῖος, -ίου (nom propre) (m)''' : Céos.<br> '''Κολοφών, -ῶνος (nom commun) (m)''' : Colophon (ville).<br> '''Κολχίς, -δος (nom propre) (f)''' : Colchide.<br> '''Κολχός, -οῦ (nom commun) (m)''' : Colchien.<br> '''Κόνων, -ος (nom commun) (m)''' : Conon.<br> '''Κόραμα, -ας (nom propre) (f)''' : Göreme.<br> '''Κορίνθιος, -ίου (nom commun) (f)''' : Corinthien.<br> '''Κόρινθος, -ίνθου (nom propre) (f)''' : Corinthe.<br> '''Κορσίς, -δος (nom propre) (f)''' : Corse.<br> '''Κόρκυρα, -ύρας (nom propre) (f)''' : Corcyre.<br> '''Κορυφώ, -οῦς (nom propre) (m)''' : Corfou (île).<br> '''Κότταλος, -άλου (nom propre) (m)''' : Cottalos.<br> '''Κράτος, -ους (nom propre) (m)''' : Cratos.<br> '''Κρατύλος, -ου (nom propre) (m)''' : Cratyle.<br> '''Κρεῖος, -ίου (nom propre) (m)''' : Crios.<br> '''Κρέουσα, -ας (nom propre) (f)''' : Créuse.<br> '''Κρέων, -οντος (nom propre) (m)''' : Créon.<br> '''Κριός, -οῦ (nom propre) (m)''' : Bélier.<br> '''Κρίτοϐουλος, -ύλου (nom propre) (m)''' : Critobule.<br> '''Κροῖσος, -ίσου (nom propre) (m)''' : Crésus.<br> '''Κρίτοϐουλος, -ύλου (nom propre) (m)''' : Critobule.<br> '''Κροκοδειλόπολις, -όλεως (nom propre) (f)''' : Fayoum.<br> '''Κτησιφῶν, -τος (nom propre) (m)''' : Ctésiphon.<br> '''Κτιμένη, -ης (nom propre) (f)''' : Ctimène (sœur d'Ulysse).<br> '''Κυαξάρης, -ου (nom propre) (m)''' : Cyaxare.<br> '''Κύθηρα, -ήρων (nom propre) (n)''' : Cythère.<br> '''Κυθήριος, -ίου (nom commun)''' : Cythérien.<br> '''Κύκλωψ, -ωπος (nom propre) (m)''' : Cyclope.<br> '''Κυνόσαργες, -ων (nom propre) (m)''' : Cynosarges.<br> '''Κύπριος, -ίου (nom commun) (m)''' : Chypriote.<br> '''Κύπρος, -ου (nom propre) (f)''' : Chypre.<br> '''Κύριλλος, -ίλλου (nom propre) (m)''' : Cyrille.<br> '''Κύριος, -ίου (nom propre) (m)''' : Seigneur.<br> '''Κύρνιος, -ίου (nom commun) (m)''' : Corse.<br> '''Κύρνος, -ου (nom propre) (f)''' : Corse.<br> '''Κῦρος, -ύρου (nom propre) (m)''' : Cyrus.<br> '''Κύψελος, -έλου (nom propre) (m)''' : Cypsélos.<br> '''Κωκυτός, -τοῦ (nom propre) (m)''' : Cocyte.<br> '''Κωνσταντῖνος, -ίνου (nom propre) (m)''' : Constantin.<br> '''Κωνσταντινούπολις, -όλεως (nom propre) (f)''' : Constantinople.<br> ==Λ== '''λαϐή, -ῆς (nom commun) (f)''' : anse.<br> '''λάϐρυς, -εως (nom commun) (f)''' : labrys.<br> '''λαϐύρινθος, -ίνθου (nom commun) (m)''' : labyrinthe.<br> '''λάγανον, -άνου (nom commun) (n)''' : crêpe.<br> '''λαγαρός, -ά, -όν (adjectif)''' : Creux, enfoncé ; lâche, ample.<br> '''λαγνεία, -ας (nom commun) (f)''' : libertinage.<br> '''λάγνευμα, -ύματος (nom commun) (n)''' : coït (acte).<br> '''λαγνεύω (verbe)''' : coïter.<br> '''λάγνης, -ης, -ες (adjectif)''' : Forme attique de ''λάγνος''.<br> '''λάγνος, -α, -ον (adjectif)''' : libertin, débauché.<br> '''λαγός, -οῦ (nom commun) (m)''' : lièvre.<br> '''λάγυνος, -ύνου (nom commun) (m/f)''' : flacon, pichet.<br> '''λαγών, -όνος (nom commun) (m)''' : flanc.<br> '''λαγώς, -ώ (nom commun) (m)''' : Forme attique de ''λαγός''.<br> '''λᾴα -ας (nom commun) (f)''' : Forme dorienne de ''λεία''.<br> '''λάθος, -ους (nom commun) (n)''' : erreur.<br> '''λαϊκός, -ή, -όν (adjectif)''' : populaire.<br> '''λαϊκῶς (adverbe)''' : populairement.<br> '''λαϊκώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''λαϊκός''.<br> '''λαϊκώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''λαϊκός''.<br> '''λαϊκώτατα, -, - (adverbe)''' : Superlatif de ''λαϊκῶς''.<br> '''λαϊκώτερον, -, - (adverbe)''' : Comparatif de ''λαϊκῶς''.<br> '''λαιµός, -οῦ (nom commun) (m)''' : cou, gorge.<br> '''λαῖον, -ίου (nom commun) (n)''' : faux.<br> '''λαιός, -ά, -όν (adjectif)''' : qui est à gauche.<br> '''λαιψηρός, -ά, -όν (adjectif)''' : agile, véhément.<br> '''λαιψηρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''λαιψηρός''.<br> '''λαιψηρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''λαιψηρός''.<br> '''λαιψηρῶς (adverbe)''' : agilement, véhémentement.<br> '''λάκτισμα, -ίσματος (nom commun) (n)''' : coup de pied.<br> '''λάκυθος, -ύθου (nom commun) (f)''' : Forme dorienne de ''λήκυθος''.<br> '''λακωνικός, -ή, -όν (adjectif)''' : concis.<br> '''λακωνικότης, -τος (nom commun) (f)''' : concision.<br> '''λακωνικῶς (adverbe)''' : concisément.<br> '''λακωνικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''λακωνικός''.<br> '''λακωνικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''λακωνικός''.<br> '''λᾳστής, -οῦ (nom commun) (m)''' : Forme dorienne de ''λῃστής''.<br> '''λαλέω (verbe)''' : Babiller, bavarder.<br> '''λαλιά, -ᾶς (nom commun) (f)''' : Babil, bavardage.<br> '''λάλος, -ος, -ον (adjectif)''' : Babillard, bavard.<br> '''λαμϐάνω (verbe)''' : prendre.<br> '''λάμϐδα (nom commun) (n)''' : lambda.<br> '''λαμπάς, -δος (nom commun) (f)''' : torche.<br> '''λαμπέτης, -ου (nom commun) (m)''' : .<br> '''λαμπέτις, -δος (nom commun) (f)''' : .<br> '''λάμπη, -ης (nom commun) (f)''' : Forme homérique et ionienne de ''λαμπάς''.<br> '''λαμπηδών, -όνος (nom commun) (f)''' : brillance des yeux.<br> '''λαμπρός, -ά, -όν (adjectif)''' : brillant.<br> '''λαμπρῶς (verbe)''' : brillamment.<br> '''λαμπρώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''λαμπρός''.<br> '''λαμπρώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''λαμπρός''.<br> '''λαμπτήρ, -ῆρος (nom commun) (m)''' : briquet, lanterne ; torche.<br> '''λαμπυρίς, -δος (nom commun) (f)''' : ver luisant.<br> '''λάμπω (verbe)''' : briller.<br> '''λάμψις, -εως (nom commun) (f)''' : brillance des étoiles, des éclairs, du Soleil.<br> '''λανθάνω (verbe)''' : être caché, faire oublier.<br> '''λαός, -οῦ (nom commun) (m)''' : peuple.<br> '''λάριξ, -κος (nom commun) (m)''' : mélèze.<br> '''λάρυγξ, -γος (nom commun) (m)''' : larynx. (Par suite) Gorge, gosier.<br> '''λάσανον, -άνου (nom commun) (n)''' : Casserole, marmite ; pot.<br> '''λατρεία, -ας (nom commun) (f)''' : service à gages. Service d’un dieu ; culte, adoration. Soins à donner au corps ou à l'âme.<br> '''λατρεύς, -έως (nom commun) (m)''' : serviteur engagé.<br> '''λατρεύω (verbe)''' : Être serviteur à gages. (Généralement) Servir que ce soit en parlant d’homme libre ou d’esclaves. (En particulier) Être serviteur de Dieu.<br> '''λάτρης, -ου (nom commun) (n)''' : adorateur.<br> '''λάτρον, -ου (nom commun) (n)''' : Gage, salaire ; rémunération.<br> '''λάφυρον, -ύρου (nom commun) (n)''' : butin.<br> '''λέαινα, -ίνης (nom propre) (f)''' : lionne.<br> '''λέϐης, -τος (nom commun) (m)''' : chaudière.<br> '''λέγω (verbe)''' : choisir.<br> '''λεία, -ας (nom commun) (f)''' : pillage.<br> '''λείϐω (verbe)''' : verser.<br> '''λειμών, -ῶνος (nom commun) (m)''' : pré.<br> '''λειμωνήρης, -ης, -ες (adjectif)''' : .<br> '''λειμωνιάς, -δος (nom commun) (f)''' : lémoniade.<br> '''λειμώνιον, -ίου (nom commun) (n)''' : .<br> '''λειμώνιος, -α, -ον (adjectif)''' : .<br> '''λειμωνίς, -δος (nom commun) (f)''' : lémoniade.<br> '''λειμωνοειδής, -ής, -ές (adjectif)''' : .<br> '''λειμωνόθεν (adverbe)''' : .<br> '''λεῖος, -ία, -ῖον (adjectif)''' : lisse, uni.<br> '''λείριον, -ίου (nom commun) (n)''' : lis (fleur).<br> '''λειτούργημα, -ήματος (nom commun) (n)''' : .<br> '''λειτουργία, -ας (nom commun) (f)''' : Cérémonie publique, service public.<br> '''λειτουργός, -οῦ (nom commun) (m)''' : Ministre, fonctionnaire. (Religion) Ministre du culte.<br> '''λειχήν, -ῆνος (nom commun) (m)''' : Lèpre, dartre sur le corps de l’homme. Cal sur la jambe du cheval. Lichen.<br> '''λείχω (verbe)''' : lécher.<br> '''λεξικός, -ή, -όν (adjectif)''' : lexical.<br> '''λεξικόν, -οῦ (nom commun) (n)''' : dictionnaire.<br> '''λεξικῶς (adverbe)''' : lexicalement.<br> '''λεξικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''λεξικός''.<br> '''λεξικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''λεξικός''.<br> '''λέξις, -εως (nom commun) (f)''' : Parole, action de parler. Élocution, style, manière de parler.<br> '''λεόντειος, -ος, -ον (adjectif)''' : léonin.<br> '''λεπίς, -δος (nom commun) (f)''' : Coque d’œuf. Lamelle de métal.<br> '''λεπτότης, -τος (nom commun) (f)''' : Minceur. Délicatesse.<br> '''λεπτός, -ή, -όν (adjectif)''' : Dépouillé de sa peau, de sa pellicule. Mince. Délicat.<br> '''λεπτότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''λεπτός''.<br> '''λεπτότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''λεπτός''.<br> '''λεπτῶς (adverbe)''' : Mincement. Délicatement<br> '''λέπω (verbe)''' : Peler, écosser ; écorcher.<br> '''λευγαλέος, -α, -ον (adjectif)''' : Triste, malheureux. Irrité, funeste. Désolé.<br> '''λευκός, -ή, -όν (adjectif)''' : blanc.<br> '''λεύκη, -ης (nom commun) (f)''' : peuplier.<br> '''λεύσσω (verbe)''' : voir.<br> '''λεώϐατος (nom commun)''' : .<br> '''λεωλογέω (verbe)''' : .<br> '''λέων, -οντος (nom commun) (m)''' : lion.<br> '''λεώς, -ώ (nom commun) (m)''' : Forme attique de ''λαός''.<br> '''λεωσφέτερος''' : .<br> '''λεωφόρος, -ου (nom commun) (f)''' : Avenue, boulevard.<br> '''λήθαιος, -α, -ον (adjectif)''' : .<br> '''ληθάνω (verbe)''' : faire oublier.<br> '''ληθαργέω (verbe)''' : oublier.<br> '''ληθαργία, -ας (nom commun) (f)''' : léthargie.<br> '''ληθαργικός, -ή, -όν (adjectif)''' : léthargique.<br> '''ληθαργικῶς (adverbe)''' : léthargiquement.<br> '''ληθαργικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ληθαργικός''.<br> '''ληθαργικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ληθαργικός''.<br> '''ληθαργικώτατα, -, - (adverbe)''' : Superlatif de ''ληθαργικῶς''.<br> '''ληθαργικώτερον, -, - (adverbe)''' : Comparatif de ''ληθαργικῶς''.<br> '''λήθαργος, -άργου (nom commun) (m)''' : torpeur.<br> '''λήθη, -ης (nom commun) (f)''' : oubli.<br> '''ληΐη, -ης (nom commun) (f)''' : Forme ionienne de ''λεία''.<br> '''ληΐς, - (nom commun) (f)''' : Forme homérique de ''λεία''.<br> '''ληϊστής, -οῦ (nom commun) (m)''' : Forme ionienne de ''λῃστής''.<br> '''λήιτον, -ίτου (nom commun) (n)''' : (En Achaïe) mairie.<br> '''λήκυθος, -ύθου (nom commun) (f)''' : petit vase.<br> '''λῃστής, -οῦ (nom commun) (m)''' : voleur, brigand. (en particulier) Pirate.<br> '''λῆξις, -ήξεως (nom commun) (f)''' : tirage au sort.<br> '''λῆμμα, -ήμματος (nom commun) (n)''' : Bénéfice, salaire, recette. Gain, profit. Bénéfice.<br> '''λημματιστής, -οῦ (nom commun) (m)''' : receveur.<br> '''λῆνος, -ήνους (nom commun) (n)''' : laine.<br> '''ληός, -οῦ (nom commun) (m)''' : Forme ionienne de ''λαός''.<br> '''λησμοσύνη, -ης (nom commun) (f)''' : oubli.<br> '''λῆψις, -ήψεως (nom commun) (f)''' : prise.<br> '''λίϐανος, -άνου (nom commun) (m)''' : oliban.<br> '''λιϐάς, -δος (nom commun) (f)''' : prairie.<br> '''λίθος, -ου (nom commun) (m)''' : pierre.<br> '''λιμήν, -ένος (nom commun) (m)''' : port.<br> '''λίμνη, -ης (nom commun) (f)''' : lac.<br> '''λιµός, -οῦ (nom commun) (m)''' : faim.<br> '''λιποθυμῶ (verbe)''' : s’évanouir.<br> '''λίπος, -ους (nom commun) (n)''' : graisse ; gras.<br> '''λιπόψυχος, -ος, -ον (adjectif)''' : pusillanime.<br> '''λιτότης, -τος (nom commun) (f)''' : simplicité.<br> '''λιτός, -ή, -όν (adjectif)''' : Uni. Simple, sans apprêts. (Par extension) Pauvre, chétif, faible, petit.<br> '''λίψ, -ϐος (nom commun) (m)''' : sud-ouest.<br> '''λογίζομαι (verbe)''' : .<br> '''λογικός, -ή, -όν (adjectif)''' : intellectuel ; rationnel.<br> '''λογικότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''λογικός''.<br> '''λογικότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''λογικός''.<br> '''λογικότατα, -, - (adverbe)''' : Superlatif de ''λογικῶς''.<br> '''λογικότερον, -, - (adverbe)''' : Comparatif de ''λογικῶς''.<br> '''λογικῶς (adverbe)''' : intellectuellement ; rationnellement.<br> '''λόγιον, -ίου (nom commun) (n)''' : oracle.<br> '''λόγος, -ου (nom commun) (m)''' : discours, sujet ; parole.<br> '''λοιμός, -οῦ (nom commun) (m)''' : peste.<br> '''λοίμωξις, -ώξεως (nom commun) (f)''' : infestation.<br> '''λοπαδοτεμαχοσελαχογαλεοκρανιολειψανοδριμυποτριμματοσιλφιοκαραϐομελιτοκατακεχυμενοκιχλεπικοσσυφοφαττοπεριστεραλεκτρυονοπτεκεφαλλιοκιγκλοπελειολαγῳ-οσιραιοϐαφητραγανοπτερυγών (nom commun) (m)''' : bigornocabillofricandortolangoustabricobouillabopoulaupococovin (Plat formé de dix-sept ingrédients différents, décrit par Aristophane dans ''L’Assemblée des femmes''. (v. 1169-1174)<br> '''λόγχη, -ης (nom commun) (f)''' : lance.<br> '''λοπάς, -δος (nom commun) (f)''' : écuelle.<br> '''λορδός, -ή, -όν (adjectif)''' : courbé.<br> '''λορδότατος, -έρα, -ότερον (adjectif)''' : Comparatif de ''λορδός''.<br> '''λορδότερος, -άτη, -ότατον (adjectif)''' : Superlatif de ''λορδός''.<br> '''λορδῶς (adverbe)''' : .<br> '''λουτήρ, -ῆρος (nom commun) (m)''' : baignoire.<br> '''λούω (verbe)''' : baigner.<br> '''λόφος, -ου (nom commun) (m)''' : colline.<br> '''λοχαγός, -οῦ (nom commun) (m)''' : capitaine.<br> '''λόχος, -ου (nom commun) (m)''' : compagnie.<br> '''λύγη, -ης (nom commun) (f)''' : crépuscule, pénombre.<br> '''λύγξ, -γός (nom commun) (f)''' : hoquet.<br> '''λύγξ, -κός (nom commun) (m/f)''' : lynx.<br> '''λυγρός, -ά, -όν (adjectif)''' : Fâcheux, triste. Malfaisant.<br> '''λύκαινα, -ίνης (nom commun) (f)''' : louve.<br> '''λυκάνθρωπος, -ώπου (nom commun) (m)''' : loup-garou.<br> '''λυκίσκος, -ου (nom commun) (m)''' : chien-loup.<br> '''λύκος, -ου (nom commun) (m)''' : loup.<br> '''λύμα, -ας (nom commun) (f)''' : Forme dorienne de ''λύμη''.<br> '''λῦμα, -ύματος (nom commun) (n)''' : .<br> '''λῦμαξ, -ύμακος (nom commun) (m)''' : .<br> '''λυμαίνομαι (verbe)''' : .<br> '''λυμαντήρ, -ῆρος (nom commun) (m)''' : destructeur.<br> '''λυμαντήριος, -α, -ον (adjectif)''' : injurieux, destructeur.<br> '''λυμαντής, -οῦ (nom commun) (m)''' : coureur.<br> '''λυμαντικός, -ή, -όν (adjectif)''' : .<br> '''λυμάντωρ, - (nom commun) (m)''' : .<br> '''λῦμαρ, -ύμαρος (nom commun) (m)''' : .<br> '''λύμασις, -εως (nom commun) (f)''' : .<br> '''λυμάχη, -ης (nom commun) (f)''' : .<br> '''λύμη, -ης (nom commun) (f)''' : .<br> '''λύπη, -ης (nom commun) (f)''' : regret.<br> '''λυποῦμαι (verbe)''' : être affligé.<br> '''λυπῶ (verbe)''' : regretter.<br> '''λύρα, -ας (nom commun) (f)''' : lyre. (Par extension) Constellation de la lyre. (Par extension) Poisson du même nom.<br> '''λύσσα, -ης (nom commun) (f)''' : Rage. (maladie canine) Fureur belliqueuse, frénésie.<br> '''λύτρωσις, -ώσεως (nom commun) (f)''' : rédemption.<br> '''λύττα, -ης (nom commun) (f)''' : Forme attique de ''λύσσα''.<br> '''λύχνος, -ου (nom commun) (m)''' : lampe.<br> '''λωρίς, -δος (nom commun) (f)''' : bande.<br> '''λῶρος, -ώρου (nom commun) (m)''' : bande.<br> '''Λάζαρος, -άρου (nom propre) (m)''' : Lazare.<br> '''Λαέρτης, -ου (nom propre) (m)''' : Laërte (père d’Ulysse).<br> '''Λαῖλαψ, -ίλαπου (nom propre) (m)''' : Lélaps.<br> '''Λάκαινα, -ίνης (nom commun) (m)''' : Laconienne.<br> '''Λακεδαιμόνιος, -ίου (nom commun) (m)''' : Lacédémonien.<br> '''Λακεδαίμων, -ονος (nom propre) (f)''' : Lacédémone.<br> '''Λακωνία, -ας (nom propre) (m)''' : Laconie.<br> '''Λάκων, -ος (nom commun) (m)''' : Laconien.<br> '''Λάμια, -ας (nom propre) (m)''' : Lamia.<br> '''Λαμπάς, -δος (nom propre) (f)''' : Lampade.<br> '''Λαμπετίη, -ης (nom propre) (f)''' : Lampétie.<br> '''Λάμπος, -ου (nom propre) (m)''' : Lampos.<br> '''Λαοδίκη, -ης (nom propre) (f)''' : Laodicé.<br> '''Λαοκόων, -οντος (nom propre) (m)''' : Laocoon.<br> '''Λαομέδων, -οντος (nom propre) (m)''' : Laomédon (fils d’Ilos et d’Eurydice).<br> '''Λατῖνος, -ίνου (nom propre) (m)''' : Latinos.<br> '''Λάτιον, -ίου (nom propre) (n)''' : Latium.<br> '''Λατώ, -οῦς (nom propre) (f)''' : Forme dorienne de ''Λητώ''.<br> '''Λαύρειον, -ίου (nom propre) (m)''' : Laurion.<br> '''Λάχεσις, -εως (nom propre) (f)''' : Lachésis (deuxième Moire).<br> '''Λέανδρος, -άνδρου (nom propre) (m)''' : Léandre.<br> '''Λεία, -ας (nom propre) (f)''' : Léa.<br> '''Λεύκιππος, -ίππου (nom propre) (m)''' : Leucippe.<br> '''Λευκοτεκία, -ας (nom propre) (f)''' : Variante de ''Λoυκoτοκία''.<br> '''Λεωνίδας, -ου (nom propre) (m)''' : Léonidas.<br> '''Λέων, -οντος (nom propre) (m)''' : Lion.<br> '''Λεωχάρης, -ου (nom propre) (m)''' : Léocharès.<br> '''Λήθη, -ης (nom propre) (f)''' : Léthé.<br> '''Λητώ, -οῦς (nom propre) (f)''' : Léto.<br> '''Λιϐύη, -ης (nom propre) (f)''' : Lybie.<br> '''Λίϐυς, -ος (nom commun) (m)''' : Libyen.<br> '''Λουκᾶνος, -άνου (nom commun) (m)''' : Lucanien.<br> '''Λουκᾶς, -ᾶ (nom propre) (m)''' : Luke ; Lucas.<br> '''Λουκιανός, -οῦ (nom propre) (m)''' : Lucien.<br> '''Λoυκoτοκία, -ας (nom propre) (f)''' : Lutèce.<br> '''Λουκρητία, -ας (nom propre) (f)''' : Lucrèce.<br> '''Λουκρήτιος, -ίου (nom propre) (m)''' : Lucrèce.<br> '''Λυγκεύς, -έως (nom propre) (m)''' : Lyncée.<br> '''Λυκάμϐης, -ου (nom propre) (m)''' : Lycambès.<br> '''Λυκάων, -ονος (nom propre) (m)''' : Lycaon.<br> '''Λύκειον, -ίου (nom propre) (m)''' : Lycée. (Gymnase au nord-est d’Athènes où enseigna Aristote.)<br> '''Λυκομήδης, -ου (nom propre) (m)''' : Lycomède.<br> '''Λυκόπολις, -όλεως (nom propre) (f)''' : Assiout.<br> '''Λυκοῦργος, -ύργου (nom propre) (m)''' : Lycurgue.<br> '''Λύσανδρος, -άνδρου (nom propre) (m)''' : Lysandre.<br> '''Λυσιδίκη, -ης (nom propre) (f)''' : Lysidice.<br> '''Λύσις, -δος (nom propre) (m)''' : Lysis. (œuvre de Platon)<br> '''Λῦσις, -ύσεως (nom propre) (m)''' Lysis. (philosophe grec)<br> '''Λωΐς, -δος (nom propre) (f)''' Loïs. (Personnage du Nouveau Testament : ''Timothée'', 1-5)<br> ==Μ== '''-μα, -τος (suffixe)''' : suffixe marquant des noms neutres abstraits.<br> '''μά (particule)''' : par. (Particule interjective.) (+ nom de divinité a l’accusatif)<br> '''μαγειρεῖον, -ίρου (nom commun) (n)''' : cuisine (pièce).<br> '''μαγειρεύω (verbe)''' : cuisiner.<br> '''μαγείρισσα, -ας (nom commun) (f)''' : cuisinière.<br> '''μάγειρος, -ίρου (nom commun) (m)''' : cuisinier.<br> '''μαγικός, -ή, -όν (adjectif)''' : magique.<br> '''μαγικῶς (adverbe)''' : magiquement.<br> '''μαγικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''μαγικός''.<br> '''μαγικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''μαγικός''.<br> '''μάγος, -ου (nom commun) (m)''' : Enchanteur, magicien ; sorcier.<br> '''μαδαρός, -ά, -όν (adjectif)''' : moite ; mouillé.<br> '''μαδάω (verbe)''' : être moite/mouillé.<br> '''μᾶζα, -άζης (nom commun) (f)''' : masse (tas).<br> '''μαζός, -οῦ (nom commun) (m)''' : sein.<br> '''μάθημα, -ήματος (nom commun) (n)''' : leçon.<br> '''μαθητής, -οῦ (nom commun) (m)''' : disciple.<br> '''μάθησις, -ήσεως (nom commun) (f)''' : apprentissage.<br> '''µαῖα, -ίας (nom propre) (f)''' : mère ; sage-femme.<br> '''μαίευμα, -ύµατος (nom commun) (n)''' : accouchement.<br> '''μαίευσις, -ύσεως (nom propre) (f)''' : accouchement.<br> '''μαιευτικός, -ή, -όν (adjectif)''' : maïeutique.<br> '''μαιεύομαι (verbe)''' : faire accoucher.<br> '''μαίνομαι (verbe)''' : être fou, délirer ; être enragé.<br> '''μαίομαι (verbe)''' : .<br> '''μαιμάω (verbe)''' : .<br> '''μακάριος, -ία, -άριον (adjectif)''' : béni, bienheureux ; heureux, fortuné.<br> '''μακρός, -ά, -όν (adjectif)''' : (idée d’espace) long. (idée de durée) long. (idée de quantité) Grand, fort.<br> '''μακρύς, -ιά, -ύ (adjectif)''' : long.<br> '''μαλακτήρ, -ῆρος (nom commun) (m)''' : .<br> '''μαλάκτης, -ου (nom commun) (m)''' : masseur.<br> '''μάλαξις, -άξεως (nom commun) (f)''' : massage.<br> '''μαλάσσω (verbe)''' : masser.<br> '''μᾶλον, -άλου (nom commun) (n)''' : Forme dorienne et éolienne de ''μῆλον''. (Au sens de « pomme ».)<br> '''μαλλός, -οῦ (nom commun) (m)''' : touffe de laine.<br> '''μάμμη, -ης (nom commun) (f)''' : maman.<br> '''μανδύα, -ας (nom commun) (f)''' : cape.<br> '''μανδύη, -ης (nom commun) (f)''' : Forme ionienne de ''μανδύα''.<br> '''μανθάνω (verbe)''' : Apprendre ; s’apercevoir de. (Par suite) Comprendre.<br> '''μανία, -ας (nom commun) (f)''' : Folie, démence ; enthousiasme, transport.<br> '''μανίη, -ης (nom commun) (f)''' : Forme ionienne de ''μανία''.<br> '''μᾶνις, -άνιος (nom commun) (f)''' : Forme dorienne de ''μῆνις''.<br> '''μαντεία, -ας (nom commun) (f)''' : Prédiction, oracle ; divination.<br> '''μαντείη, -ης (nom commun) (f)''' : Forme homérique de ''μαντεία''.<br> '''μαντηΐη, -ης (nom commun) (f)''' : Forme ionienne de ''μαντεία''.<br> '''μάντις, -εως (nom commun) (m) ''' : devin.<br> '''μάραθον, -άθου (nom commun) (n)''' : fenouil.<br> '''μαργαρίδης, -ου (nom commun) (m) ''' : Forme ionienne de ''μαργαρίτης''.<br> '''μαργαρίτα, -ας (nom commun) (f) ''' : marguerite.<br> '''μαργαρίτης, -ου (nom commun) (m) ''' : perle.<br> '''μαρμαίρω (verbe)''' : briller.<br> '''μαρμάρεος, -έα, -άρεον (adjectif) ''' : brillant ; fait de marbre.<br> '''μαρμάρινος, -η, -ον (adjectif) ''' : marmoréen.<br> '''μάρμαρος, -άρου (nom commun) (m)''' : marbre.<br> '''μαρμαρώδης, -ης, -ες (adjectif)''' : marbré.<br> '''μάρσιπος, -ίπου (nom commun) (m)''' : sac.<br> '''μαρσίππιον, -ίου (nom commun) (n)''' : petit sac.<br> '''μαρτυρέω (verbe)''' : .<br> '''μαρτύρημα, -ήματος (nom commun) (n)''' : témoignage.<br> '''μαρτυρία, -ας (nom commun) (f)''' : témoignage.<br> '''μαρτύριον, -ίου (nom commun) (n)''' : Témoignage, preuve. Sanctuaire dédié à un martyr.<br> '''μάρτυρ, -ος (nom commun) (m/f)''' : Forme éolienne de ''μάρτυς''.<br> '''μάρτυς, -ρος (nom commun) (m/f)''' : témoin ; témoin de Dieu.<br> '''μασδός, -οῦ (nom commun) (m)''' : Forme dorienne de ''μαζός''.<br> '''μασθός, -οῦ (nom commun) (m)''' : Forme tardive de ''μαζός''.<br> '''μάσσω (verbe)''' : pétrir, masser.<br> '''μάσταξ, -κος (nom commun) (f)''' : mâchoire.<br> '''μαστιάω (verbe)''' : Forme homérique de ''μαστίζω''.<br> '''μαστίγωσις, -ώσεως (nom commun) (f)''' : flagellation.<br> '''μαστιγῶ (verbe)''' : fouetter.<br> '''μαστίζω (verbe)''' : flageller.<br> '''μαστίσδω (verbe)''' : Forme dorienne de ''μαστίζω''.<br> '''μάστιξ, -ίγος (nom commun) (f)''' : fouet.<br> '''μαστός, -οῦ (nom commun) (m)''' : mamelle ; sein.<br> '''μασχάλη, -ης (nom commun) (f)''' : aisselle (cavité placée sous le bras).<br> '''μάταιος, -ία, -αιον (adjectif)''' : futile, vain ; frivole.<br> '''ματαιότης, -τος (nom commun) (f)''' : futilité, vanité ; frivolité.<br> '''μάτημι (verbe)''' : Forme éolienne de ''πατέω''.<br> '''μάτηρ, -ρός (nom commun) (f)''' : Forme dorienne de ''μήτηρ''.<br> '''μάττω (verbe)''' : Forme attique de ''μάσσω''.<br> '''μαυρός, -ός, -όν (adjectif)''' : Forme alternative de ''ἀμαυρός''.<br> '''μάχαιρα, -ίρας (nom commun) (f)''' : sabre.<br> '''μαχαιτάς, -δος (nom commun) (m)''' : Forme éolienne de ''μαχητής''.<br> '''μαχανά, -ᾶς (nom commun) (f)''' : Forme dorienne de ''μηχανή''.<br> '''μαχατάρ, -ος (nom commun) (m)''' : Forme laconienne de ''μαχητής''.<br> '''μαχάτας, -ου (nom commun) (m)''' : Forme dorienne de ''μαχητής''.<br> '''μαχέομαι (verbe)''' : Forme ionienne de ''μάχομαι''.<br> '''μάχη, -ῆς (nom commun) (f)''' : Combat ; bataille.<br> '''μαχητής, -οῦ (nom commun) (m)''' : combattant.<br> '''μάχλος, -ος, -ον (adjectif)''' : libertin, débauché.<br> '''μάχομαι (verbe)''' : combattre.<br> '''μᾶχος, -άχου (nom commun) (n)''' : Forme dorienne de ''μῆχος''.<br> '''μέγαθος, -άθεος (nom commun) (n)''' : Forme ionienne de ''μέγεθος''.<br> '''μεγαλομανής, -ής, -ές (adjectif)''' : mégalomane.<br> '''μέγας, -άλη, -α (adjectif)''' : grand.<br> '''μέγεθος, -έθους (nom commun) (n)''' : Grandeur, hauteur.<br> '''μεγιστάν, -ᾶνος (nom commun) (m)''' : magnat.<br> '''μέγιστος, -η, -ον (adjectif)''' : Superlatif de ''μέγας''.<br> '''μέδος, -ου (nom commun) (m)''' : hydromel.<br> '''μέδων, -οντος (nom commun) (m)''' : seigneur.<br> '''μέδω (verbe)''' : Commander, régner.<br> '''μεθίημι (verbe)''' : .<br> '''μέθυστος, -ος, -ον (adjectif)''' : ivre.<br> '''μέθυ, -ος (nom commun) (n)''' : vin.<br> '''μεθύω (verbe)''' : être ivre.<br> '''μεῖγμα, -ίγματος (nom commun) (n)''' : mixture.<br> '''μείζων, -ων, -ον (adjectif)''' : Comparatif de ''μέγας''.<br> '''μεῖξις, -ίξεως (nom commun) (f)''' : .<br> '''μεῖλον, -ίλου (nom commun) (n)''' : Forme béotienne de ''μῆλον''. (Au sens de « petit bétail ».)<br> '''μεῖραξ, -ίρακος (nom commun) (m/f)''' : jeune fille ; jeune garçon.<br> '''μείρομαι (verbe)''' : attribuer ; prendre.<br> '''μείωσις, -ώσεως (nom commun) (f)''' : réduction.<br> '''μειῶ (verbe)''' : réduire.<br> '''μελάμπυγος, -ος, -ον (adjectif)''' : Qui a les fesses noires.<br> '''μελάντατος, -άτη, -άντατον (adjectif)''' : Superlatif de ''μέλας''.<br> '''μελάντερος, -έρα, -άντερον (adjectif)''' : Comparatif de ''μέλας''.<br> '''μελάνως (adverbe)''' : en noir.<br> '''μέλας, -αινα, -αν (adjectif)''' : noir ; sombre.<br> '''μελεαγρίς, -δος (nom commun) (f)''' : pintade.<br> '''μελετηρός, -ή, -όν (adjectif)''' : studieux.<br> '''μελετῶ (verbe)''' : étudier.<br> '''μελία, -ας (nom commun) (f)''' : frêne.<br> '''μελίζω (verbe)''' : moduler, chanter.<br> '''μελίη, -ης (nom commun) (f)''' : Forme ionienne de ''μελία''.<br> '''μέλι, -τος (nom commun) (f)''' : miel.<br> '''μέλισσα, -ης (nom commun) (f)''' : abeille.<br> '''μέλος, -ους (nom commun) (n)''' : Membre, articulation. Chant. <br> '''μελῳδία, -ας (nom commun) (f)''' : mélodie.<br> '''μελῳδικός, -ή, -όν (adjectif)''' : mélodieux.<br> '''μελῳδός, -ή, -όν (adjectif)''' : musical.<br> '''μέλω (verbe)''' : être un objet de soin ; prendre soin de ; (impersonnel) être un sujet de souci.<br> '''μέλλων, -οντος (nom commun) (m)''' : futur.<br> '''μέμψις, -εως (nom commun) (f)''' : blâme ; censure.<br> '''μέμφομαι (verbe)''' : reprocher.<br> '''μέν (particule)''' : .<br> '''μένος, -ους (nom commun) (n)''' : Esprit. Courage, cœur, ardeur, volonté. Désir. Force, violence.<br> '''μέντοι (particule)''' : cependant.<br> '''μένω (verbe)''' : rester, demeurer. Attendre<br> '''μερίς, -δος (nom commun) (f)''' : part.<br> '''μέρος, -ους (nom commun) (n)''' : partie.<br> '''μεσαιπόλιος -ος, -ον (adjectif)''' : .<br> '''µεσοστιχίς, -δος (nom commun) (f)''' : mésostiche.<br> '''μέσος, -η, -ον (adjectif)''' : médian.<br> '''μέσος, -ου (nom commun) (m)''' : majeur.<br> '''μεστός, -ή, -όν (adjectif)''' : plein.<br> '''μεστῶς (adverbe)''' : pleinement.<br> '''μεστώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''μεστός''.<br> '''μεστώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''μεστός''.<br> '''μεστῶ (verbe)''' : être plein.<br> '''μέσως (adverbe)''' : au milieu de.<br> '''μεσώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''μέσος''.<br> '''μεσώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''μέσος''.<br> '''μεσηγύ (adverbe)''' : au milieu.<br> '''μετά (adverbe)''' (Devient ''μετ’'' devant un mot commençant par une voyelle à esprit doux, et ''μεθ’'' devant un mot commençant par une voyelle à esprit rude.) : Au milieu, parmi.<br> '''μετα- (préfixe)''' : .<br> '''μεταϐαίνω (verbe)''' : changer ; dépasser.<br> '''μετάϐασις, -άσεως (nom commun) (f)''' : changement ; dépassement.<br> '''μεταϐίϐασις, -άσεως (nom commun) (f)''' : transfert ; transmission.<br> '''μεταϐιϐάζω (verbe)''' : transférer ; transmettre.<br> '''μεταγιγνώσκω (verbe)''' : regretter.<br> '''μετακινῶ (verbe)''' : .<br> '''μεταμέλεια, -ας (nom commun) (f)''' : repentir.<br> '''μεταμέλω (verbe)''' : se repentir.<br> '''μεταμόρφωσις, -ώσεως (nom commun) (f)''' : transformation.<br> '''μετάνοια, -ίας (nom commun) (f)''' : repentance ; pénitence.<br> '''μετανοῶ (verbe)''' : faire pénitence.<br> '''μέταξα, -άξης (nom commun) (f)''' : soie.<br> '''µεταξύ (préposition)''' : entre.<br> '''μεταφέρω (verbe)''' : transporter.<br> '''μεταφορά, -άς (nom commun) (f)''' : transport.<br> '''μεταφράζω (verbe)''' : traduire.<br> '''μετάφρασις, -άσεως (nom commun) (f)''' : traduction.<br> '''μετέωρος, -ος, -ον (adjectif)''' : élevé.<br> '''μέτοικος, -ίκου (nom commun) (m/f)''' : Individu étranger à une cité.<br> '''μετεωρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''μετέωρος''.<br> '''μετεωρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''μετέωρος''.<br> '''μετεωρότατα (adverbe)''' : Superlatif de ''μετεώρως''.<br> '''μετεωρότερον (adverbe)''' : Comparatif de ''μετεώρως''.<br> '''μετεώρως (adverbe)''' : de façon élevée.<br> '''μέτρον, -ου (nom commun) (n)''' : mesure.<br> '''μέτωπον, -ώπου (nom commun) (n)''' : front.<br> '''μέχρι (conjonction)''' : jusqu'à ce que.<br> '''μηδέν (adjectif numéral)''' : zéro.<br> '''μηδέποτε (adverbe)''' : jamais.<br> '''μηδικός, -ή, -όν (adjectif)''' : mède.<br> '''μῆδος, -ήδους (nom commun) (n)''' : mesure.<br> '''μή (particule)''' : non (subjectif).<br> '''μηλίτης, -ου (nom commun) (m)''' : cidre.<br> '''μῆλον, -ήλου (nom commun) (n)''' : Petit bétail ; pomme.<br> '''μηνιαῖος, -ία -ῖον (suffixe)''' : mensuel.<br> '''μηναιότατος, -άτη, -ότατον (suffixe)''' : Forme superlative de ''μηνιαῖος''.<br> '''μηναιότερος, -έρα, -ότερον (suffixe)''' : Forme comapartive de ''μηνιαῖος''.<br> '''μηναίως (suffixe)''' : mensuellement.<br> '''μήνη, -ης (nom commun) (f)''' : mère.<br> '''μῆνιγξ, -ήνιγγος (nom commun) (f)''' : membrane.<br> '''μῆνις, -ήνιος (nom commun) (f)''' : colère.<br> '''μήν, -ός (nom commun) (m)''' : mois.<br> '''μηριαῖος, -ία, -ῖον (adjectif)''' : fémural.<br> '''μηρóς, -οῦ (nom commun) (m)''' : côté, flanc ; cuisse, fémur.<br> '''μήτηρ, -ρός (nom commun) (f)''' : mère.<br> '''μητιάω (verbe)''' : ruse.<br> '''μητιόεις, -εσσα, -εν (adjectif)''' : .<br> '''μῆτις, -ήτεως (nom commun) (f)''' : ruse.<br> '''μήτις, -ις, -ι (pronom)''' : personne.<br> '''μήτρα, -ας (nom commun) (f)''' : matrice ; ventre ou sein de la mère.<br> '''μήτρη, -ης (nom commun) (f)''' : Forme ionienne de ''μήτρα''.<br> '''μητροκτονία, -ας (nom commun) (m)''' : matricide.<br> '''μητροκτόνος, -ου (nom commun) (m)''' : matricide.<br> '''μητρυιά, -ᾶς (nom commun) (f)''' : belle-mère.<br> '''μητρυιός, -οῦ (nom commun) (m)''' : beau-père.<br> '''μηχανή, -ῆς (nom commun) (f)''' : machine ; engin. Invention.<br> '''μηχανικός, -ή, -όν (f)''' : mécanique ; ingénieux.<br> '''μηχανικότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''μηχανικός''.<br> '''μηχανικότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''μηχανικός''.<br> '''μηχανικῶς (adverbe)''' : mécaniquement ; ingénieusement.<br> '''μῆχος, -ήχους (nom commun) (n)''' : .<br> '''μιαίνω (verbe)''' : Salir, souiller, polluer, profaner, teindre, colorer.<br> '''μιαρός, -ά, -όν (adjectif)''' : impur.<br> '''μίασμα, -άσματος (nom commun) (n)''' : Souillure provenant d’un meurtre. Personne souillée d’un meurtre.<br> '''μιασμός, -οῦ (nom commun) (m)''' : Action de salir, souiller, tacher ; deuil, vêtements salis en signe de deuil, teinture.<br> '''μίγδην (adverbe)''' : confusément.<br> '''μῖγμα, -ίγματος (nom commun) (n)''' : .<br> '''μικρός, -ά, -όν (adjectif)''' : petit.<br> '''μικρός, -οῦ (nom commun) (m)''' : auriculaire.<br> '''μικρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''μικρός''.<br> '''μικρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''μικρός''.<br> '''μικρῶς (adverbe)''' : .<br> '''μιμάς, -δος (nom commun) (f)''' : actrice.<br> '''μιμεῖσθαι (verbe)''' : imiter.<br> '''μίμημα, -ήματος (nom commun) (n)''' : Imitation, copie ; contrefaçon.<br> '''μίμησις, -ήσεως (nom commun) (f)''' : Imitation, représentation.<br> '''μιμητικός, -ή, -όν (adjectif)''' : représentatif.<br> '''μιμητικῶς (adverbe)''' : représentativement.<br> '''μιμητικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''μιμητικός''.<br> '''μιμητικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''μιμητικός''.<br> '''μιμητικώτατα, -, - (adverbe)''' : Superlatif de ''μιμητικῶς''.<br> '''μιμητικώτερον, -, - (adverbe)''' : Comparatif de ''μιμητικῶς''.<br> '''μιμναίσκω (verbe)''' : Forme éolienne de ''μιμνήσκω''.<br> '''μιμνήσκω (verbe)''' : Rappeler à la mémoire. Rappeler une chose, mentionner.<br> '''μῖμος, -ίμου (nom commun) (m)''' : acteur.<br> '''μιμοῦμαι (verbe)''' : mimer.<br> '''μίνθη, -ης (nom commun) (f)''' : menthe.<br> '''µινώταυρος, -ύρου (nom commun) (m)''' : minotaure.<br> '''μισανδρία, -ας (nom commun) (f)''' : misandrie.<br> '''μισάνδρος, -ος, -ον (adjectif)''' : misandre.<br> '''μισανθρωπία, -ας (nom commun) (f)''' : misanthropie.<br> '''μισάνθρωπος, -ος, -ον (adjectif)''' : misanthropie.<br> '''μισθός, -οῦ (nom commun) (m)''' : salaire.<br> '''μισθοφόρος, -ου (nom commun) (m)''' : mercenaire.<br> '''μισογύνης, -ου (nom commun) (m)''' : matcho.<br> '''μισογυνία, -ας (nom commun) (f)''' : misogynie.<br> '''μῖσος, -ίσους (nom commun) (n)''' : Haine, aversion ; objet de haine.<br> '''μισῶ (verbe)''' : détester, haïr.<br> '''μίτος, -ου (nom commun) (m)''' : fil.<br> '''μίτωσις, -ώσεως (nom commun) (f)''' : mitose.<br> '''μνᾶ, -ᾶς (nom commun) (f)''' : mine (monnaie).<br> '''μνᾶμα, -άματος (nom commun) (n)''' : Forme dorienne de ''μνῆμα''.<br> '''μνάμων, -ων, -ον (adjectif)''' : Forme dorienne de ''μνήμων''.<br> '''μνάομαι (verbe)''' : .<br> '''μναστήρ, -ῆρος (nom commun) (m)''' : Forme dorienne de ''μνηστήρ''.<br> '''μνᾶστις, -άστεως (nom commun) (f)''' : Forme dorienne de ''μνῆστις''.<br> '''μνῆμα, -ήματος (nom commun) (n)''' : tombe.<br> '''μνημεῖον, -ίου (nom commun) (n)''' : monument.<br> '''μνημήιον, -ίου (nom commun) (n)''' : Forme dorienne de ''μνημεῖον''.<br> '''μνήμων, -ων, -ον (adjectif)''' : .<br> '''μνηστήρ, -ῆρος (nom commun) (m)''' : prétendant.<br> '''μνῆστις, -ήστεως (nom commun) (f)''' : .<br> '''µvοῦς, -οῦ (nom commun) (m)''' : chatte (sexe féminin).<br> '''μόγις (adverbe)'''' : à peine.<br> '''μόγος, -ου (nom commun) (m)''' : peine ; labeur.<br> '''μόλις (adverbe)''' : Variante de ''μόγις''.<br> '''µοῖρα, -ίρας (nom commun) (f)''' : part ; portion. Parti politique.<br> '''μοιχαλίς, -δος (nom commun) (f)''' : adultère (celle qui la commet).<br> '''μοιχεία, -ας (nom commun) (f)''' : adultère.<br> '''μοιχεύω (verbe)''' : commettre l’adultère.<br> '''μοιχός, -οῦ (nom commun) (m)''' : adultère (celui qui la commet).<br> '''μόλυϐδος, -ύϐδου (nom commun) (m)''' : plomb.<br> '''μόλυνσις, -ύνσεως (nom commun) (f)''' : infection.<br> '''μομφή, -ῆς (nom commun) (f)''' : reproche.<br> '''μονάς, -δος (nom commun) (f)''' : unité.<br> '''μοναχεῖον, -ίου (nom commun) (n)''' : monastère.<br> '''μοναχός, -οῦ (nom commun) (m)''' : moine.<br> '''μονή, -ῆς (nom commun) (f)''' : action de s’arrêter ; lieu où l’on séjourne.<br> '''μονόκερως, -έρωτος (nom commun) (f)''' : licorne.<br> '''μονομαχεῖον, -ίου (nom commun) (n)''' : lieu de duel.<br> '''μονομαχέω (verbe)''' : se battre en duel.<br> '''μονομαχία, -ας (nom commun) (f)''' : duel.<br> '''μονομάχος, -ου (nom commun) (m)''' : duelliste.<br> '''μονόφθογγος, -όγγου (nom commun) (f)''' : monophtongue.<br> '''μόνος, -η, -ον (adjectif)''' : Seul, unique ; solitaire.<br> '''μόνϝος, -η, -ον (adjectif)''' : Forme ancienne de ''μόνος''.<br> '''μονῳδία, -ας (nom commun) (f)''' : .<br> '''μόνως (adverbe)''' : uniquement.<br> '''μονώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''μόνος''.<br> '''μονώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''μόνος''.<br> '''μορμολύκα, -ας (nom commun) (f)''' : Forme dorienne de ''μορμολύκη''.<br> '''μορμολυκεῖον, -ίου (nom commun) (n)''' : croque-mitaine.<br> '''μορμολύκη, -ης (nom commun) (f)''' : .<br> '''μορμωτός, -ή, -όν (adjectif)''' : effroyable.<br> '''μορμῶ -οῦς (nom commun) (m)''' : monstre marin.<br> '''μορφή, -ῆς (nom commun) (f)''' : forme.<br> '''μόρφωσις, -ώσεως (nom commun) (f)''' : formation.<br> '''μορφῶ (verbe)''' : former.<br> '''μόσχευμα, -ύματος (nom commun) (n)''' : plant.<br> '''μοσχεύω (verbe)''' : planter.<br> '''μοσχοκαρύδιον, -ίου (nom commun) (n)''' : Diminutif de ''μοσχοκάρυον''.<br> '''μοσχοκάρυον, -ύου (nom commun) (n)''' : noix de muscade.<br> '''μόσχος, -ου (nom commun) (m)''' : Musc ; pousse.<br> '''μοχθηρός, -ά, -όν (adjectif)''' : malveillant ; souffrant.<br> '''μοχθηρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''μοχθηρός''.<br> '''μοχθηρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''μοχθηρός''.<br> '''μοχθηρῶς, -ά, -όν (adverbe)''' : .<br> '''μόχθος, -ου (nom commun) (m)''' : peine ; labeur.<br> '''μοχθῶ (verbe)''' : être malveillant.<br> '''μουνάς, -δος (nom commun) (f)''' : Forme ionienne de ''μονάς''.<br> '''μοῦνος, -ύνη, -ῦνον (adjectif)''' : Forme homérique et ionienne de ''μόνος''.<br> '''μῶλυ, -ώλυος (nom commun) (n)''' : moly.<br> '''μῶνος, -η, -ον (adjectif)''' : Forme dorienne de ''μόνος''.<br> '''μορμολύκειον, -ίου (nom commun) (n)''' : masque.<br> '''μορφή, -ῆς (nom commun) (f)''' : forme.<br> '''μόρφωσις, -ώσεως (nom commun) (f)''' : formation.<br> '''μουσεῖον, -ίου (nom commun) (n)''' : musée.<br> '''μούσμων, -ονος (nom commun) (m)''' : mouflon.<br> '''μυδάω (verbe)''' : être moite.<br> '''μυγαλῆ, -ς (nom commun) (f)''' : musaraigne.<br> '''μύγις (adverbe)''' : Forme éolienne de ''μόγις''.<br> '''μυελός, -οῦ (nom commun) (m)''' : moelle.<br> '''μυζῶ (verbe)''' : sucer.<br> '''μυθικός, -ή, -όν (adjectif)''' : mythique.<br> '''μυθιστορία, -ας (nom commun) (f)''' : légende.<br> '''μυθιστορικός, -ή, -όν (adjectif)''' : légendaire.<br> '''μῦθος, -ύθου (nom commun) (m)''' : mythe.<br> '''μυῖα, -ίας (nom commun) (f)''' : mouche.<br> '''μύκης, -τος (nom commun) (m)''' : Champignon. (Par analogie) Toute excroissance fougueuse. Champignon que se forme à la mèche d’une lampe. Virole d’une gaine. Membre viril.<br> '''μυκτήρ, -ῆρος (nom commun) (m)''' : museau.<br> '''μύλη, -ης (nom commun) (f)''' : moulin.<br> '''μυλεργάτης, -ου (nom commun) (m)''' : meunier.<br> '''μυλών, -ῶνος (nom commun) (m)''' : meunier.<br> '''μύξα, -ας (nom commun) (f)''' : morve.<br> '''μυρίαπους, -δος (nom commun) (m)''' : mille-pattes.<br> '''μυριάς, -δος (nom commun) (f)''' : .<br> '''μυρίος, -α, -ον (adjectif)''' : Innombrable, immense ; infini.<br> '''μύρμηξ, -κος (nom commun) (m)''' : fourmi.<br> '''μυροϐάλανος, -άνου (nom commun) (f)''' : myrobolan.<br> '''μύρος, -ου (nom commun) (m)''' : parfum.<br> '''μυρσίνα, - (nom commun) (f)''' : myrtille.<br> '''μύρτος, -ου (nom commun) (f)''' : myrtille.<br> '''μῦς, -ός (nom commun) (m)''' : Rat ; souris. Muscle.<br> '''μύσταξ, -κος (nom commun) (f)''' : Forme dorienne de ''μάσταξ'' ; moustache.<br> '''μυστήριον, -ίου (nom commun) (n)''' : sacrement.<br> '''μυστηριώδης, -ης, -ες (adjectif)''' : relatif aux sacrements.<br> '''μυστικός, -ή, -όν (adjectif)''' : secret.<br> '''μυστικῶς (adverbe)''' : secrètement.<br> '''μυστικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''μυστικός''.<br> '''μυστικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''μυστικός''.<br> '''µῦ (nom commun) (n)''' : mu.<br> '''μύχιος, -α, -ον (adjectif)''' : intime.<br> '''μυχός, -οῦ (nom commun)''' : cœur.<br> '''μῶλυ, -ώλυος (nom commun) (n)''' : moly.<br> '''μῶμαι (verbe)''' : méditer.<br> '''μῶμος, -ώμου (nom commun) (m)''' : blâme.<br> '''μῶνυξ, -ώνυχος (nom commun) (m)''' : .<br> '''μωρός, -ά, -όν (adjectif)''' : Émoussé, hébété. Fade, Insipide. Sot, fou, insensé.<br> '''μῶρος, -ώρα, -ῶρον (adjectif)''' : Forme attique de ''μωρός''.<br> '''Μάατ (nom propre) (f)''' : Maât.<br> '''Μαθθαῖος, -ίου (nom propre) (m)''' : Forme alternative de ''Ματθαῖος''.<br> '''Μαθουσάλα, -ας (nom propre) (m)''' : Mathusalem.<br> '''Μαῖα, -ίας (nom propre) (f)''' : Maïa.<br> '''Μαῖρα, -ίρας (nom propre) (f)''' : Maera.<br> '''Μακάριος, -ίου (nom propre) (m)''' : Macaire.<br> '''Μακαρία, -ας (nom propre) (f)''' : Macaria.<br> '''Μάνης, -ου (nom propre) (m)''' : Mani (prophète).<br> '''Μαντώ, -οῦς (nom propre) (f)''' : Manto.<br> '''Μάξυος, -ου (nom commun) (m)''' : Berbère.<br> '''Μαραθών, -ῶνος (nom propre) (m)''' : Marathon.<br> '''Μαργαρίτα, -ας (nom commun) (f) ''' : Marguerite.<br> '''Μαρδοχαῖος, -ίου (nom propre) (m)''' : Mardochée.<br> '''Μάρθα, -ας (nom propre) (f)''' : Martha.<br> '''Μαρία, -ας (nom propre) (f)''' : Marie.<br> '''Μασσαλία, -ας (nom propre) (f)''' : Marseille.<br> '''Μασσαλιώτης, -ου (nom commun) (m)''' : Marseillais.<br> '''Μασσαλιῶτις, -ώτιδα (nom commun) (f)''' : Marseillaise.<br> '''Μαῦρος, -ύρου (nom commun) (m)''' : Maure.<br> '''Μαυσωλεῖον, -ίου (nom propre) (m)''' : Mausolée.<br> '''Μαύσωλος, -ώλου (nom propre) (m)''' : Mausole.<br> '''Ματθαῖος, -ίου (nom propre) (m)''' : Matthieu.<br> '''Μέγαιρα, -ίρας (nom propre) (f)''' : Mégère (une des Érynies).<br> '''Μέδουσα, -ας (nom propre) (f)''' : Méduse.<br> '''Μελέαγρος, -άγρου (nom propre) (m)''' : Méléagre.<br> '''Μελησιγενής, -οῦ (nom propre) (m)''' : Mélésigène.<br> '''Μέλης (nom propre) (m)''' : Mélès (rivière).<br> '''Μελέτη, -ης (nom propre) (f)''' : Mélété.<br> '''Μέλισσα, -ίσσης (nom propre) (f)''' : Mélissa.<br> '''Μελίτη, -ης (nom propre) (f)''' : Mélite.<br> '''Μελπομένη, -ης (nom propre) (f)''' : Melpomène.<br> '''Μελχισέδεκ (nom propre) (m)''' : Melchisédech.<br> '''Μέμφις, -δος (nom propre) (f)''' : Memphis.<br> '''Μενίππη, -ης (nom propre) (f)''' : Ménippe.<br> '''Μένιππος, -ίππου (nom propre) (m)''' : Ménippe.<br> '''Μεχείρ (nom commun) (m)''' : Méchir.<br> '''Μήδεια, -ίας (nom propre) (f)''' : Médée.<br> '''Μηδία, -ας (nom propre) (f)''' : Médie.<br> '''Μῆδος, -ήδου (nom commun) (m)''' : Mède.<br> '''Μηλινόη, -ης (nom propre) (f)''' : Mélinoé.<br> '''Μῆτις, -ήτιδος (nom propre) (f)''' : [[wikt:Métis|Métis]].<br> '''Μίδας, -ου (nom propre) (m)''' : Midas.<br> '''Μίθρας, -ου (nom propre) (m)''' : Mithra.<br> '''Μίθρης, -ου (nom propre) (m)''' : Forme ionienne de ''Μίθρας''.<br> '''Μιθριδάτης, -ου (nom propre) (m)''' : Mithridate.<br> '''Μιχαίας, -ου (nom propre) (m)''' : Michée.<br> '''Μίνως, -ωος (nom propre) (m)''' : Minos.<br> '''Μίσφρης, -ου (nom propre) (m)''' : Menkhéperrê.<br> '''Μνεῦις, -ύιδος (nom propre) (m)''' : Mnévis.<br> '''Μοῖρα, -ίρας (nom propre) (f)''' : Moire.<br> '''Μοῖσα, -ίσης (nom propre) (f)''' : Forme éolienne de ''Μοῦσα''.<br> '''Μόνοικος, -ίκου (nom propre) (f)''' : Monaco.<br> '''Μορμώ, -οῦς (nom propre) (f)''' : Mormo.<br> '''Μορφεύς, -έως (nom propre) (m)''' : [[wikt:Morphée|Morphée]].<br> '''Μοῦσα, -ύσης (nom propre) (f)''' : Muse.<br> '''Μοϋσῆς, -έως (nom propre) (m)''' : Forme alternative de ''Μωϋσῆς''.<br> '''Μυκερίνος, -ου (nom propre) (m)''' : Mykérinos.<br> '''Μύρμηξ, -ηκος (nom propre) (f)''' : Myrmex.<br> '''Μῶμος, -ώμου (nom propre) (m)''' : Momos.<br> '''Μωσῆς, -έως (nom propre) (m)''' : Forme alternative de ''Μωϋσῆς''.<br> '''Μωϋση, -ης (nom propre) (m)''' : Forme alternative de ''Μωϋσῆς''.<br> '''Μωϋσῆς, -έως (nom propre) (m)''' : Moïse.<br> '''Μῶσα, -ώσης (nom propre) (f)''' : Forme dorienne de ''Μοῦσα''.<br> '''Μῶἁ, -ἁς (nom propre) (f)''' : Forme laconienne de ''Μοῦσα''.<br> ==Ν== '''ναϝός, -οῦ (nom commun) (m)''' : Forme laconienne de ''ναός''.<br> '''ναί (particule)''' : oui.<br> '''ναίχι (adverbe)''' : certes.<br> '''ναίω (verbe)''' : Habiter. Héberger. Construire ; s’installer quelque part.<br> '''νᾶνος, -άνου (nom commun) (m)''' : nain.<br> '''ναός, -οῦ (nom commun) (m)''' : temple.<br> '''νᾶπυ, -άπυος (nom commun) (f)''' : moutarde (plante).<br> '''νάρθηξ, -κος (nom commun) (f)''' : férule.<br> '''ναρθηκοφόρος, -ου (nom commun) (m)''' : licteur.<br> '''νάρκη, -ης (nom commun) (f)''' : torpeur.<br> '''νάρκωσις, -όσεως (nom commun) (f)''' : engourdissement.<br> '''ναρκωτικός, -ή, -όν (adjectif)''' : engourdissant.<br> '''ναρκῶ (verbe)''' : engourdir.<br> '''νάσσω (verbe)''' : Presser, fouler. Bourrer, emplir ; encombrer.<br> '''ναύκληρος, -ήρου (nom commun) (m)''' : .<br> '''ναῦος, -ύου (nom commun) (m)''' : Forme éolienne de ''ναός''.<br> '''ναῦς, -εώς (nom commun) (f)''' : navire.<br> '''ναυτικός, -ή, -όν (adjectif)''' : marin.<br> '''ναύτης, -ου (nom commun) (m)''' : marin.<br> '''νάφθα, -ης (nom commun) (f)''' : naphte.<br> '''νεανιεία, -ας (nom commun) (f)''' : jouvence.<br> '''νεανίας, -ου (nom commun) (m)''' : jouvenceau.<br> '''νεᾶνις, -άνιδος (nom commun) (f)''' : jouvencelle.<br> '''νεανιεύομαι (verbe)''' : .<br> '''νεανίζω (verbe)''' : .<br> '''νεηνίης, -ου (nom commun) (m)''' : Forme homérique et ionienne de ''νεανίας''.<br> '''νεῆνις, -ήνιδος (nom commun) (f)''' : Forme homérique et ionienne de ''νεᾶνις''.<br> '''νεῖκος, -ίκους (nom commun) (n)''' : Bataille ; combat.<br> '''νεῖλος, -ίλου (nom commun) (m)''' : rivière de vallée.<br> '''νεῖος, -ία, -ῖον (adjectif)''' : Forme ionienne de ''νέος''.<br> '''νεκραγωγός, -οῦ (nom commun) (m)''' : nécragogue.<br> '''νεκρός, -οῦ (nom commun) (m)''' : mort, cadavre.<br> '''νεκροψία, -ας (nom commun) (f)''' : nécropsie.<br> '''νεκυαγωγός, -οῦ (nom commun) (m)''' : nékyagogue.<br> '''νεκυάμϐατος, -άτου (nom commun) (m)''' : .<br> '''νεκυδαίμων, -ονος (nom commun) (m)''' : .<br> '''νεκυηπόλος, - (nom commun) (m)''' : .<br> '''νέκυια, -ίας (nom commun) (f)''' : descente aux Enfers.<br> '''νεκυοδαίμων, -ονος (nom commun) (m)''' : .<br> '''νεκυομαντεῖον, -ίου (nom commun) (n)''' : nékyomantien.<br> '''νεκυοπομπός, -οῦ (nom commun) (m)''' : nékyopompe.<br> '''νέκυς, -ος (nom commun) (m)''' : mort.<br> '''νάννα, -ας (nom commun) (f)''' : tante.<br> '''νέμος, -ους (nom commun) (n)''' : clairière.<br> '''νέμω (verbe)''' : Distribuer, partager, attribuer une part, diviser, découper. Attribuer à un troupeau la partie du pâturage où on le mène paître. Habiter. Occuper, détenir. Conduire, gouverner, administrer. Tenir pour, regarder comme (avec double accusatif). (Par suite) Choisir pour, admettre comme.<br> '''νέννος, -ου (nom commun) (m)''' : oncle.<br> '''νέομαι (verbe)''' : arriver.<br> '''νεοσσιά, -ᾶς (nom commun) (f)''' : nid.<br> '''νεοσσός, -οῦ (nom commun) (m)''' : oisillon, poussin.<br> '''νέος, -α, -ον (adjectif)''' : Nouveau ; jeune. Neuf.<br> '''νευρόσπαστον, -ου (nom commun) (n)''' : marionnette.<br> '''νεῦρον, -ύρου (nom commun) (n)''' : Fibre ; nerf.<br> '''νευρώδης, -ης, -ες (adjectif)''' : nerveux.<br> '''νεῦσις, -ύσεως (nom commun) (f)''' : nœud.<br> '''νεύω (verbe)''' : hocher la tête.<br> '''νέφος, -ους (nom commun) (n)''' : nuage.<br> '''νεφρῖτις, -ίτης (nom commun) (f)''' : néphrite (maladie).<br> '''νεφρός, -οῦ (nom commun) (m)''' : rein.<br> '''νεώς, -ώ (nom commun) (m)''' : Forme attique de ''ναός''.<br> '''νέω (verbe)''' : Flotter ; filer la laine.<br> '''νή (particule)''' : par. (Particule interjective.) (+ nom de divinité a l’accusatif)<br> '''νῆμα, -ήματος (nom commun) (n)''' : fil.<br> '''νηματικός, -ή, -όν (adjectif)''' : .<br> '''νηματώδης, -ης, -ες (adjectif)''' : fibreux.<br> '''νηός, -οῦ (nom commun) (m)''' : Forme ionienne de ''ναός''.<br> '''νήπιον, -ίου (nom commun) (n)''' : bébé.<br> '''νήπιος, -ίου (nom commun) (m)''' : bébé.<br> '''νήριον, -ίου (nom commun) (n)''' : laurier-rose.<br> '''νῆσσα, -ήσσης (nom commun) (f)''' : canard.<br> '''νηστεία, -ας (nom commun) (f)''' : jeûne.<br> '''νηστεύω (verbe)''' : jeûner.<br> '''νῆττα, -ήττης (nom commun) (f)''' : Forme attique de ''νῆσσα''.<br> '''νίζω (verbe)''' : nettoyer.<br> '''νικέω (verbe)''' : Forme ionienne de ''νικῶ''.<br> '''νίννη, -ης (nom commun) (f)''' : grand-mère ; belle-mère.<br> '''νίκη, -ης (nom commun) (f)''' : victoire.<br> '''νικῶ (verbe)''' : vaincre.<br> '''νιπτήρ, -ῆρος (nom commun) (m)''' : lavabo.<br> '''νίπτω (verbe)''' : Variante de ''νίζω''.<br> '''νίφω (verbe)''' : neiger.<br> '''νίψ, -φος (nom commun) (f)''' : neige.<br> '''νόημα, -ήµατος (nom commun) (n)''' : Source de la pensée ; intelligence. Pensée (chose).<br> '''νόησις, -ήσεως (nom commun) (f)''' : pensée (processus).<br> '''νοητικός, -ή, -όν (adjectif)''' : Mental ; intellectuel.<br> '''νοητικῶς (adverbe)''' : Mentalement ; intellectuellement.<br> '''νοητικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''νοητικός''.<br> '''νοητικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''νοητικός''.<br> '''νοητικώτατα, -, - (adverbe)''' : Superlatif de ''νοητικῶς''.<br> '''νοητικώτερον, -, - (adverbe)''' : Comparatif de ''νοητικῶς''.<br> '''νοητός, -ή, -όν (adjectif)''' : pensable.<br> '''νοητῶς (adverbe)''' : .<br> '''νοητώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''νοητός''.<br> '''νοητώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''νοητός''.<br> '''νομάς, -δος (nom commun) (m/f)''' : nomade.<br> '''νομοθέτης, -ου (nom commun) (m)''' : législateur.<br> '''νόμος, -ου (nom commun) (m)''' : Ce qui est attribué en partage. (Par suite) Opinion générale. Maxime. Règle de conduite.<br> '''νομός, -οῦ (nom commun) (m)''' : Part, portion. (Par extension) Division de territoire. Pâturage, pacage. Herbe, fourrage.<br> '''νόννος, -ου (nom commun) (m)''' : grand-père ; beau-père.<br> '''νόος, -ου (nom commun) (m)''' : Faculté de penser.<br> '''νόσημα, -ήματος (nom commun) (n)''' : infirmité ; fléau.<br> '''νοσοκομεῖον, -ίου (nom commun) (n)''' : hôpital.<br> '''νοσοκόμος, -ος, -ν (adjectif)''' : soignant<br> '''νόσος, -ου (nom commun) (f)''' : maladie.<br> '''νότιος, -ία, -ιον (adjectif)''' : méridional.<br> '''νοτιώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''νότιως''.<br> '''νοτιώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''νότιως''.<br> '''νοτιώτατα, -, - (adverbe)''' : Superlatif de ''νότιως''.<br> '''νοτιώτερον, -, - (adverbe)''' : Comparatif de ''νότιως''.<br> '''νότιως (adverbe)''' : méridionalement.<br> '''νότος, -ου (nom commun) (m)''' : sud.<br> '''νουθετέω (verbe)''' : Admonester ; avertir. Conseiller.<br> '''vοῦς, -οῦ (nom commun) (m)''' : Variante de ''νόος''.<br> '''νοῶ (verbe)''' : Penser. Percevoir, noter, observer. Ourdir. Avoir l’intention de. (Linguistique) Signifier, en parlant des mots.<br> '''νυκτάλωψ, -πία (nom commun) (f)''' : nyctalopie.<br> '''νυκτερίς, -δος (nom commun) (f)''' : chauve-souris.<br> '''νύκτερος, -ος, -ον (adjectif)''' : nocturne.<br> '''νύμφα, -ῦμφας''' : Forme dorienne de ''νύμφη''.<br> '''νύμφη, -ης (nom commun) (f)''' : nymphe.<br> '''νυμφόληπτος, -ος, -ον (adjectif)''' : .<br> '''νυμφιάω (verbe)''' : Être possédé des nymphes ; être en délire.<br> '''νυμφομανία, -ας (nom commun) (n)''' : nymphomanie.<br> '''νῦν (adverbe)''' : maintenant.<br> '''νύξ, -κτός (nom commun) (f)''' : nuit.<br> '''νυός, -οῦ (nom commun) (f)''' : belle-fille.<br> '''νῦ (nom commun) (n)''' : nu.<br> '''νῶμα, -ώματος (nom commun) (n)''' : Forme ionienne de ''νόημα''.<br> '''νωπός, -ή, -όν (adjectif)''' : frais.<br> '''νῶσις, -ώσεως (nom commun) (f)''' : Forme ionienne de ''νόησις''.<br> '''νωτίζω (verbe)''' : tourner le dos.<br> '''νῶτον, -ώτου (nom commun) (n)''' : (Anatomie) Derrière, dos. (Figuré) Large surface courbe (mer, ciel).<br> '''νωτοστροφέω (verbe)''' : tourner le dos.<br> '''νώ (pronom personnel)''' : nous (nous deux).<br> '''Ναϐαταῖος, -ίου (nom commun) (m)''' : Nabatéen.<br> '''Ναϐατηνή, -ῆς (nom propre) (f)''' : Nabatea.<br> '''Ναϊάς, -δος (nom propre) (f)''' : Naïade.<br> '''Νάρκισσος, -ίσσου (nom propre) (m)''' : Narcisse.<br> '''Ναυσίθοος, - (nom propre) (m)''' : Nausithoos.<br> '''Ναυσικάα, -ας (nom propre) (f)''' : Nausicaa.<br> '''Ναυσίνοoς, - (nom propre) (m)''' : Nausinoos.<br> '''Νέαιρα, -ίρας (nom propre) (f)''' : Nérée.<br> '''Νεάπολις, -όλεως (nom propre) (f)''' : Naples.<br> '''Νεῖλος, -ίλου (nom propre) (m)''' : Nil.<br> '''Νειλῶτις, -ώτεως (nom propre) (f)''' : Nilotis.<br> '''Νέμεσις, -έσεως (nom propre) (f)''' : [[wikt:Némésis|Némésis]].<br> '''Νέσσος, -ου (nom propre) (m)''' : Nessos.<br> '''Νέστωρ, -ορος (nom propre) (m)''' : Nestor.<br> '''Νεφέλη, -ης (nom propre) (f)''' : Néphélé.<br> '''Νεφελοκοκκυγία, -ας (nom propre) (f)''' : Coucouville-les-Nuées. (Ville décrite par Aristophane dans ''Les Oiseaux''.)<br> '''Νηρεύς, -έως (nom propre) (m)''' : Nérée.<br> '''Νηρῇς, -δος (nom propre) (f)''' : Néréide.<br> '''Νίκαια, -ίας (nom propre) (f)''' : Nice.<br> '''Νίκανδρος, -άνδρου (nom propre) (m)''' : Nicandre.<br> '''Νίκη, -ης (nom propre) (f)''' : [[wikt:Niké|Niké]].<br> '''Νικόλαος, -άου (nom propre) (m)''' : Nicolas.<br> '''Νιόϐη, -ης (nom propre) (f)''' : Niobé.<br> '''Νότος, -ου (nom propre) (m)''' : [[wikt:Notos|Notos]]. (dieu du vent du sud)<br> '''Νουμιδία, -ας (nom propre) (f)''' : Numidie.<br> '''Νύξ, -κτός (nom propre) (f)''' : [[wikt:Nyx|Nyx]].<br> '''Νῶε (nom propre) (m)''' : Noé.<br> ==Ξ== '''ξανθóς, -ή, -όν (adjectif)''' : Jaune ; jaunâtre. Blond.<br> '''ξενοδοχεῖον, -ίου (nom commun) (n)''' : hôtel.<br> '''ξένος, -η, -ον (adjectif)''' : étranger, insolite.<br> '''ξένος, -ου (nom commun) (m)''' : étranger ; hôte.<br> '''ξενών, -ῶνος (nom commun) (f)''' : .<br> '''ξέσις, -εως (nom commun) (f)''' : .<br> '''ξεχνῶ (verbe)''' : oublier.<br> '''ξέω (verbe)''' : gratter ; raser. Polir.<br> '''ξηρός, -ά, -όν (adjectif)''' : sec.<br> '''ξῖ (nom commun) (n)''' : xi.<br> '''ξιφίας, -ου (nom commun) (m)''' : espadon.<br> '''ξιφίδιον, -ίου (nom commun) (n)''' : dague.<br> '''ξίφος, -ους (nom commun) (n)''' : glaive.<br> '''ξύλον, -ου (nom commun) (n)''' : bois (matériau). Tout objet en bois.<br> '''ξυλόσπογγος, -όγγου (nom commun) (m)''' : tersorium.<br> '''ξύλωσις, -ώσεως (nom commun) (f)''' : charpente.<br> '''ξυνός, -ή, -όν (adjectif)''' : Forme ionienne de ''κοινός''.<br> '''ξύω (verbe)''' : Variante de ''ξέω''.<br> '''Ξενοφῶν, -τος (nom propre) (m)''' : Xénophon.<br> '''Ξέρξης, -ου (nom propre) (m)''' : Xerxès.<br> '''Ξοῦθος, -ύθου (nom propre) (m)''' : Xouthos.<br> ==Ο== '''ὁ (article défini)''' : le.<br> '''ὄασις, -άσεως (nom commun) (f)''' : Voie, route ; chemin.<br> '''ὀγδοήκοντα (adjectif numéral)''' : quatre-vingts.<br> '''ὀγκάομαι (verbe)''' : .<br> '''ὄγκος, -ου (nom commun) (m)''' : tumeur.<br> '''ὄγχνη, -ης (nom commun) (f)''' : poirier.<br> '''ὅδερος, -έρου (nom commun) (m)''' : ventre.<br> '''ὁδηγός, -οῦ (nom commun) (m)''' : conducteur.<br> '''ὁδηγῶ (verbe)''' : conduire.<br> '''ὁδός, -οῦ (nom commun) (f)''' : Voie, route ; chemin.<br> '''ὀδούς, -όντος (nom commun) (m)''' : dent.<br> '''ὀδμή, -ῆς (nom commun) (f)''' : Forme plus ancienne de ''ὀσμή''.<br> '''ὀδύνη, -ης (nom commun) (f)''' : douleur ; chagrin.<br> '''ὀδυσάω (verbe)''' : Haïr ; être fâché.<br> '''ὀδυσσειακός, -ή, -όν (adjectif)''' : odysséen.<br> '''ὀδύσσομαι (verbe)''' : Être irrité contre quelqu’un.<br> '''ὄζω (verbe)''' : Exhaler une odeur.<br> '''ὅθεν (adverbe relatif)''' : d’où (je viens).<br> '''οἷ (adverbe relatif)''' : là où (je vais).<br> '''ὀθόνη, -ης (nom commun) (f)''' : toile.<br> '''οἴ (interjection)''' : hélas ; ouille.<br> '''οἴκημα, -ήματος (nom commun) (n)''' : résidence.<br> '''οἰκηματικός, -ή, -όν (adjectif)''' : résidentiel.<br> '''οἰκημάτιον, -ίου (nom commun) (n)''' : .<br> '''οἰκητήριον, -ίου (nom commun) (n)''' : domicile.<br> '''οἰκοπεδικός, -ή, -όν (adjectif)''' : .<br> '''οἰκόπεδον, -έδου (nom commun) (n)''' : .<br> '''οἰκοπεδοποίησις, -ήσεως (nom commun) (f)''' : .<br> '''οἶκος, -ου (nom commun) (m)''' : maison.<br> '''οἰκοῦμαι (verbe)''' : .<br> '''οἰκουμένη, -ης (nom commun) (f)''' : .<br> '''οἰκουμενικός, -ή, -όν (adjectif)''' : .<br> '''ϝοῖκος, -ίκου (nom commun) (m)''' : Forme ancienne de ''οἶκος''.<br> '''οἰκεῖος, -ία, -ῖον (adjectif)''' : de la maison.<br> '''οἰκός, -τος (nom commun) (n)''' : Forme ionienne de ''εἰκός''.<br> '''οἰκοτροφεῖον, -ίου (nom commun) (n)''' : pensionnat.<br> '''οικότροφος, -όφου (nom commun) (m/f)''' : pensionnaire.<br> '''οἶκτος, -ἴκτου (nom commun) (m)''' : pitié.<br> '''οἰκτρός, -ά, -όν (adjectif)''' : .<br> '''οἰκτρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''οἰκτρός''.<br> '''οἰκτρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''οἰκτρός''.<br> '''οἰκτρότατα, -, - (adverbe)''' : Superlatif de ''οἰκτρῶς''.<br> '''οἰκτρότερον, -, - (adverbe)''' : Comparatif de ''οἰκτρῶς''.<br> '''οἰκτρῶς (adverbe)''' : .<br> '''οἰκῶ (verbe)''' : Habiter ; occuper.<br> '''οἴμοι (interjection)''' : pauvre de moi.<br> '''οἶνος, -ἴνου (nom commun) (m)''' : vin.<br> '''ϝοῖνος, -ίνου (nom commun) (m)''' : Forme dorienne de ''οἶνος''.<br> '''οἰνοχόη, -ης (nom commun) (f)''' : œnochoé ; échansonne.<br> '''οἰνοχόος, -ου (nom commun) (m)''' : échanson.<br> '''ὄϊς, -ΐος (nom commun) (m/f)''' : bélier ; brebis.<br> '''οἶς, -ός (nom commun) (m/f)''' : Forme attique de ''ὄϊς''.<br> '''οἷος, -ἵα, -ἷον (adjectif)''' : tel.<br> '''οἰσοφάγος, -ου (nom commun) (m)''' : œsophage.<br> '''οἶσος, -ἴσου (nom commun) (m)''' : gattilier.<br> '''οἶστρος, -ίστρου (nom commun) (m)''' : (au propre) taon. (au figuré) fureur, désir ; passion.<br> '''οἶτος, -ἴτου (nom commun) (m)''' : destin.<br> '''οἰφόλης, -ης, ες (adjectif)''' : obscène.<br> '''οἴφω (verbe)''' copuler.<br> '''οἰωνοσκοπία, -ας (nom commun) (f)''' : augure.<br> '''οἰωνοσκόπος, -ου (nom commun) (m)''' : augure.<br> '''οἰωνός, -οῦ (nom commun) (m)''' : présage, augure.<br> '''ὀκνείω (verbe)''' : Forme homérique de ''ὀκνέω''.<br> '''ὀκνέω (verbe)''' : hésiter.<br> '''ὄκνος, -ου (nom commun) (m)''' : hésitation.<br> '''ὀκτώ (adjectif numéral)''' : huit.<br> '''ὄκχος, -ου (nom commun) (m)''' : Forme poétique de ''ὄχος''.<br> '''ὀλιγάρχης, -ου (nom commun) (m)''' : oligarque.<br> '''ὀλιγαρχία, -ας (nom commun) (f)''' : oligarchie.<br> '''ὀλίγος, -η, -ον (adjectif)''' : .<br> '''ὁλικός, -ή , -όν (adjectif)''' : total.<br> '''ὁλικῶς (adverbe)''' : totalement.<br> '''ὁλικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ὁλικός''.<br> '''ὁλικώτερος, -έρη, -ώτερον (adjectif)''' : Comparatif de ''ὁλικός''.<br> '''ὁλικώτατα, -, - (adverbe)''' : Superlatif de ''ὁλικῶς''.<br> '''ὁλικώτερον, -, - (adverbe)''' : Comparatif de ''ὁλικῶς''.<br> '''ὄλισϐος, -ίσϐου (nom commun) (m)''' : godemichet.<br> '''ὁλκή, -ῆς (nom commun) (f)''' : attraction.<br> '''ὄλλυμι (verbe)''' : (Sens actif) Perdre, causer la perte, détruire, annihiler. Mourir. (Sens passif) Périr.<br> '''ὅλος, -η, -ον (adjectif)''' : entier, complet.<br> '''ὁλοφύρομαι (verbe)''' : .<br> '''ὄλπη, -ης (nom commun) (f)''' : .<br> '''ὀλυμπιακός, -ή, -όν (adjectif)''' : olympien.<br> '''ὀλυμπικός, -ή, -όν (adjectif)''' : olympique.<br> '''ὀλύμπιος, -ία, -ύμπιον (adjectif)''' : olympien.<br> '''ὁμαδικός, -ήν, -όν (adjectif)''' : .<br> '''ὁμαλός, -ή, -όν (adjectif)''' : lisse.<br> '''ὁμάς, -δος (nom commun) (f)''' : équipe.<br> '''ὄμϐρος, -ου (nom commun) (m)''' : tempête de pluie, orage, envoyé par Zeus. Eau. Inondation.<br> '''ὁμηρικός, -ή, -όν (adjectif)''' : homérique.<br> '''ὅμηρος, -ήρου (nom commun) (m/f)''' : otage.<br> '''ὂ μικρόν (nom commun) (n)''' : omicron.<br> '''ὁμιλία, -ας (nom commun) (f)''' : discours.<br> '''ὁμιλῶ (verbe)''' : discourir.<br> '''ὁμίχλη, -ης (nom commun) (f)''' : brouillard.<br> '''ὄμμα, -τος (nom commun) (n)''' : œil.<br> '''ὅμοιος, ία, -ον (adjectif)''' : semblable.<br> '''ὁμοῖος, -, -ῖον (adjectif)''' : Forme homérique, ionienne, et ancienne attique de ''ὅμοιος''.<br> '''ὁμοίιος, -, - (adjectif)''' : Forme homérique de ''ὅμοιος''.<br> '''ὁμοιοκαταληξία, -ας (nom commun) (f)''' : rime.<br> '''ὁμοιοκατάληκτος, -η, -ο (adjectif)''' : rimique.<br> '''ὁμοιοκαταληκτῶ (verbe)''' : rimer.<br> '''ὁμοούσιος, -ος, -ον (adjectif)''' : de même substance.<br> '''ὁμοιούσιος, -ος, -ον (adjectif)''' : de nature semblable.<br> '''ὁμοιοτέλευτος, -ύτου (nom commun) (m)''' : homéotéleute.<br> '''ὀμοίωμα, -ώματος (nom commun) (n)''' : effigie.<br> '''ὁμόνοια, -ας (nom commun) (f)''' : concorde.<br> '''ὁμός, -ή, -όν (adjectif)''' : Pareil ; semblable.<br> '''ὁμοῦ (adverbe)''' : En un même lieu, ensemble. (Par suite) Ensemble, à la fois. (Par extension) Auprès, proche.<br> '''ὀμφαλός, -οῦ (nom commun) (m)''' : nombril.<br> '''ὀμφή, -ῆς (nom commun) (f)''' : oracle, prophétie.<br> '''ὀμφής, -ής, -ές : (adjectif)''' : prophétique.<br> '''ὀμφητήρ, -τρός (nom commun) (m)''' : prophète.<br> '''ὄνειδος, -ίδους (nom commun) (n)''' : Reproche ; disgrâce.<br> '''ὀνειρευτής, -οῦ (nom commun) (m)''' : rêveur.<br> '''ὄνειρος, -ίρου (nom commun) (m)''' : rêve.<br> '''ὀνειροπόλος, -ου (nom commun) (m)''' : rêvasseur.<br> '''ὀνειροπωλῶ (verbe)''' : rêvasser.<br> '''ὀνοκρόταλος, -άλου (nom commun) (m)''' : pélican.<br> '''ὄνομα, -όματος (nom commun) (n)''' : nom.<br> '''ὀνοματοποιία, -ας (nom commun) (f)''' : mot imitant un son.<br> '''ὄνος, -ου (nom commun) (m/f)''' : Âne ; ânesse.<br> '''ὄνυξ, -χος (nom commun) (m)''' : ongle.<br> '''ὄνυμα, -ύματος (nom commun) (n)''' : Forme dorienne et éolienne de ''ὄνομα''.<br> '''ὀνύχιον, -ίου (nom commun) (m)''' : griffe.<br> '''ὄνω (adverbe)''' : Forme éolienne de ''ἄνω''.<br> '''ὀξίνης, -ης, -ες (adjectif)''' : aigre.<br> '''ὀξύα, -ας (nom commun) (f)''' : Hêtre. Arme en bois de hêtre comme un épieu ou un javelot.<br> '''ὀξύγαλα, -άλακτος (nom commun) (n)''' : petit-lait.<br> '''ὀξύμωρος, -ος, -ον (adjectif)''' : .<br> '''ὀξύς, -εῖα, -ύ (adjectif)''' : Aigu. Pointu. Tranchant en parlant d’une arme. Piquant en parlant de la sensation (chaleur, froid, douleur), du goût (acidité). Vif. Fin, pénétrant. Prompt à l’action.<br> '''ὀξύτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ὀξύς''.<br> '''ὀξύτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ὀξύς''.<br> '''ὀπαδός, -οῦ (nom commun) (m)''' : fan.<br> '''ὀπάζω (verbe)''' : .<br> '''ὀπή, -ῆς (nom commun) (f)''' : Trou ; orifice.<br> '''ὄπιον, -ίου (nom commun) (n)''' : opium.<br> '''ὄπισθεν (adverbe)''' : arrière, derrière.<br> '''ὄπις, -δος (nom commun) (f)''' : (Sens négatif) Revanche, vengeance. (Sens positif) Regard bienveillant, égard. (Religion) Égards dûs aux dieux par les hommes.<br> '''ὄπις (adverbe)''' : en arrière (sans mouvement).<br> '''ὀπίσω (adverbe)''' : en arrière (avec mouvement), vers l’arrière.<br> '''ὁπλή, -ῆς (nom commun) (f)''' : sabot (corne pédestre de certains animaux).<br> '''ὅπλη, -ης (nom commun) (f)''' : Forme homérique de ''ὁπλή''.<br> '''ὁπλήεις, -εις, -ης (f)''' : .<br> '''ὁπλίτης, -ου (nom commun) (m)''' : Soldat pesamment armé.<br> '''ὅπλον, -ου (nom commun) (n)''' : Outil. (Au pluriel) Armes.<br> '''ὀποπάναξ, -κος (nom commun) (m)''' : jus de légume.<br> '''ὀπός, -οῦ (nom commun) (m)''' : jus ; suc.<br> '''ὀπτασία, -ας (nom commun) (f)''' : fantasme.<br> '''ὀπτικός, -ή, -όν (adjectif)''' : visuel.<br> '''ὀπτός, -ή, -όν (adjectif)''' : Rôti, grillé. (Par extension) Cuit. Visible, vu.<br> '''ὀπτῶ (verbe)''' : Rôtir, griller.<br> '''ὅραμα, -άματος (nom commun) (n)''' : vision, spectacle.<br> '''ὄρασις, -άσεως (nom commun) (f)''' : vue.<br> '''ὁρατός, -ή, -όν, (adjectif)''' : visible.<br> '''ὁράω (verbe)''' : voir, regarder.<br> '''ὀρεάς, -δος (nom commun) (f)''' : oréade.<br> '''ὁρέω (verbe)''' : Forme ionienne de ''ὁράω''.<br> '''ὄρημι (verbe)''' : Forme éolienne de ''ὁράω''.<br> '''ὄργανον, -άνου (nom commun) (n)''' : organe, instrument de musique.<br> '''ὀργασμός, -οῦ (nom commun) (m)''' : point culminant du plaisir sexuel.<br> '''ὀργάς, -δος (nom commun) (f)''' : .<br> '''ὀργή, -ῆς (nom commun) (f)''' : colère.<br> '''ὀργῶ (verbe)''' : enfler, être empli de désir amoureux.<br> '''ὄρεξις, -έξεως (nom commun) (f)''' : appétit.<br> '''ὀρθογραφία, -ας (nom commun) (f)''' : écriture correcte.<br> '''ὀρθόδοξος, -ος, -ον (adjectif)''' : orthodoxe.<br> '''ὀρθός, -ή, -όν (adjectif)''' : droit.<br> '''ὀρθότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ὀρθός''.<br> '''ὀρθότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ὀρθός''.<br> '''ὀρθῶς (adverbe)''' : droitement.<br> '''ὁρίζων, -οντος (m)''' : horizon.<br> '''ὁρίζω (verbe)''' : limiter, borner.<br> '''ὁρμά, -ᾶς (nom commun) (f)''' : Saut, essor.<br> '''ὁρμέω (verbe)''' : (Marine) Mouiller, être à l'ancrage.<br> '''ὁρμή, -ῆς (nom commun) (f)''' : élan (rapidité).<br> '''ὅρμημα, -ήματος (nom commun) (f)''' : impulsion, désir.<br> '''ὅρμησις, -ήσεως (nom commun) (f)''' : élan.<br> '''ὁρμητικός, -ή, -όν (adjectif)''' : impétueux.<br> '''ὁρμητικῶς (adverbe)''' : impétueusement.<br> '''ὁρμητικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ὁρμητικός''.<br> '''ὁρμητικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ὁρμητικός''.<br> '''ὁρμητικώτατα, -, - (adverbe)''' : Superlatif de ''ὁρμητικῶς''.<br> '''ὁρμητικώτερον, -, - (adverbe)''' : Comparatif de ''ὁρμητικῶς''.<br> '''ὁρμητικότης, -τος (nom commun) (f)''' : impétuosité.<br> '''ὁρμῶ (verbe)''' : Pousser, démarrer, mettre en mouvement ; presser, se presser ; aller vite.<br> '''ὄρνεον, -έου (nom commun) (n)''' : oiseau.<br> '''ὄρνις, -θος (nom commun) (m/f)''' : oiseau.<br> '''ὄρνυμι (verbe)''' : animer, inciter.<br> '''ὄρος, -ους (nom commun) (m)''' : Montagne ; colline, hauteur.<br> '''ὅρος, -ου (nom commun) (m)''' : borne.<br> '''ὀρός, -οῦ (nom commun) (m)''' : sérum.<br> '''ὄρρος, -ου (nom commun) (m)''' : (Familier) cul.<br> '''ὀροφή, -ῆς (nom commun) (f)''' : plafond.<br> '''ὁρόω (verbe)''' : Forme homérique de ''ὁράω''.<br> '''ὄρτυξ, -ύκου (nom commun) (m/f)''' : caille.<br> '''ὀρυκτήρ, -ῆρος (nom commun) (m)''' : mineur.<br> '''ὄρυξ, -γος (nom commun) (m)''' : oryx.<br> '''ὀρύσσω (verbe)''' : creuser.<br> '''ὀρφανία, -ας (nom commun) (f)''' : .<br> '''ὀρφανίζω (verbe)''' : .<br> '''ὀρφανιστής, -οῦ (nom commun) (m)''' : .<br> '''ὀρφανός, -ή, -όν (adjectif)''' : orphelin.<br> '''ὀρφανός, -οῦ (nom commun) (m)''' : orphelin.<br> '''ὀρφανοτροφεῖον, -ίου (nom commun) (n)''' : orphelinat.<br> '''ὄρανος, -άνου (nom commun) (m)''' : Forme éolienne de ''οὐρανός''.<br> '''ὀρείχαλκος, -άλκου (nom commun) (m)''' : orichalque.<br> '''ὄρφνα, -ας (nom commun) (f)''' : Forme dorienne de ''ὄρφνη''.<br> '''ὄρφνη, -ης (nom commun) (f)''' : obscurité.<br> '''ὀρφνός, -ή, -όν (adjectif)''' : obscur.<br> '''ὀρφνότατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ὀρφνός''.<br> '''ὀρφνότερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ὀρφνός''.<br> '''ὀρφνῶς (adverbe)''' : obscurément.<br> '''ὀρχήστρα, -ας (nom commun) (f)''' : place du chœur.<br> '''ὀρχηστρίς, -δος (nom commun) (f)''' : danseuse.<br> '''ὄρχις, -εως (nom commun) (m/f)''' : (Au masculin) Testicule, ovaire, orchidée. (Au féminin) Sorte d’olive.<br> '''ὀρχοῦμαι (verbe)''' : danser.<br> '''ὄσδω (verbe)''' : Forme dorienne de ''ὄζω''.<br> '''ὀσμή, -ῆς (nom commun) (f)''' : odeur.<br> '''ὀστέον, -ου (nom commun) (n)''' : os ; noyau.<br> '''ὀστοῦν, -οῦ (nom commun) (n)''' : Forme attique de ''ὀστέον''.<br> '''ὀστεῦν, -εῦ (nom commun) (n)''' : Forme poétique de ''ὀστέον''.<br> '''ὄστιον, -ίου (nom commun) (n)''' : Forme éolienne de ''ὀστέον''.<br> '''ὅς, ἥ, ὅ''' : (adjectif démonstratif) Celui-ci, celle-ci, ceci. (pronom relatif) Qui, lequel, laquelle.<br> '''ὄστρειον, -ίου (nom commun) (n)''' : Forme de ''ὄστρεον''.<br> '''ὄστρεον, -έου (nom commun) (n)''' : huître.<br> '''ὀσφραίνομαι (verbe)''' : sentir.<br> '''ὄσφρησις, -ήσεως (nom commun) (f)''' : odorat.<br> '''ὀσφυαλγία, -ας (nom commun) (f)''' : lumbago.<br> '''ὀσφῦς, -ύος (nom commun) (f)''' : flanc.<br> '''οὐ- (préfixe)''' : préfixe privatif.<br> '''οὐαί (interjection)''' : ah.<br> '''οὖας, -τός (nom commun) (n)''' : Forme homérique de ''οὖς''.<br> '''οὐδείς, -μία, -έν (adjectif indéfini ; pronom indéfini)''' : Aucun, personne.<br> '''οὐδέποτε (adverbe)''' : jamais.<br> '''οὐδέτερος, -έρα, -έτερον (adjectif)''' : ni l’un ni l’autre.<br> '''οὕδωρ, -ατος (nom commun) (n)''' : Forme béotienne de ''ὕδωρ''.<br> '''οὐκί (adverbe)''' : Forme attique et ionienne de ''οὐ''<br> '''οὐλή, -ῆς (nom commun) (f)''' : cicatrice.<br> '''οὔνομα, -όματος (nom commun) (n)''' : Forme homérique et ionienne de ''ὄνομα''.<br> '''οὖθαρ, -ὔθατος (nom commun) (n)''' : Mamelle. (Anatomie) Pis.<br> '''οὔποτε (adverbe)''' : jamais.<br> '''οὐροδοχεῖον, -ίου (nom commun) (n)''' : pot de chambre.<br> '''οὖρον, -ὔρου (nom commun) (n)''' : urine.<br> '''οὖρος, -ὔρου (nom commun) (m)''' : gardien.<br> '''οὗ (adverbe relatif)''' : où (je suis).<br> '''οὐ (particule)''' (Devient ''οὐκ'' devant un mot commençant par une voyelle à esprit doux, et ''οὐχ'' devant un mot commençant par une voyelle à esprit rude.) : non.<br> '''οὖν (adverbe)''' : Sans doute, réellement, en effet. Donc, eh bien.<br> '''οὐρά, -ᾶς (nom commun) (f)''' : queue.<br> '''οὐράνη, -ης (nom commun) (f)''' : pot de chambre.<br> '''οὐράνιος, -α, -ον (adjectif)''' : céleste.<br> '''οὐρανός, -οῦ (nom commun) (m)''' : ciel.<br> '''οὔρησις, -ήσεως (nom commun) (f)''' : miction.<br> '''οὐρητρίς, -δος (nom commun) (f)''' : pot de chambre.<br> '''οὖρον, -ὔρου (nom commun) (n)''' : urine.<br> '''οὐρῶ (verbe)''' : uriner.<br> '''οὐσία, -ας (nom commun) (f)''' : (Philosophie) Essence, substance, être. Élément, substance première. Biens, fortune, richesse.<br> '''οὐσιαστικόν, -οῦ (nom commun) (n)''' : substantif.<br> '''οὐσίη, -ης (nom commun) (f)''' : Forme ionienne de ''οὐσία''.<br> '''οὐσιώδης, -ης, -ες (adjectif)''' : essentiel.<br> '''οὖς, ὠτός (nom commun) (n)''' : oreille.<br> '''οὔτις, -ις, -ι (pronom)''' : personne.<br> '''οὐχί (adverbe)''' : Forme attique et homérique de ''οὐ''<br> '''ὀφείλημα, -ήματος (nom commun) (n)''' : dette.<br> '''ὀφείλω (verbe)''' : devoir de l'argent.<br> '''ὀφέλλω (verbe)''' : Forme homérique et de ''ὀφείλω''.<br> '''ὄφελος, -έλους (nom commun) (n)''' : .<br> '''ὀφθαλμός, -οῦ (nom commun) (m)''' : œil.<br> '''ὄφις, -εως (nom commun) (m)''' : serpent.<br> '''ὀφρῦς, -ύος (nom commun) (f)''' : sourcil.<br> '''ὀχεύω (verbe)''' copuler.<br> '''ὄχημα, -ήματος (nom commun) (n)''' : véhicule.<br> '''ϝόχος, -ου (nom commun) (m)''' : Forme ancienne de ''ὄχος''.<br> '''ὄχθη, -ης (nom commun) (f)''' : Rive ; berge.<br> '''ὀχλοκρατία, -ας (nom commun) (f)''' : ochlocratie.<br> '''ὄχλος, -ου (nom commun) (m)''' : Foule ; multitude. Tumulte d'une foule.<br> '''ὄχνη, -ης (nom commun) (f)''' : poire.<br> '''ὄχος, -ου (nom commun) (m)''' : Réceptacle, abri. Tout ce qui sert à transporter, véhicule.<br> '''-οχος, -όχου (suffixe) (m)''' : .<br> '''ὀχυρός, -ά, -όν (adjectif)''' : ferme.<br> '''ὀχυρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ὀχυρός''.<br> '''ὀχυρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ὀχυρός''.<br> '''ὀχυρῶς (adverbe)''' : fermement.<br> '''ὀχύρωμα, -ώματος (nom commun) (n)''' : forteresse.<br> '''ὀχυρῶ (verbe)''' : fortifier.<br> '''ὀχῶ (verbe)''' : .<br> '''ὄψις, -εως (nom commun) (f)''' : vue. (perception visuelle)<br> '''ὄψον, -ου (nom commun) (n)''' : (Cuisine) Plat cuisiné, mets. Assaisonnement, sauce. Délicatesse. (Attique) Poisson.<br> '''ὀψοποιός, -οῦ (nom commun) (m)''' : cuisinier.<br> '''ὀψώνης, -ου (nom commun) (m)''' : .<br> '''ὀψώνιον, -ίου (nom commun) (n)''' : Provisions, vivres. Salaire.<br> '''ὀψωνῶ (verbe)''' : .<br> '''ὄψ, -πός (nom propre) (f)''' : Voix. Parole, discours. Œil. (Par métonymie) Visage.<br> '''Ὀδρύσης, -ου (nom commun) (m)''' : Odryse.<br> '''Ὀδύσσεια, -ίας (nom propre) (f)''' : Odyssée.<br> '''Ὀδυσσεία, -ας (nom propre) (f)''' : Forme alternative de ''Ὀδύσσεια''.<br> '''Ὀδυσσεύς, -έως (nom propre) (m)''' : Ulysse.<br> '''Ὀζυμάνδιος, -ίου (nom propre) (m)''' : Ozymandias.<br> '''Ὄθων, -ου (nom propre) (m)''' : Othon.<br> '''Οἰδίπους, -οδος (nom propre) (m)''' : Œdipe.<br> '''Οἰκλῆς, -έους (nom propre) (m)''' : Oïclès.<br> '''Οἰνεύς, -έως (nom propre) (m)''' : Œnée.<br> '''Οἰνόμαος, -άου (nom propre) (m)''' : Œnomaos.<br> '''Οἰταῖος, -ίη, -ῖον (adjectif)''' : œtéen.<br> '''Οἴτη, -ης (nom propre) (f)''' : Œta.<br> '''Ὄλθφες, - (nom propre) (m)''' : Olivier.<br> '''Ὀλυμπιάς, -δος (nom propre) (f)''' : olympiade.<br> '''Ὀλύμπια, -ίων (nom propre) (n)''' : Jeux olympiques.<br> '''Ὄλυμπος, -ύμπου (nom propre) (m)''' : Olympe.<br> '''Ὀλυσσεύς, -έως (nom propre) (m)''' : Forme de ''Ὀδυσσεύς''.<br> '''Ὀλυττεύς, -έως (nom propre) (m)''' : Forme de ''Ὀδυσσεύς''.<br> '''Ὅμηρος, -ήρου (nom propre) (m)''' : Homère. (poète grec)<br> '''Ὄνειρος, -ίρου (nom propre) (m)''' : Oniros.<br> '''Ὀννῶφρις, -ίδος (nom propre) (m)''' : Onnophris.<br> '''Ὀνούφριος, -ίου (nom propre) (m)''' : Onuphre.<br> '''Ὄρανος, -άνου (nom propre) (m)''' : Forme éolienne de ''Οὐρανός''.<br> '''Ὀρσηίς, -δος (nom propre) (f)''' : Orséis (épouse d'Hellen).<br> '''Ὄρθρος, -ου (nom propre) (m)''' : Orthros.<br> '''Ὀρφεύς, -έως (nom propre) (m)''' : Orphée.<br> '''Ὄσιρις, -ίριδος (nom propre) (m)''' : [[wikt:Osiris|Osiris]].<br> '''Οὐδαῖος, -ίου (nom propre) (m)''' : Udée.<br> '''Οὑδυσσεύς, -έως (nom propre) (m)''' : Forme de ''Ὀδυσσεύς''.<br> '''Οὐλιξεύς, -έως (nom propre) (m)''' : Forme de ''Ὀδυσσεύς''.<br> '''Οὐλίξης, -ους (nom propre) (m)''' : Forme de ''Ὀδυσσεύς''.<br> '''Οὐόλκος, -ου (nom commun) (m)''' : Volque.<br> '''Οὐρανία, -ας (nom propre) (f)''' : Uranie.<br> '''Οὐρανός, -οῦ (nom propre) (m)''' : [[wikt:Ouranos|Ouranos]].<br> '''Ὀφηλία, -ας (nom propre) (f)''' : Ophélie.<br> '''Ὀφιοῦχος, -ύχου (nom propre) (f)''' : Serpentaire.<br> '''Ὄφις, -εως (nom propre) (m)''' : Serpent.<br> ==Π== '''παγά, -ᾶς (nom commun) (f)''' : Forme dorienne de ''πηγή''.<br> '''παγίδευσις, -ύσεως (nom commun) (f)''' : .<br> '''παγιδεύω (verbe)''' : piéger.<br> '''παγίς, -δος (nom commun) (f)''' : piège.<br> '''παγκόσμιος, -α, -ον (adjectif)''' : universel.<br> '''πάγκοσμος, -όσμου (nom commun) (m)''' : univers.<br> '''πάγος, -ου (nom commun) (m)''' : glace (eau à l'état solide).<br> '''πάγουρος, -ύρου (nom commun) (m)''' : crabe.<br> '''πάγχυ (adverbe)''' : totalement.<br> '''παθοποιός, -ός, -όν (adjectif)''' : Qui afflige le corps ou l’âme.<br> '''πάθος, -ους (nom commun) (n)''' : Ce que l’on éprouve. Évènement, conjoncture. État de l’âme agitée par diverses circonstances.<br> '''παιάν, -ᾶνος (nom commun) (m)''' : péan.<br> '''παίγνιον, -ίου (nom commun) (n)''' : jeu.<br> '''παιδαγωγός, -οῦ (nom commun) (m)''' : éducateur.<br> '''παιδάριον, -ίου (nom commun) (n)''' : gamin.<br> '''παιδεραστής, -οῦ (nom commun) (m)''' : amant de garçon.<br> '''παιδιά, -ᾶς (nom commun) (f)''' : jeu.<br> '''παιδίον, -ου (nom commun) (n)''' : petit enfant.<br> '''παιδοτρίϐης, -ου (nom commun) (m)''' : maître de gymnastique.<br> '''παίδων παῖδες (nom commun) (m/f)''' : Petits-fils/Petites-filles.<br> '''παίζω (verbe)''' : jouer.<br> '''παίκτης, -ου (nom commun) (m)''' : joueur.<br> '''παῖς, -δός (nom commun) (m/f)''' : enfant ; jeune serviteur.<br> '''παιωνία, -ας (nom commun) (f)''' : pivoine.<br> '''παιών, -ος (nom commun) (m)''' : physicien.<br> '''παλαιός, -ά, -όν (adjectif)''' : ancien.<br> '''παλιγγενεσία, -ας (nom commun) (f)''' : Renaissance, résurrection. Régénération.<br> '''παλιγγενεσιακός, -ά, -όν (adjectif)''' : palingénésiaque.<br> '''πάλιν (adverbe)''' : encore.<br> '''παλλακή, -ῆς (nom commun) (f)''' : concubine.<br> '''παλλακίς, -δος (nom commun) (f)''' : concubine.<br> '''πάλλαξ, -κος (nom commun) (m/f)''' : jeune enfant.<br> '''πάλληξ, -κος (nom commun) (m/f)''' : Forme ionienne de ''πάλλαξ''.<br> '''πάλλω (verbe)''' : vibrer.<br> '''παλμός, -οῦ (nom commun) (m)''' : vibration.<br> '''παλός, -οῦ (nom commun) (m/f)''' : forme dorienne de ''πηλός''.<br> '''παμμεγεθέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''παμμεγέθης''.<br> '''παμμεγεθέστερος, -έρα, -έστερον (adjectif)''' : Comparatif de ''παμμεγέθης''.<br> '''παμμεγέθης, -ης, -ες (adjectif)''' : immense.<br> '''παμμεγέθως (adverbe)''' : immensément.<br> '''πάμπαν (adverbe)''' : totalement.<br> '''πάμφλεκτος, -ος, -ον (adjectif)''' : .<br> '''πανάκεια, -ας (nom commun) (f)''' : remède universel.<br> '''πάναξ, -κος (nom commun) (m)''' : plante médicinale.<br> '''πανδοκεῖον, -ίου (nom commun) (n)''' : auberge.<br> '''πανδοκεύς, -έως (nom commun) (m)''' : aubergiste.<br> '''παράδοσις, -όσεως (nom commun) (f)''' : transmission ; tradition.<br> '''πανήγυρις, -ύρεως (nom commun) (f)''' : réunion.<br> '''πάνθηρ, -ος (nom commun) (m)''' : panthère.<br> '''πανέλοψ, -πος (nom commun) (m)''' : Forme éolienne et dorienne de ''πηνέλοψ''.<br> '''πανοῦργος, -ύργα, -ῦργον (adjectif)''' : .<br> '''παντοπωλεῖον, -ίου (nom commun) (n)''' : épicerie.<br> '''παντοπώλης, -ου (nom commun) (m)''' : épicier.<br> '''πάνυ (adverbe)''' : totalement.<br> '''πάππας, -ου (nom commun) (m)''' : papa.<br> '''πάππος, -ου (nom commun) (m)''' : papi.<br> '''πάπυρος, -ύρου (nom commun) (m)''' : papyrus.<br> '''παρά (adverbe ; préposition)''' : (avec le génitif) D’auprès de, du côté de. (avec le datif) Auprès avec l’idée de toute absence de mouvement. Chez, dans, en. (Avec l’accusatif) Auprès de, vers avec l’idée de mouvement.<br> '''παρά- (préfixe)''' : Auprès. Vers. Le long de. Contre. En détournant.<br> '''παραϐάλλω (verbe)''' : s’emparer de.<br> '''παράδειγμα, -ίγματος (nom commun) (n)''' : modèle.<br> '''παραδειγματικός, -ή, -όν (adjectif)''' : modèle.<br> '''παράδεισος, -ίσου (nom commun) (m)''' : parc ; paradis.<br> '''παραδέχομαι (verbe)''' : admettre.<br> '''παραδίδωμι (verbe)''' : transmettre ; remettre.<br> '''παράθυρος, -ου (nom commun) (f)''' : Porte de côté ; porte dérobée.<br> '''παρακινῶ (verbe)''' : .<br> '''παρακλαυσίθυρον, -ύρου (nom commun) (n)''' : paraclausithuron.<br> '''παραλείπω (verbe)''' : omettre.<br> '''παράλειψις, -ίψεως (nom commun) (f)''' : omission.<br> '''πάρδαλις, -άλεως (nom commun) (f)''' : léopard.<br> '''παράλληλος, -η, -ον (adjectif)''' : Porte de côté ; porte dérobée.<br> '''παραλήρησις, -ήσεως (nom commun) (f)''' : délire.<br> '''παράμεσος, -ου (nom commun) (m)''' : annulaire.<br> '''παραμυθέομαι (verbe)''' : exhorter.<br> '''παραμύθιον, -ίου (nom commun) (m)''' : exhortation.<br> '''παραποίησις, -ήσεως (nom commun) (f)''' : contrefaçon.<br> '''παραποιῶ (verbe)''' : contrefaire.<br> '''παράρτημα, -ήματος (nom commun) (n)''' : annexe.<br> '''παρασάγγης, -ου (nom commun) (m)''' : parasange. (env. 6 km)<br> '''παράσιτος, -ος, -ον (adjectif)''' : Qui sert de mets en surplus ; Parasite.<br> '''παραίσθησις, -ήσεως (nom commun) (f)''' : illusion.<br> '''παράστασις, -άσεως (nom commun) (f)''' : représentation.<br> '''παραστράτημα, -ήματος (nom commun) (n)''' : incartade.<br> '''παρειά, -ᾶς (nom commun) (f)''' : joue.<br> '''παρελθών, -όντος (nom commun) (m)''' : passé.<br> '''παρεξήγησις, -ήσεως (nom commun) (f)''' : malentendu.<br> '''παρεξηγῶ (verbe)''' : méprendre.<br> '''παρεργάτης, -ου (nom commun) (m)''' : assistant.<br> '''παρεύνασθαι (verbe)''' : représenter.<br> '''πάρευνος, -ος, -ον (adjectif)''' : .<br> '''παρθενεία, -ας (nom commun) (f)''' : virginité .<br> '''παρθένειος, -α, -ον (adjectif)''' : virginal.<br> '''παρθενικός, -ή, -όν (adjectif)''' : de vierge.<br> '''παρθενικῶς (adverbe)''' : virginalement.<br> '''παρθενικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''παρθενικός''.<br> '''παρθενικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''παρθενικός''.<br> '''παρθενικώτατα, -, - (adverbe)''' : Superlatif de ''παρθενικῶς''.<br> '''παρθενικώτερον, -, - (adverbe)''' : Comparatif de ''παρθενικῶς''.<br> '''παρθένος, -ος, -ον (adjectif)''' : vierge.<br> '''παρθενεύω (verbe)''' : devenir jeune fille.<br> '''παρθενών, -ῶνος (nom commun) (m)''' : parthénon.<br> '''παρθικός, -ή, -όν (adjectif)''' : parthe.<br> '''παρθιστί (adverbe)''' : en parthe.<br> '''παρίσθμιον, -ίου (nom commun) (n)''' : (anatomie) amygdale.<br> '''παρόρμησις, -ήσεως (nom commun) (f)''' : impulsion.<br> '''παρορμητικός, -ή, -όν (adjectif)''' : impulsif.<br> '''παρορμητικῶς (adverbe)''' : impulsivement.<br> '''παρορμητικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''παρορμητικός''.<br> '''παρορμητικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''παρορμητικός''.<br> '''παρορμῶ (verbe)''' : impulser.<br> '''παρσένος, -ος, -ον (adjectif)''' : Forme laconienne de ''παρθένος''.<br> '''παρών, -όντος (nom commun) (m)''' : présent.<br> '''παρωνυχία, -ας (nom commun) (f)''' : panaris.<br> '''πᾶς, -σα, -ᾶν (adjectif)''' : (Au singulier) Chaque, chacun. Tout entier, tout. (Au pluriel) Tous.<br> '''πάσσω (verbe)''' : .<br> '''παστά, -ᾶς (nom commun) (f)''' : pâte.<br> '''παστός, -ή, -όν (adjectif)''' : .<br> '''πάσχω (verbe)''' : Être affecté de telle ou telle façon, telle ou telle affection, sensation ou sentiment.<br> '''πατήρ, -ρός (nom commun) (m)''' : père.<br> '''πάτος, -ου (nom commun) (m)''' : sentier.<br> '''πατριά, -ᾶς (nom commun) (f)''' : tribu, famille.<br> '''πατριάρχης, -ου (nom commun) (m)''' : patriarche.<br> '''πατρίς, -δος (nom commun) (f)''' : patrie.<br> '''πατροφονεύς, -έως (nom commun) (m)''' : patricide.<br> '''πατροφόνος, -ου (nom commun) (m)''' : patricide.<br> '''πατῶ (verbe)''' : Manger, absorber. Fouler aux pieds. Fouler le sol.<br> '''παῦρος -ύρα, -ῦρον (adjectif)''' : En petit nombre. (Par extension) Petit, court.<br> '''παῦσις, -ύσεως (nom commun) (f)''' : cessation.<br> '''παύω (verbe)''' : cesser.<br> '''πάφλασμα, -άσματος (nom commun) (n)''' : .<br> '''πάχνη, -ης (nom commun) (f)''' : givre.<br> '''παχύς, -εῖα, -ύ (adjectif)''' : Épais, gras.<br> '''πεδά (préposition)''' : Forme arcado-chypriote, dorienne et éolienne de ''μετά''.<br> '''πεδιάς, -δος (nom commun) (f)''' : plaine.<br> '''πεδίον, -ου (nom commun) (n)''' : champ.<br> '''πέζα, -ης (nom commun) (f)''' : cheville du pied.<br> '''πεζός, -ή, -όν (adjectif)''' : piéton.<br> '''πεζῶς (adverbe)''' : .<br> '''πεζώτατα, -, - (adverbe)''' : Superlatif de ''πεζῶς''.<br> '''πεζώτερον, -, - (adverbe)''' : Comparatif de ''πεζῶς''.<br> '''πεζώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''πεζός''.<br> '''πεζώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''πεζός''.<br> '''πείθομαι (verbe)''' : persuader ; suivre.<br> '''πείθω (verbe)''' : convaincre ; persuader.<br> '''πεῖνα, -ίνας (nom commun) (f)''' : faim.<br> '''πεινῶ (verbe)''' : avoir faim.<br> '''πεῖρα, -ίρας (nom commun) (f)''' : Essai, tentative ; épreuve.<br> '''πειράζω (verbe)''' : Essayer ; tenter.<br> '''πειράομαι (verbe)''' : essayer.<br> '''πειρασμός, -οῦ (nom commun) (m)''' : Épreuve, essai ; expérience. Tentation.<br> '''πειρατής, -οῦ (nom commun) (m)''' : pirate.<br> '''πειρῶ (verbe)''' : .<br> '''πελεκάν, -ᾶνος (nom commun) (m)''' : pélican.<br> '''πελεκῖνος, -ίνου (nom commun) (m)''' : pélican.<br> '''πέλεκυς, -έκεως (nom commun) (m)''' : hache.<br> '''πέλμα, -τος (nom commun) (n)''' : Plante du pied ; tige des pommes et des poires.<br> '''πελώριος, -α, -ον (adjectif)''' : prodigieux.<br> '''πελωρίς, -δος (nom commun) (f)''' : moule.<br> '''πέλωρ, -ος (nom commun) (n)''' : prodige.<br> '''πέμμα, -τος (nom commun) (n)''' : gâteau.<br> '''πεμπτουσία, -ας (nom commun) (f)''' : quintessence.<br> '''πεντάφυλλον, -ύλλου (nom commun) (n)''' : potentille.<br> '''πέντε (adjectif numéral)''' : cinq.<br> '''πεντήκοντα (adjectif numéral)''' : cinquante.<br> '''πενθερά, -ᾶς (nom commun) (f)''' : belle-mère.<br> '''πενθερός, -οῦ (nom commun) (m)''' : beau-père.<br> '''πένθος, -ους (nom commun) (n)''' : deuil.<br> '''πέος, -ους (nom commun) (n)''' : pénis.<br> '''πέπερι, -τος (nom commun) (n)''' : poivre.<br> '''πέπλος, -ου (nom commun) (m)''' : péplos.<br> '''πέπλωμα, -ώματος (nom commun) (n)''' : robe.<br> '''πεπτός, -ή, -όν (adjectif)''' : cuit.<br> '''πέπων, -ονος (nom commun) (m)''' : melon.<br> '''περαίνω (verbe)''' : Finir, conclure.<br> '''πέρασμα, -άσματος (nom commun) (n)''' : passage.<br> '''πέρας, -τος (nom commun) (n)''' : Fin, limite.<br> '''πέρδιξ, -ικος (nom commun) (m/f)''' : perdrix.<br> '''πέρδομαι (verbe)''' : péter (faire un pet).<br> '''περιϐόλιον, -ίου (nom commun) (n)''' : .<br> '''περιδέραιον, -ου (nom commun) (n)''' : collier (bijou).<br> '''περιδέραιος, -ος, -ου (adjectif)''' : .<br> '''περίζωμα, -ώματος (nom commun) (n)''' : caleçon.<br> '''περιήγησις, -ήσεως (nom commun) (f)''' : Voyage ; parcours.<br> '''περιηγοῦμαι (verbe)''' : Voyager ; parcourir.<br> '''περιηγητής, -οῦ (nom commun) (m)''' : voyageur.<br> '''περιλαμϐάνω (verbe)''' : .<br> '''περίληψις, -ήψεως (nom commun) (f)''' : résumé.<br> '''περίναιον, -ίου (nom commun) (n)''' : périnée.<br> '''περιπατητικός, -ή, -όν (adjectif)''' : péripatéticien.<br> '''περιπατῶ (verbe)''' : Circuler, aller et venir ; se promener (Par extension) (Figuré) Se comporter, se conduire, vivre de telle ou de telle manière.<br> '''περιπέτεια, -ας (nom commun) (f)''' : aventure.<br> '''περιπίπτω (verbe)''' : tomber autour, sur.<br> '''περιποιοῦμαι (verbe)''' : s'occuper de.<br> '''περιποιῶ (verbe)''' : .<br> '''περιστερά, -ᾶς (nom commun) (f)''' : pigeon, colombe.<br> '''περιστερός, -οῦ (nom commun) (m)''' : pigeon, colombe. (Pour un mâle de ces espèces.)<br> '''περιστερεών, -ῶνος (nom commun) (m)''' : pigeonnier, colombier.<br> '''περιφρονῶ (verbe)''' : mépriser.<br> '''περιφρούρησις, -ήσεως (nom commun) (f)''' : protection.<br> '''περιφρουρῶ (verbe)''' : protéger.<br> '''περκνός, -ή, -όν (adjectif)''' : noirâtre.<br> '''περκνότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''περκνός''.<br> '''περκνότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''περκνός''.<br> '''περκνότατα, -, - (adverbe)''' : Superlatif de ''περκνῶς''. '''περκνότερον, -, - (adverbe)''' : Comparatif de ''περκνῶς''. '''περκνῶς (adverbe)''' : noirâtrement.<br> '''πέρνημι (verbe)''' : Exploiter, vendre. (Au passif) Être vendu.<br> '''περόνη, -ης (nom commun) (f)''' : agrafe, clavette.<br> '''περῶ (verbe)''' : passer.<br> '''πέσσω (verbe)''' : Digérer ; cuire. Mûrir.<br> '''πετάννυμι (verbe)''' : .<br> '''πέτασος, -άσου (nom commun) (m)''' : pétase.<br> '''πετεεινός, -ή, -όν (adjectif)''' : Forme homérique de ''πετεινός''.<br> '''πετεινός, -ή, -όν (adjectif)''' : capable de voler.<br> '''πετεσοũχος, -ύχου (nom commun) (m)''' : petsuchos.<br> '''πετηνός, -ή, -όν (adjectif)''' : Forme ionienne de ''πετεινός''.<br> '''πετῶ (verbe)''' : voler (planer dans le ciel).<br> '''πεύκη, -ης (nom commun) (f)''' : pin.<br> '''πεύθομαι (verbe)''' : Forme poétique de ''πυνθάνομαι''.<br> '''πέψις, -εως (nom commun) (f)''' : digestion.<br> '''πηγή, -ῆς (nom commun) (f)''' : source.<br> '''πήγνυμι (verbe)''' : .<br> '''πηδάλιον, -ίου (nom commun) (n)''' : talaria.<br> '''πήδημα, -ήματος (nom commun) (n)''' : saut.<br> '''πηδόν, -οῦ (nom commun) (n)''' : .<br> '''πηδός, -οῦ (nom commun) (f)''' : .<br> '''πηδῶ (verbe)''' : sauter.<br> '''πῇ (adverbe interrogatif)''' : par où.<br> '''πήληξ, -κος (nom commun) (m)''' : .<br> '''πηλός, -οῦ (nom commun) (m/f)''' : boue.<br> '''πήμων, -ων, -ον (adjectif)''' : nuisible.<br> '''πηνέλοψ, -πος (nom commun) (m)''' : canard sauvage.<br> '''πήνη, -ης (nom commun) (f)''' : bobine.<br> '''πηνήκη, -ης (nom commun) (f)''' : perruque.<br> '''πηνηκίζω (verbe)''' : .<br> '''πηνήκισμα, -ίσματος (nom commun) (n)''' : .<br> '''πῆνος, -ήνου (nom commun) (m)''' : .<br> '''πῆξις, -ήξεως (nom commun) (f)''' : .<br> '''πήρα, -ας (nom commun) (f)''' : besace.<br> '''πήριξ, -ικος (nom commun) (m/f)''' : Forme crétoise de ''πέρδιξ''.<br> '''πῆχυς, -ήχεως (nom commun) (m)''' : avant-bras.<br> '''πιέζω (verbe)''' : Presser ; appuyer.<br> '''πίεσις, -έσεως (nom commun) (f)''' : pression.<br> '''πῖ (nom commun) (n)''' : pi.<br> '''πίθακος, -άκου (nom commun) (m)''' : Forme dorienne de ''πίθηκος''.<br> '''πιθανός, -ή, -όν (adjectif)''' : probable.<br> '''πιθανῶς (adverbe)''' : probablement.<br> '''πιθανώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''πιθανός''.<br> '''πιθανώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''πιθανός''.<br> '''πιθηκοειδής, -ής, -ές (adjectif)''' : .<br> '''πίθηκος, -ήκου (nom commun) (m)''' : singe.<br> '''πίθων, -ονος (nom commun) (m)''' : Singe, petit singe.<br> '''πῖλος, -ίλου (nom commun) (m)''' : pileus.<br> '''πίμπλημι (verbe)''' : remplir.<br> '''πίναξ, -κος (nom commun) (m)''' : tableau.<br> '''πίπτω (verbe)''' : tomber.<br> '''πίσσα, -εως (nom commun) (f)''' : poix.<br> '''πιστάκη, -ης (nom commun) (f)''' : pistachier.<br> '''πιστάκιον, -ίου (nom commun) (n)''' : pistache.<br> '''πίστις, -εως (nom commun) (f)''' : Foi. Confiance en autrui. Ce qui fait foi. Résultat de la confiance. Moyen d’inspirer confiance, de persuader ; preuve.<br> '''πιστότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''πιστός''.<br> '''πιστότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''πιστός''.<br> '''πιστός, -ή, -όν (adjectif)''' : fidèle ; loyal.<br> '''πιστότατα, -, - (adverbe)''' : Superlatif de ''πιστῶς''.<br> '''πιστότερον, -, - (adverbe)''' : Comparatif de ''πιστῶς''.<br> '''πιστῶς (adverbe)''' : fidèlement ; loyalement.<br> '''πίστωσις, -ώσεως (nom commun) (f)''' : crédit.<br> '''πισύγγιον, ίου (nom commun) (n)''' : Diminutif de ''πίσυγγος''.<br> '''πίσυγγος, -ύγγου (nom commun) (m)''' : cordonnier.<br> '''πίττα, -ας (nom commun) (f)''' : Forme attique de ''πίσσα''.<br> '''πίτα, -ας (nom commun) (f)''' : pita.<br> '''πλαγκτός, -ή, -όν (adjectif)''' : errant.<br> '''πλαδαρός, -ά, -όν (adjectif)''' : Forme dorienne de ''βλαδαρός''.<br> '''πλάζω (verbe)''' : errer.<br> '''πλᾶθος, -άθους (nom commun) (n)''' : Forme dorienne de ''πλῆθος''.<br> '''πλακοῦς, -ύντος (nom commun) (m)''' : Gâteau ; galette.<br> '''πλανάτας, -ου (nom commun) (m)''' : Forme dorienne de ''πλανήτης''.<br> '''πλάνης, -τος (nom commun) (m)''' : vagabond.<br> '''πλανήτης, -ου (nom commun) (m)''' : planète.<br> '''πλάν (préposition)''' : Forme dorienne de ''πλήν''.<br> '''πλανῶ (verbe)''' : vagabonder.<br> '''πλάξ, -κός (nom commun) (f)''' : plaque.<br> '''πλάσμα, -τος (nom commun) (n)''' : Ouvrage façonné, modelé ; figure. Modulation de la voix. Contrefaçon, imitation. Travail de composition.<br> '''πλάσσω (verbe)''' : former, mouler.<br> '''πλατέως (adverbe)''' : largement.<br> '''πλατύτατος, -άτη, -ύτατον (adjectif)''' : Superlatif de ''πλατύς''.<br> '''πλατύτερος, -έρα, -ύτερον (adjectif)''' : Comparatif de ''πλατύς''.<br> '''πλατύς, -εῖα, -ύ (adjectif)''' : large.<br> '''πλάττω (verbe)''' : Forme attique de ''πλάσσω''.<br> '''πλέθρον, -ου (nom commun) (n)''' : plèthre. (env. 30 m)<br> '''πλεῖστος, -ίστη, -ῖστον (adjectif)''' : Superlatif de ''πολύς''.<br> '''πλείων, -ων, -ῖον (adjectif)''' : Comparatif de ''πολύς''.<br> '''πλεῖθος, -ίθους (nom commun) (n)''' : Forme béotienne de ''πλῆθος''.<br> '''πλῆθος, -ήθους (nom commun) (n)''' : .<br> '''πληθύς, -ος (nom commun) (n)''' : Forme ionienne de ''πλῆθος''.<br> '''πληθώρα, -ας (nom commun) (f)''' : plénitude.<br> '''πλήθω (verbe)''' : remplir.<br> '''πληκτικός, -ή, -όν (adjectif)''' : ennuyeux.<br> '''πληκτικότης, -ητος (nom commun) (f)''' : ennui.<br> '''πλῆκτρον, -ήκτρου (nom commun) (n)''' : plectre.<br> '''πλῆξις, -ήξεως (nom commun) (f)''' : ennui.<br> '''πλήν (préposition)''' : plus que.<br> '''πληρέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''πλήρης''.<br> '''πληρέστερος, -έρα, -έστερον (adjectif)''' : Comparatif de ''πλήρης''.<br> '''πλήρης, -ης, -ῆρες (adjectif)''' : complet ; plein.<br> '''πλήρως (adverbe)''' : complètement ; pleinement.<br> '''πληρῶ (verbe)''' : compléter ; emplir.<br> '''πλήσσω (verbe)''' : Frapper, battre. (Au passif) Être battu, subir une défaite.<br> '''πλήττω (verbe)''' : Forme attique de ''πλήσσω''.<br> '''πλοῖον, -ίου (nom commun) (n)''' : navire, bateau ; vaisseau.<br> '''πλούσιος, -α, -ον (adjectif)''' : riche, opulent.<br> '''πλουσιότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''πλούσιος''.<br> '''πλουσιότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''πλούσιος''.<br> '''πλουσίως (adverbe)''' : richement.<br> '''πλουτηρός, -ά, -όν (adjectif)''' : dispensateur de richesse.<br> '''πλουτίζω (verbe)''' : (voix active) enrichir ; (voix passive) s’enrichir, être enrichi.<br> '''πλουτίνδην (adverbe)''' : en choisissant parmi les plus riches.<br> '''πλουτοτήριος, -α, -ον (adjectif)''' : Capable d’enrichir.<br> '''πλουτοκρατία, -ας (nom commun) (f)''' : ploutocratie.<br> '''πλοῦτος, -ύτου (nom commun) (m)''' : richesse, opulence.<br> '''πλουτῶ (verbe)''' : être riche.<br> '''πλύνω (verbe)''' : laver des vêtements.<br> '''πνεῦμα, -ύματος (nom commun) (n)''' : Souffle. Exhalaison ; odeur. Esprit.<br> '''πνευματικός, -ή, -όν (adjectif)''' : spirituel.<br> '''πνευματικότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''πνευματικός''.<br> '''πνευματικότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''πνευματικός''.<br> '''πνευματικότατα, -, - (adverbe)''' : Superlatif de ''πνευματικῶς''.<br> '''πνευματικότερον, -, - (adverbe)''' : Comparatif de ''πνευματικῶς''.<br> '''πνευματικῶς (adverbe)''' : spirituellement.<br> '''πνεύμων, -ονος (nom commun) (m)''' : poumon.<br> '''πνέω (verbe)''' : souffler.<br> '''πνιγηρός, -ά, -όν (adjectif)''' : étouffant, où l’on étouffe (Par extension) Étroit, resserré.<br> '''πνίγω (verbe)''' : étrangler, étouffer ; suffoquer.<br> '''πνίξ, -γός (nom commun) (f)''' : crampe.<br> '''ποδάριον -ίου (nom commun) (n)''' : Diminutif de ''πούς''.<br> '''πόδιον, -ίου (nom commun) (n)''' : podium.<br> '''πόθεν (adverbe interrogatif)''' : d’où.<br> '''πόθος, -ου (nom commun) (m)''' : Désir ; regret.<br> '''ποῖ (adverbe interrogatif)''' : où (avec mouvement).<br> '''ποίησις, -ήσεως (nom commun) (f)''' : création.<br> '''ποιμήν, -ένος (nom commun) (m)''' : berger.<br> '''ποινή, -ῆς (nom commun) (f)''' : Expiation d’un crime. Argent par lequel on paye les parents de la victime, le prix du sang. Rançon, expiation, châtiment, vengeance. Délivrance. Compensation, récompense.<br> '''ποῖος, -ία, -ῖον (adjectif interrogatif)''' : quel.<br> '''ποιότης, -τος (nom commun) (f)''' : qualité.<br> '''ποιῶ (verbe)''' : faire.<br> '''πολεμικός, -ή, -όν (adjectif)''' : guerrier.<br> '''πολεμικῶς (adverbe)''' : belliqueusement.<br> '''πολεμικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''πολεμικός''.<br> '''πολεμικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''πολεμικός''.<br> '''πολεμιστής, -οῦ (nom commun) (m)''' : guerrier.<br> '''πολεμίστρα, -ας (nom commun) (f)''' : guerrière.<br> '''πόλεμος, -έμου (nom commun) (m)''' : guerre.<br> '''πολεμῶ (verbe)''' : guerroyer.<br> '''πολιός, -ός, -όν (adjectif)''' : gris.<br> '''πόλις, -εως (nom commun) (f)''' : ville.<br> '''πολιτεία, -ας (nom commun) (f)''' : citoyenneté.<br> '''πολίτευμα, -τος (nom commun) (n)''' : gouvernement.<br> '''πολιτεύω (verbe)''' : Être citoyen. Participer au gouvernement, faire de la politique. (Au passif) Être gouverné, en parlant de l’État.<br> '''πολίτης, -ου (nom commun) (m)''' : citoyen.<br> '''πολιτικός, -ή, -όν (adjectif)''' : civique.<br> '''πολῖτις, -ίτιδος (nom commun) (f)''' : citoyenne.<br> '''πολλάκις (adverbe)''' : souvent.<br> '''πολλῶς (adverbe)''' : .<br> '''πολυμάθεια, -ας (nom commun) (f)''' : érudition.<br> '''πολυμαθής, -ής, -ές (adjectif)''' : érudit.<br> '''πολυμήτις, -, - (adjectif)''' : .<br> '''πολυμήχανος, -η, -ον (adjectif)''' : ingénieux.<br> '''πολύτροπος, -ος, -ον (adjectif)''' : astucieux.<br> '''πολύς, -λλή, -ύ (adjectif)''' : nombreux.<br> '''πολύχρωμος, -η, -ον (adjectif)''' : multicolore.<br> '''πομφολυγοπάφλασμα, -άσματος (nom commun) (n)''' : .<br> '''πομφόλυξ, -γος (nom commun) (m)''' : bulle ; ornement en forme de bulle, de rond. (Chimie) Oxyde de zinc.<br> '''πομφός, -οῦ (nom commun) (m)''' : verrue.<br> '''πονηρία, -ας (nom commun) (f)''' : ruse.<br> '''πονηρός, -ά, -όν (adjectif)''' : mauvais, méchant ; pervers.<br> '''πονηρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''πονηρός''.<br> '''πονηρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''πονηρός''.<br> '''πονηρῶς (adjectif)''' : mauvaisement, méchamment ; perversement.<br> '''πόποι (interjection)''' : hélas.<br> '''πορδή, -ῆς (nom commun) (f)''' : pet. (gaz intestinal)<br> '''πορθμεῖον, -ίου (nom commun) (n)''' .<br> '''πορθμεύς, -έως (nom commun) (m)''' nocher.<br> '''πορθμεύω (verbe)''' .<br> '''πορθμός, -οῦ (nom commun) (m)''' : détroit.<br> '''πορνεία, -ας (nom commun)''' : Fornication, prostitution.<br> '''πορνεῖον, -ίου (nom commun) (n)''' lupanar.<br> '''πόρνευμα, -ύµατος (nom commun (n)''' : .<br> '''πόρνευσις, -ύσεως (nom commun) (f)''' : .<br> '''πορνεύτρια, -ας (nom commun) (f)''' : .<br> '''πορνεύω (verbe)''' : prostituer.<br> '''πόρνη, -ης (nom commun) (f)''' : Prostituée, putain.<br> '''πορνικός, -ή, -όν (adjectif)''' : de lupanar.<br> '''πορνοϐοσκεῖον, -ίου (nom commun) (n)''' : lupanar.<br> '''πορνοϐοσκία, -ας (nom commun) (f)''' : prostitution.<br> '''πορνοϐοσκός, -οῦ (nom commun) (m)''' : tenancier.<br> '''πορνοϐοσκῶ (verbe)''' : gérer un lupanar.<br> '''πορνοδιάκονος, -όνου (nom commun) (m/f)''' : .<br> '''πορνοδιδάσκαλος, -άλου (nom commun) (m) ''' : .<br> '''πορνοδύτης, -ου (nom commun) (m)''' .<br> '''πορνοφίλης, -ου (nom commun) (m)''' : amateur de prostituées.<br> '''πορνογενής, -ής, -ές (adjectif)''' : .<br> '''πορνογέννητος, -ος, -ον (adjectif)''' : né dans un lupanar.<br> '''πορνογράφος, -ου (nom commun) (m)''' : pornographe.<br> '''πορνοκοπέω (verbe)''' : .<br> '''πορνοκοπία, -ας (nom commun) (f)''' .<br> '''πορνοκόπος, -ου (nom commun) (m)''' : client de lupanar.<br> '''πορνομανής, -ής, -ές''' : furieux contre la prostitution.<br> '''πόρνος, -ου (nom commun) (m)''' : Prostitué ; gigolo.<br> '''πόρπη, -ης (nom commun) (f)''' : broche (bijou).<br> '''πόρ, -δός (nom commun) (m)''' : Forme laconienne de ''πούς''.<br> '''πόρρω (adverbe)''' : Forme attique de ''πρόσω''.<br> '''πορφύρεος, -α, -ον (adjectif)''' : (chez Homère) Sombre. (grec post-homérique) Pourpre.<br> '''πορφύρω (verbe)''' : Bouillir, fulminer ; rougir.<br> '''πόσις, -εως (nom commun) (f)''' : action de boire.<br> '''πόσις, -ιος (nom commun) (m)''' : époux ; mari.<br> '''πόσσις, -ιος (nom commun) (m)''' : Forme poétique de ''πόσις''. (au sens d’« époux », « mari »)<br> '''πόσος, -η, -ον (adjectif interrogatif)''' : combien.<br> '''ποσότης, -τος (nom commun) (f)''' : quantité.<br> '''πός, -δός (nom commun) (m)''' : Forme dorienne de ''πούς''.<br> '''ποταμός, -οῦ (nom commun) (m)''' : fleuve.<br> '''πότε (adverbe interrogatif)''' : quand.<br> '''ποτέ (adverbe)''' (Devient ''ποτ᾽'' devant un mot commençant par une voyelle à esprit doux, et ''ποθ᾽'' devant un mot commençant par une voyelle à esprit rude.) : jamais.<br> '''ποτήριον, -ίου (nom commun) (n)''' : coupe. (récipient)<br> '''ποτήρ, -ῆρος (nom commun) (m)''' : verre. (récipient)<br> '''πότμος, -ου (nom commun) (m)''' : destin ; sort.<br> '''πότνια, -ίης (nom commun) (f)''' : épouse ; maîtresse.<br> '''πούς, -δός (nom commun) (m)''' : pied.<br> '''ποῦ (adverbe interrogatif)''' : où (sans mouvement) ; comment.<br> '''πρᾶγμα, -άγματος (nom commun) (n)''' : Chose, évènement ; affaire. Fait.<br> '''πραγματικός, -ή, -όν (adjectif)''' : évènementiel ; factuel.<br> '''πραγματικῶς (adverbe)''' : évènementiellement ; factuellement.<br> '''πραγματικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''πραγματικός''.<br> '''πραγματικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''πραγματικός''.<br> '''πραικόκιον, -ίου (nom commun) (n)''' : abricot.<br> '''πράκτωρ, -ορος (nom commun) (m)''' : agent.<br> '''πρᾶξις, -άξεως (nom commun) (f)''' : action.<br> '''πραπίς, -δος (nom commun) (f)''' : intelligence.<br> '''πράσινος, -ίνη, -άσινον (adjectif)''' : vert poireau.<br> '''πράσσω (verbe)''' : faire, pratiquer.<br> '''πρατήρ, -ῆρος (nom commun) (m)''' : vendeur.<br> '''πρᾶτος, -άτη, -ᾶτον (adjectif)''' : Forme dorienne de ''πρῶτος''.<br> '''πράττω (verbe)''' : Forme attique de ''πράσσω''.<br> '''πρέπω (verbe)''' : .<br> '''πρέσϐυς, -έως (nom commun) (m)''' : Envoyé ; député ; ambassadeur.<br> '''πρεσϐυτέριον, -ίου (nom commun) (n)''' : assemblée des anciens.<br> '''πρῆγμα, -ήγματος (nom commun) (f)''' : Forme ionienne de ''πρᾶγμα''.<br> '''πρηκτήρ, -ός (nom commun) (m)''' : Forme homérique et ionienne de ''πράκτωρ''.<br> '''πρῆξις, -ήξεως (nom commun) (f)''' : Forme homérique et ionienne de ''πρᾶξις''.<br> '''πρήσσω (verbe)''' : Forme homérique et ionienne de ''πράσσω''.<br> '''πρῆχμα, -ήχματος (nom commun) (f)''' : Autre forme ionienne de ''πρᾶγμα''.<br> '''πρῖγκιψ, -ίγκιπος (nom commun) (m)''' : prince. (chef d’une principauté)<br> '''πριγκιπίσσα, -ας (nom commun) (f)''' : princesse. (cheffe d’une principauté)<br> '''πρίν (conjonction)''' : avant que.<br> '''πριόνιον, -ίου (nom commun) (n)''' : diminutif de ''πρίων''.<br> '''πρίων, -ονος (nom commun) (m)''' : scie.<br> '''προάστειος, -, - (adjectif)''' : suburbain.<br> '''προάστειον, -ίου (nom commun) (n)''' : banlieue.<br> '''προϐαίνω (verbe)''' : marcher en avant.<br> '''προϐατίνα, -ας (nom commun) (f)''' : brebis.<br> '''πρόϐατον, -άτου (nom commun) (n)''' : mouton.<br> '''πρόϐλημα, -ήματος (nom commun) (n)''' : problème.<br> '''πρόγνωσις, -ώσεως (nom commun) (f)''' : .<br> '''πρόγονος, -όνου (nom commun) (m)''' : ancêtre.<br> '''προπάτωρ, -ορος (nom commun) (m)''' : ancêtre.<br> '''πρόγραμμα, -άμματος (nom commun) (n)''' : notice écrite publique.<br> '''προγράφω (verbe)''' : écrire une notice publique.<br> '''προδίδωμι (verbe)''' : trahir.<br> '''προδότης, -ου (nom commun) (m)''' : traître.<br> '''προδοτικός, -ή, -όν (adjectif)''' : traître.<br> '''προδοσία, -ας (nom commun) (f)''' : trahison.<br> '''προοίμιον, -ίου (nom commun) (n)''' : prélude.<br> '''προκινῶ (verbe)''' : .<br> '''πρόκοιτος, -ίτου (nom commun) (m)''' : chambellan.<br> '''προλαμϐάνω (verbe)''' : prévoir.<br> '''πρόληψις, -ήψεως (nom commun) (f)''' : prévention.<br> '''πρόλογος, -όγου (nom commun) (m)''' : préface.<br> '''προσϐάλλω (verbe)''' : .<br> '''προσϐολή, -ῆς (nom commun) (f)''' : .<br> '''προσευχή, -ῆς (nom commun) (f)''' : prière.<br> '''προσεύχομαι (verbe)''' : Adresser une prière. (Absolu) Adorer, prier, supplier.<br> '''προσήλωσις, -ώσεως (nom commun) (f)''' : attachemeent.<br> '''πρόσθεν (adverbe)''' Devant ; en avant.<br> '''προσιτός, -ή, -όν (adjectif)''' : abordable.<br> '''πρόσειμι (verbe)''' : aborder.<br> '''προσθιγγάνω (verbe)''' : .<br> '''προσκέφαλον, -άλου (nom commun) (m)''' : oreiller.<br> '''πρόσκοπος, -όπου (nom commun) (m)''' : éclaireur.<br> '''πρόσκοπευω (verbe)''' : .<br> '''προσποιῶ (verbe)''' : .<br> '''προσωποποιία, -ας (nom commun) (f)''' : personnification.<br> '''πρόσω (adverbe)''' : .<br> '''πρός (adverbe ; préposition)''' : Auprès, à côté ; en outre.<br> '''πρότατος, -άτα, -άτετον (adjectif)''' : Superlatif de ''πρῶτος''.<br> '''πρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''πρῶτος''.<br> '''προτί (adverbe ; préposition)''' : Forme homérique de ''πρός''.<br> '''ποτί (adverbe ; préposition)''' : Forme homérique et dorienne de ''πρός''.<br> '''ποί (adverbe ; préposition)''' : Forme dorienne de ''πρός''.<br> '''πορτί (adverbe ; préposition)''' : Forme crétoise de ''πρός''.<br> '''πός (adverbe ; préposition)''' : Forme arcado-chypriote de ''πρός''.<br> '''πρές (adverbe ; préposition)''' : Forme éolienne de ''πρός''.<br> '''πέρτι (adverbe ; préposition)''' : Forme pamphylienne de ''πρός''.<br> '''πρᾶος, -ος, -ᾷον (adjectif)''' : doux ; calmant.<br> '''πραότης, -τος (nom commun) (f)''' : Douceur, bonté ; facilité de caractère.<br> '''πραύς, -εῖα, -ύ (adjectif)''' : Variante de ''πρᾶος''.<br> '''πραΰς, -εΐα, -ΰ (adjectif)''' : Forme poétique de ''πρᾶος''.<br> '''πρήξιμον, -ίματος (nom commun) (n)''' : Enflure, gonflement ; ballonnement, boursouflure, fluxion.<br> '''πρῖγκιψ, -ίγκιπος (nom commun) (m)''' : prince (chef d’une principauté).<br> '''πριγκίπισσα, -ας (nom commun) (f)''' : princesse (cheffe d’une principauté).<br> '''πρό (adverbe ; préposition)''' devant.<br> '''προ- (préfixe)''' pré-.<br> '''παράρτημα, -ήματος (nom commun) (n)''' : annexe.<br> '''προζύμιον, -ίου (nom commun) (n)''' : .<br> '''προζυμίτης, -ου (nom commun) (m)''' : .<br> '''πρόσθεσις, -έσεως (nom commun) (f)''' : addition.<br> '''προσφορά, -ᾶς (nom commun) (f)''' : offre.<br> '''προσωπεῖον, -ίου (nom commun) (n)''' : masque.<br> '''προσωπίς, -δος (nom commun) (f)''' : masque.<br> '''προσ- (préfixe)''' : Vers, à ; Auprès. En outre, encore. Excessivement ; tout à fait.<br> '''προσαρτῶ (verbe)''' : annexer.<br> '''προστίθημι (verbe)''' : additionner ; ajouter.<br> '''προσομοίωσις, -ώσεως (nom commun) (f)''' : simulation.<br> '''προσποιῶ (verbe)''' : simuler.<br> '''πρότανις, -άνεως (nom commun) (m)''' : Forme éolienne de ''πρύτανις''.<br> '''προῦμνον, -ύμνου (nom commun) (n)''' : prune.<br> '''προφατεία, -ας (nom commun) (f)''' : Forme dorienne de ''προφητεία''.<br> '''προφάτης, -ου (nom commun) (m)''' : Forme dorienne de ''προφήτης''.<br> '''προφητεία, -ας (nom commun) (f)''' : prophétie.<br> '''προφήτης, -ου (nom commun) (m)''' : prophète.<br> '''προφυλακτικός, -ή, -όν (adjectif)''' : .<br> '''προφυλάξις, -εως (nom commun) (f)''' : .<br> '''προφυλάσσω (verbe)''' : .<br> '''πρύμνα, -ας (nom commun) (f)''' : poupe.<br> '''πρύμνη, -ης (nom commun) (f)''' : Forme ionienne de ''πρύμνα''.<br> '''πρυτανεῖον, -ίου (nom commun) (n)''' : (À Athènes) mairie.<br> '''πρύτανις, -άνεως (nom commun) (m)''' : prytane.<br> '''πρωΐ (adverbe)''' : tôt.<br> '''πρῴ (adverbe)''' : Forme attique de ''πρωΐ''.<br> '''πρωκτός, -οῦ (nom commun) (m)''' : anus.<br> '''πρωκτόσοφος, -όφου (nom commun) (m/f)''' : Expert en débauche contre nature.<br> '''πρῷρα, -ῴρας (nom commun) (f)''' : proue.<br> '''πρωταγωνιστής, -οῦ (nom commun) (m)''' : protagoniste.<br> '''πρῶτος, -ώτη, -ῶτον (adjectif)''' : premier.<br> '''πρωτόκολλον, -όλλου (nom commun) (n)''' : frontispice.<br> '''πτελέα, -ας (nom commun) (f)''' : orme.<br> '''πτέρινος, -ίνη, -ινον (adjectif)''' : .<br> '''πτέρις, -δος (nom commun) (f)''' : fougère.<br> '''πτερόεις, -εσσα, -εν (adjectif)''' : ailé.<br> '''πτερόν, -οῦ (nom commun) (n)''' : aile.<br> '''πτέρνα, -ης (nom commun) (f)''' : talon. (partie postérieure du pied)<br> '''πτέρυξ, -υγος (nom commun) (f)''' : Aile ; nageoire.<br> '''πτηνόν, -οῦ (nom commun) (n)''' : oiseau.<br> '''πτηνοπέδιλος, -ίλου (nom commun) (m)''' : talaria.<br> '''πτισάνη, -ης (nom commun) (f)''' : tisane.<br> '''πτίσσω (verbe)''' : .<br> '''πτίττω (verbe)''' : Forme attique de ''πτίσσω''.<br> '''πτόλεμος, -έμου (nom commun) (m)''' : Forme homérique de ''πόλεμος''.<br> '''πτολίεθρον, -έθρου (nom commun) (n)''' : citadelle.<br> '''πτόλις, -εως (nom commun) (f)''' : Forme homérique de ''πόλις''.<br> '''πτύον, -ου (nom commun) (n)''' : pelle.<br> '''πτύω (verbe)''' : cracher.<br> '''πτῶσις, -ώσεως (nom commun) (f)''' : chute.<br> '''πτώσσω (verbe)''' : chuter.<br> '''πτωχεία, -ας (nom commun) (f)''' : pauvre.<br> '''πτωχεῖον, -ίου (nom commun) (n)''' : hospice.<br> '''πτώχευσις, -ύσεως (nom commun) (f)''' : banqueroute.<br> '''πτωχεύω (verbe)''' : faire banqueroute.<br> '''πτωχός, -ή, -όν (adjectif)''' : pauvre.<br> '''πτωχοτροφεῖον, -ίου (nom commun) (n)''' : hospice.<br> '''πτωχοτρόφος, -ου (nom commun) (m)''' : ptôchotrophe.<br> '''πτωχότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''πτωχός''.<br> '''πτωχότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''πτωχός''.<br> '''πτωχῶς (adverbe)''' : pauvrement.<br> '''πυγή, -ῆς (nom commun) (f)''' : fesse.<br> '''πυγηφαvοῦς, -οῦ (nom commun) (m)''' : mooning. (Action de montrer ses fesses nues en baissant son pantalon et en se penchant en avant.)<br> '''πυγίδιον, -ίου (nom commun) (n)''' : croupion.<br> '''πυγίζω (verbe)''' : sodomiser.<br> '''πυγμαῖος, -ία -ῖον (adjectif)''' : pygmée.<br> '''πυγμή, -ῆς (nom commun) (f)''' : poing.<br> '''πύελος, -έλου (nom commun) (f)''' : bassin (os).<br> '''πυθμήν, -ένος (nom commun) (m)''' : fond.<br> '''πυκνός, -ή, -όν (adjectif)''' : dense, sagace.<br> '''πυκνότατα, -, - (adverbe)''' : Superlatif de ''πυκνῶς''.<br> '''πυκνότερον, -, - (adverbe)''' : Comparatif de ''πυκνῶς''.<br> '''πυκνότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''πυκνός''.<br> '''πυκνότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''πυκνός''.<br> '''πυκνότης, -τος (nom commun) (f)''' : densité ; sagacité.<br> '''πυκνῶς (adverbe)''' : densément ; sagacement.<br> '''πύλη, -ης (nom commun) (f)''' : (Au singulier) battant de porte. (Au pluriel) porte.<br> '''πυλωρός, -οῦ (nom commun) (m)''' : Portier. (Anatomie) pylore.<br> '''πύνδαξ, -κος (nom commun) (m)''' : fond.<br> '''πυνθάνομαι (verbe)''' : chercher à savoir ; s’enquérir ; s’informer de ; apprendre en s’informant ; apprendre<br> '''πυξίς, -δος (nom commun) (f)''' : pyxide.<br> '''πύον, -ου (nom commun) (n)''' : ‎pus.<br> '''πυραμίς, -δος (nom commun) (f)''' : pyramide.<br> '''πυργίτης, -ου (nom commun) (m)''' : moineau.<br> '''πύργος, -ου (nom commun) (m)''' : Tour. (Par extension) Enceinte garnie de tours. (Par extension) Citadelle, remparts. (Par analogie) Sorte de bataillon carré.<br> '''πύρινος, -η, -ον (adjectif)''' : enflammé.<br> '''πυρινότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''πύρινος''.<br> '''πυρινότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''πύρινος''.<br> '''πύρινως (adverbe)''' : .<br> '''πῦρ, -ός (nom commun) (n)''' : feu.<br> '''πυρρός, -ά, -όν (adjectif)''' : .<br> '''πυρρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''πυρρός''.<br> '''πυρρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''πυρρός''.<br> '''πυρρῶς (adverbe)''' : .<br> '''πύσμα, -τος (nom commun) (n)''' : question ouverte.<br> '''πύστις, -εως (nom commun) (f)''' : Enquête, question. Apprentissage, chose apprise.<br> '''πυστός, -ή, -όν (adjectif)''' : .<br> '''πωγώνιον, -ίου (nom commun) (m)''' : menton.<br> '''πώγων, -ονος (nom commun) (m)''' : Barbe ; barbe d’animal, de plante. Barbelure. Langue de feu.<br> '''πωλέω (verbe)''' : vendre.<br> '''πώλης, -ου (nom commun) (m)''' : vendeur.<br> '''πωλητής, -οῦ (nom commun) (m)''' : vendeur.<br> '''πῶμα, -ώματος (nom commun) (n)''' : bouchon.<br> '''πῶυ, -ώεος (nom commun) (n)''' : Troupeau d’ovins ou de chèvres.<br> '''πῶς (adverbe)''' : comment.<br> '''Παιάν, -ᾶνος (nom commun) (m)''' : péan. (nom propre) : Péan.<br> '''Πακτωλός, -οῦ (nom propre) (m)''' : Pactole.<br> '''Παλαιὰ Διαθήκη (locution nominale) (f)''' : Ancien Testament.<br> '''Παλλάδιον, -ίου (nom propre) (n)''' : Palladium.<br> '''Πάλλας, -αντος (nom propre) (m)''' : Pallas (nom masculin).<br> '''Παλλάς, -δος (nom propre) (f)''' : Pallas (nom féminin).<br> '''Πάλμυρα, -ύρας (nom propre) (f)''' : Palmyre.<br> '''Πάμφιλος, -ίλου (nom propre) (m)''' : Pamphile.<br> '''Πανάκεια, -ας (nom propre) (f)''' : [[wikt:Panacée|Panacée]].<br> '''Πανδώρα, -ας (nom propre) (f)''' : [[wikt:Pandore|Pandore]].<br> '''Πάν, -ός (nom propre) (m)''' : [[wikt:Pan|Pan]].<br> '''Πανοῦργος, -ύργου (nom propre) (m)''' : Panurge.<br> '''Πάνθειον, -ίου (nom propre) (m)''' : Panthéon.<br> '''Παρθένος, -ου (nom propre) (f)''' : Vierge.<br> '''Παρθενών, -ῶνος (nom commun) (m)''' : Parthénon.<br> '''Παρθία, -ας (nom propre) (f)''' : Parthie.<br> '''Πάρθος, -ου (nom commun) (m)''' : Parthe.<br> '''Πάρις, -δος (nom propre) (m)''' : Pâris.<br> '''Παρμενίδης, -ου (nom propre) (m)''' : Parménide.<br> '''Πασιφάη, -ης (nom propre) (f)''' : Pasiphaé.<br> '''Παῦλος, -ύλου (nom propre) (m)''' : Paul.<br> '''Παῦνι (nom propre) (m)''' : Payni.<br> '''Παυσανίας, -ου (nom propre) (m)''' : Pausanias.<br> '''Παχώμιος, -ίου (nom propre) (m)''' : Pacôme.<br> '''Παχών (nom propre) (m)''' : Pachon.<br> '''Πελοπόννησος, -ήσου (nom propre) (f)''' : Péloponnèse.<br> '''Πέλοψ, -πος (nom propre) (m)''' : Pélops.<br> '''Πεμφρηδώ, -οῦς (nom propre) (f)''' : Pemphrédo (une des Grées).<br> '''Πεντάτευχος, -ύχου (nom propre) (f)''' : Pentateuque.<br> '''Πέργαμον, -άμου (nom propre) (n)''' : Pergame.<br> '''Περίϐοια, -ίας (nom propre) (f)''' : Périboée.<br> '''Περικλῆς, -έους (nom propre) (m)''' : Périclès.<br> '''Περίλεως, -εω (nom propre) (m)''' : Périléos.<br> '''Περσέπολις, -όλεως (nom propre) (f)''' : Persépolis.<br> '''Περσεπολίτης, -ου (nom commun) (m)''' : Persépolitain.<br> '''Πέρσης, -ου (nom commun) (m)''' : Perse.<br> '''Περσίς, -δος (nom propre) (f)''' : Perse.<br> '''Περσίς, -δος (nom commun) (f)''' : Perse.<br> '''Πετεφρής, -οῦ (nom propre) (m)''' : Potiphar.<br> '''Πήγασος, -άσου (nom propre) (m)''' : Pégase.<br> '''Πηλεύς, -έως (nom propre) (m)''' : Pélée.<br> '''Πηνειός, -οῦ (nom propre) (m)''' : Pénée.<br> '''Πηνελόπη, -ης (nom propre) (f)''' : Pénélope.<br> '''Πίστις, -εως (nom propre) (f)''' : Pistis.<br> '''Πιτθεύς, -έως (nom propre) (m)''' : Pitthée. (Grand-père de Thésée.)<br> '''Πλάτων, -ωνος (nom propre) (m)''' : Platon.<br> '''Πλευρών, -ῶνος (nom propre) (m/f)''' : Pleuron.<br> '''Πλούταρχος, -άρχου (nom propre) (m)''' : Plutarque.<br> '''Πλουτεύς, -έως (nom propre) (m)''' : Autre nom de Pluton.<br> '''Πλουτίς, -δος (nom propre) (f)''' : Ploutis.<br> '''Πλοῦτος, -ύτου (nom propre) (m)''' : [[wikt:Ploutos|Ploutos]].<br> '''Πλούτων, -ωνος (nom propre) (m)''' : [[wikt:Pluton|Pluton]].<br> '''Πόθος, - (nom propre) (m)''' : [[wikt:Pothos|Pothos]].<br> '''Ποικίλη, -ης (nom propre) (f)''' : Pœcile. (portique au nord de l’Agora d’Athènes.)<br> '''Πολύϐιος, -ίου (nom propre) (m)''' : Polybe.<br> '''Πολυμνία, -ας (nom propre) (f)''' : Polymnie.<br> '''Πολύαινος, -ίνου (nom propre) (m)''' : Polyen.<br> '''Πολυνείκης, -ους (nom propre) (m)''' : Polynice.<br> '''Πολυπήμων, -ονος (nom propre) (m)''' : Polypémon (véritable nom de Procuste).<br> '''Πολύφημος, -ήμου (nom propre) (m)''' : Polyphème.<br> '''Πομπηία, -ας (nom propre) (f)''' : Pompéi.<br> '''Πομπήϊος, -ΐου (nom propre) (m)''' : Pompée.<br> '''Ποσειδώνιος, - (nom propre) (m)''' : Posidonios (Philosophe grec stoïcien né à Apamée en 135 av. J.-C. et mort à Rome en 51 av. J.-C. .).<br> '''Ποσειδάν, - (nom propre) (m)''' : Forme dorienne de ''Ποσειδῶν''.<br> '''Ποσειδάων, - (nom propre) (m)''' : Forme homérique de ''Ποσειδῶν''.<br> '''Ποσειδέων, - (nom propre) (m)''' : Forme ionienne de ''Ποσειδῶν''.<br> '''Ποσειδῶν, -ῶνος (nom propre) (m)''' : [[wikt:Poséidon|Poséidon]].<br> '''Ποτειδάν, - (nom propre) (m)''' : Autre forme dorienne de ''Ποσειδῶν''.<br> '''Ποτείδαν, - (nom propre) (m)''' : Forme éolienne de ''Ποσειδῶν''.<br> '''Ποτειδᾶς, - (nom propre) (m)''' : Forme de ''Ποσειδῶν''.<br> '''Ποτειδάων, - (nom propre) (m)''' : Forme crétoise et béotienne de ''Ποσειδῶν''.<br> '''Πραξιτέλης, -ους (nom propre) (m)''' : Praxitèle.<br> '''Πρίαμος, -άμου (nom propre) (m)''' : Priam.<br> '''Πρόκνη, -ης (nom propre) (f)''' : Procné.<br> '''Προκρούστης, -ου (nom propre) (m)''' : Procuste (surnom de Polypémon.).<br> '''Προκύων, -ός (nom propre) (m)''' : Procyon.<br> '''Προμηθεύς, -έως (nom propre) (m)''' : Prométhée.<br> '''Προξένος, -ρου (nom propre) (m)''' : Proxenos.<br> '''Προυσίας, -ου (nom propre) (m)''' : Prusias.<br> '''Πρωταγόρας, -ου (nom propre) (m)''' : Protagoras.<br> '''Πυγμαλίων, -ωνος (nom propre) (m)''' : Pygamlion.<br> '''Πυθαγόρας, -ου (nom propre) (m)''' : Pythagore.<br> '''Πυθόπολις, -όλεως (nom propre) (f)''' : Antioche du Méandre.<br> '''Πύθων, -ωνος (nom propre) (m)''' : Python.<br> '''Πυθώ, -οῦς (nom propre) (f)''' : Ancien nom de Delphes.<br> '''Πυλάδας, -ου (nom propre) (m)''' : Forme dorienne de ''Πυλάδης''.<br> '''Πυλάδης, -ου (nom propre) (m)''' : Pylade.<br> '''Πύραμος, -άμου (nom propre) (m)''' : Pyrame.<br> '''Πυρετός, -οῦ (nom propre) (m)''' : (fleuve d’Europe de l’Est).<br> '''Πυργοπολυνείκης, -ους (nom propre) (m)''' : Pyrgopolinice.<br> '''Πύργος, -ου (nom propre) (m)''' : Pyrgos.<br> '''Πύρρα, -ας (nom propre) (f)''' : Pyrrha.<br> '''Πύρρος, -ου (nom propre) (m)''' : Pyrrhus.<br> '''Πύρρων, -ωνος (nom propre) (m)''' : Pyrrhon.<br> '''Πῶλος, -ώλου (nom propre) (m)''' : Polos.<br> ==Ρ== '''ῥᾶ (nom commun) (n)''' : rhubarbe.<br> '''ῥαϐϐί (nom commun) (m)''' : rabbin.<br> '''ῥαϐδομαντεία, -ας (nom commun) (f)''' : Divination pratiquée grâce à une baguette.<br> '''ῥαϐδονόμος, -ου (nom commun) (m)''' : licteur.<br> '''ῥαϐδοῦχος, -ύχου (nom commun) (m)''' : licteur.<br> '''ῥάϐδος, -ου (nom commun) (f)''' : baguette.<br> '''ῥαγάς, -δος (nom commun) (f)''' : .<br> '''ῥαιϐηδόν, -οῦ (nom commun) (n)''' .<br> '''ῥαιϐοειδής, -ής, -ές (adjectif) ''' .<br> '''ῥαιϐόκρανος, -άνου (nom commun) (m)''' .<br> '''ῥαιϐοσκελής, -ής, -ές (adjectif) ''' .<br> '''ῥαιϐός, -ή, -όν (adjectif)''' : tendu.<br> '''ῥαιϐότης, -τος (nom commun) (f)''' .<br> '''ῥαιϐῶς (adverbe)''' : de façon tendue.<br> '''ῥαιϐῶ (verbe)''' tendre.<br> '''ῥαδινός, -ή -όν (adjectif)''' : souple.<br> '''ῥᾴδιος, -α, -ον (adjectif)''' : facile.<br> '''ῥᾳδίως (adverbe)''' : facilement.<br> '''ῥᾷστος, -, - (adjectif)''' : Superlatif de ''ῥᾴδιος''.<br> '''ῥᾴων, -, - (adjectif)''' : Comparatif de ''ῥᾴδιος''.<br> '''ῥάμνος, -ου (nom commun) (f)''' nerprun épineux.<br> '''ῥάμφος, -ους (nom commun) (n)''' : bec (d’un oiseau).<br> '''ῥάξ, -γός (nom commun) (m)''' : téton.<br> '''ῥάπισμα, -ίσματος (nom commun) (n)''' : gifle.<br> '''ῥαπίς, -δος (nom commun) (f)''' : verge ; bâton.<br> '''ῥάπτης, -ου (nom commun) (n)''' : tailleur (de vêtements).<br> '''ῥαπτός, -ή, -όν (adjectif)''' : cousu.<br> '''ῥάπτω (verbe)''' : coudre.<br> '''ῥάπυς, -ος (f)''' : navet.<br> '''ῥάσσω (verbe)''' : .<br> '''ῥάττω (verbe)''' : Forme attique de ''ῥάσσω''.<br> '''ῥαφανιδῶ (verbe)''' : .<br> '''ῥαφανίδωσις, -ώσεως (nom commun) (f)''' : .<br> '''ῥαφανός, -οῦ (nom commun) (m)''' : radis.<br> '''ῥαφεύς, -έως (nom commun) (m)''' : couturier.<br> '''ῥαφή, -ῆς (nom commun) (f)''' : couture.<br> '''ῥαφίς, -δος (nom commun) (f)''' : Aiguille, poinçon. Aiguille (poisson de mer).<br> '''ῥάφυς, -ος (nom commun) (f)''' : Variante de ''ῥάπυς''.<br> '''ῥαχίζω (verbe)''' : .<br> '''ῥάχις, -εως (nom commun) (f)''' : épine dorsale.<br> '''ῥαχιστής, -οῦ (nom commun) (m)''' : .<br> '''ῥαχιστός, -ός, -όν (adjectif)''' : .<br> '''ῥαχίτης, -ης, -ες, (adjectif)''' : .<br> '''ῥαχός, -ή, -όν, (adjectif)''' : superficiel.<br> '''ῥαχός, -οῦ (nom commun) (m)''' : .<br> '''ῥάψις, -εως (nom commun) (f)''' : .<br> '''ῥαψῳδία, -ας (nom commun) (f)''' : récitation d’un poème épique.<br> '''ῥαψῳδός, -οῦ (nom commun) (m)''' : barde.<br> '''ῥέδδω (verbe)''' : Forme béotienne et dorienne de ''ῥέζω''.<br> '''ῥέζω (verbe)''' : Travailler, faire, exécuter.<br> '''ῥέπω (verbe)''' : incliner.<br> '''ῥεῦμα, -ύματος (nom commun) (n)''' : rhume.<br> '''ῥευματίζομαι (verbe)''' : souffrir de rhumatismes.<br> '''ῥευματισμός, -οῦ (nom commun) (m)''' : rhumatisme.<br> '''ῥευστός, -ή -όν (adjectif)''' : liquide.<br> '''ῥέω (verbe)''' : couler.<br> '''ῥῆγμα, -ήγματος (nom commun) (n)''' : .<br> '''ῥήγνυμι (verbe)''' : .<br> '''ῥῆμα, -ήματος (nom commun) (n)''' : verbe.<br> '''ῥῆξις, -ήξεως (nom commun) (f)''' : déchirure.<br> '''ῥῆον, -ήου (nom commun) (n)''' : rhubarbe.<br> '''ῥῆσις, -ήσεως (nom commun) (f)''' : citation.<br> '''ῥήσσω (verbe)''' : Forme ionienne de ''ῥάσσω''.<br> '''ῥητορικός, -ή, -όν (adjectif)''' : oratoire.<br> '''ῥητορικῶς (adverbe)''' : oratoirement.<br> '''ῥητορικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ῥητορικός''.<br> '''ῥητορικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ῥητορικός''.<br> '''ῥητορικώτατα, -, - (adverbe)''' : Superlatif de ''-ικῶς''.<br> '''ῥητορικώτερον, -, - (adverbe)''' : Comparatif de ''-ικῶς''.<br> '''ῥητός, -ή, -όν (adjectif)''' : Dit ; dicible, (Mathématiques) rationnel.<br> '''ῥήτρα, -ας (nom commun) (f)''' : clause.<br> '''ῥήτωρ, -ορος (nom commun) (m/f)''' : orateur.<br> '''ῥηχός, -ή -όν (adjectif)''' : Forme ionienne de ''ῥαχός''.<br> '''ῥῖγος, -ίγους (nom commun) (n)''' : frisson.<br> '''ῥιγῶ (verbe)''' : frissonner.<br> '''ῥίζα, -ης (nom commun) (f)''' : racine.<br> '''ῥινόκερως, -έρωτος (nom commun) (m)''' : rhinocéros.<br> '''ῥίον, -ου (nom commun) (n)''' : sommet.<br> '''ῥιπή, -ῆς (nom commun) (f)''' : .<br> '''ῥίπτω (verbe)''' : lancer, jeter ; projet.<br> '''ῥίς, -νός (nom commun) (f)''' : nez.<br> '''ῥίψασπις, -δος (nom commun) (f)''' : .<br> '''ῥίψις, -πός (nom commun) (f)''' : entrelac.<br> '''ῥιπίζω (verbe)''' : éventer.<br> '''ῥιπίς, -δος (nom commun) (f)''' : éventail.<br> '''ῥοά, -ᾶς (nom commun) (f)''' : Forme dorienne de ''ῥοή''.<br> '''ῥοή, -ῆς (nom commun) (f)''' : écoulement.<br> '''ῥοδόεις, -εσσα, -εν (adjectif)''' : rosé.<br> '''ῥοδοέντως (adverbe)''' : .<br> '''ῥοδοέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''ῥοδόεις''.<br> '''ῥοδοέστερος, -έρα, -ερον (adjectif)''' : Comparatif de ''ῥοδόεις''.<br> '''ῥόδον, -ου (nom commun) (n)''' : rose (fleur).<br> '''ϝρόδον, -ου (nom commun) (n)''' : Forme éolienne de ''ῥόδον''.<br> '''ῥοιά, -ᾶς (nom commun) (f)''' : grenade (fruit).<br> '''ῥόκα, -ας (nom commun) (f)''' : roquette (plante).<br> '''ῥόμος, -ου (nom commun) (m)''' : ver.<br> '''ῥομφαία, -ας (nom commun) (f)''' : estramaçon.<br> '''ῥόπαλον, -άλου (nom commun) (n)''' : gourdin.<br> '''ῥοφῶ (verbe)''' : sucer.<br> '''ῥύαξ, -κος (nom commun) (n)''' : ruisseau.<br> '''ῥύγχος, -ους (nom commun) (n)''' : Trompe, museau. Bec d’un oiseau.<br> '''ῥυθμός, -οῦ (nom commun) (m)''' : mouvement régulier.<br> '''ῥύμη, -ης (nom commun) (f)''' : rue.<br> '''ῥυπαίνω (verbe)''' : polluer.<br> '''ῥύπανσις, -άνσεως (nom commun) (f)''' : pollution.<br> '''ῥυπαρός, -ά, -όν (adjectif)''' : crasseux.<br> '''ῥυπαρῶς (adverbe)''' : crasseusement.<br> '''ῥυπαρώτατα, -, - (adverbe)''' : Superlatif de ''ῥυπαρῶς''.<br> '''ῥυπαρώτερον, -, - (adverbe)''' : Comparatif de ''ῥυπαρῶς''.<br> '''ῥυπαρώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ῥυπαρός''.<br> '''ῥυπαρώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ῥυπαρός''.<br> '''ῥύπος, -ου (nom commun) (m)''' : polluant.<br> '''ῥυσμός, -οῦ (nom commun) (m)''' : Forme ionienne de ''ῥυθμός''.<br> '''ῥυτίς, -δος (nom commun) (f)''' : ride.<br> '''ῥωγμή, -ῆς (nom commun) (f)''' : fissure.<br> '''ῥώθων, -ος (nom commun) (m)''' : narine.<br> '''ῥωμαϊκός, -ή, -όν (adjectif)''' : romain.<br> '''ῥωμαϊκῶς (adverbe)''' : romainement.<br> '''ῥωμαϊκώτατα, -, - (adverbe)''' : Superlatif de ''ῥωμαϊκῶς''.<br> '''ῥωμαϊκώτερον, -, - (adverbe)''' : Comparatif de ''ῥωμαϊκῶς''.<br> '''ῥωμαϊκώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ῥωμαϊκός''.<br> '''ῥωμαϊκώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ῥωμαϊκός''.<br> '''ῥωμαλέος, -α, -ον (adjectif)''' : fort, robuste (en parlant des personnes) ; solide (en parlant des choses).<br> '''ῥωμαλεότης, -τος (nom commun) (f)''' : force, robustesse (en parlant des personnes) ; solidité (en parlant des choses).<br> '''ῥώμη, -ης (nom propre) (f)''' : force.<br> '''ῥώομαι (verbe)''' : se précipiter, fondre sur.<br> '''ῥωσικός, -ή, -όν (adjectif)''' : russe.<br> '''ῥώξ, -γός (nom commun) (m)''' : Forme ionienne de ''ῥάξ''.<br> '''ῥῶ (nom commun) (n)''' : rhô.<br> '''Ῥαάβ (nom propre) (f)''' : Rahab.<br> '''Ῥα (nom propre) (m)''' : Rê.<br> '''Ῥᾶ (nom propre) (n)''' : Volga.<br> '''Ῥαδάμανθυς, -άνθυος (nom propre) (m)''' : Rhadamanthe.<br> '''Ῥαθούρης, -ου (nom propre) (m)''' : Niouserrê.<br> '''Ῥαθωτις, -ίδος (nom propre) (m)''' : Toutânkhamon.<br> '''Ῥαμέσσης, -ου (nom propre) (m)''' : Ramsès.<br> '''Ῥαμνοῦς, -ντος (nom propre) (m)''' : Rhamnonte.<br> '''Ῥαφαήλ (nom propre) (m)''' : Raphaël.<br> '''Ῥεϐέκκα, -ας (nom propre) (f)''' : Rebecca.<br> '''Ῥῆνος, -ήνου (nom propre) (m)''' : Rhin.<br> '''Ῥίον, -ου (nom propre) (m)''' : Río (ville de Grèce).<br> '''Ῥοδανός, -οῦ (nom propre) (m)''' : Rhône.<br> '''Ῥόδη, -ης (nom propre) (f)''' : Rhodé.<br> '''Ῥόδιος, - (nom propre) (m)''' : Rhodien.<br> '''Ῥοδόπη, -ης (nom propre) (f)''' : Rhodope.<br> '''Ῥόδος, -ου (nom propre) (f)''' : Rhodes.<br> '''Ῥούθ (nom propre) (f)''' : Ruth.<br> '''Ῥοῦφος, -ύφου (nom propre) (m)''' : Rufus.<br> '''Ῥωμαῖος, -ίου (nom commun) (m)''' : Romain.<br> '''Ῥώμη, -ης (nom propre) (f)''' : Rome.<br> '''Ῥῶμος, -ώμου (nom propre) (m)''' : Rémus.<br> '''Ῥώμυλος, -ύλου (nom propre) (m)''' : Romulus.<br> '''Ῥωξάνη, -ης (nom propre) (f)''' : Roxane (Épouse d'Alexandre le Grand.)<br> '''Ῥωσία, -ας (nom propre) (f)''' : Russie.<br> '''Ῥωσίς, -δος (nom propre) (f)''' : Russe.<br> '''Ῥῶς, -ώσος (nom commun) (m)''' : Russe.<br> ==Σ== '''σάϐϐατον, -άτου (nom commun) (n)''' : shabbat.<br> '''σαϐϐατισμός, -οῦ (nom commun) (n)''' : sabbatisme.<br> '''σαδδουκαῖος, -ίου (nom commun) (m)''' : sadducéen.<br> '''σάγμα, -τος (nom commun) (n)''' : bât.<br> '''σάκκος, -ου (nom commun) (m)''' : sac.<br> '''σάκος, -ους (nom commun) (n)''' : bouclier.<br> '''σάκχαρις, -άρεως (nom commun) (f)''' : sucre.<br> '''σάλπιγξ, -γoς (nom commun) (f)''' : trompette.<br> '''σᾶμα, -άματος (nom commun) (n)''' : Forme dorienne de ''σῆμα''.<br> '''σάμερον (adverbe)''' : Forme dorienne de ''σήμερον''.<br> '''σάμιος, -ος, -ον (adjectif)''' : samosien.<br> '''σαμψήρα, -ας (nom commun) (f)''' : cimeterre.<br> '''σάνδαλον, -άλου (nom commun) (n)''' : sandale.<br> '''σανίς, -δος (nom commun) (f)''' : planche.<br> '''σαρδονικός, -ή, -όν (adjectif)''' : sarde.<br> '''σαρδονικότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''σαρδονικός''.<br> '''σαρδονικότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''σαρδονικός''.<br> '''σαρδονικότατα, -, - (adverbe)''' : Superlatif de ''σαρδονικῶς''.<br> '''σαρδονικότερον, -, - (adverbe)''' : Comparatif de ''σαρδονικῶς''.<br> '''σαρδονικῶς (adverbe)''' : sardoniquement.<br> '''σαρκικός, -ή, -όν (adjectif)''' : charnel.<br> '''σαρκικότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''σαρκικός''.<br> '''σαρκικότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''σαρκικός''.<br> '''σαρκικότατα, -, - (adverbe)''' : Superlatif de ''σαρκικῶς''.<br> '''σαρκικότερον, -, - (adverbe)''' : Comparatif de ''σαρκικῶς''.<br> '''σαρκικῶς (adverbe)''' : charnellement.<br> '''σάρκινος, -ίνη, -άρκινον (adjectif)''' : charnu.<br> '''σάρξ, -κός (nom commun) (f)''' : chair.<br> '''σατυρίασις, -άσεως (nom commun) (f)''' : satyriasis.<br> '''σατυρικός, -ή, -όν (adjectif)''' : satyrique.<br> '''σατύριον, -ίου (nom commun) (n)''' : satyrion.<br> '''σατυρίσκος, -ου (nom commun) (m)''' : satyreau.<br> '''σάτυρος, -ύρου (nom commun) (m)''' : satyre.<br> '''σατυρώδης, -ης, -ες (adjectif)''' : satyrode.<br> '''σαύρα, -ας (nom commun) (f)''' : lézard ; quéquette.<br> '''σαύρη, -ης (nom commun) (f)''' : Forme ionienne de ''σαύρα''.<br> '''σαυροματικός, -ή, -όν (adjectif)''' : sarmate.<br> '''σαυροματικῶς (adverbe)''' : .<br> '''σαυροματικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''σαυροματικός''.<br> '''σαυροματικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''σαυροματικός''.<br> '''σαῦρος, -ύρου (nom commun) (m)''' : lézard.<br> '''σάπφειρος, -ίρου (nom commun) (f)''' : saphir.<br> '''σαφέστερος, -άτη, -έστατον (adjectif)''' : Superlatif de ''σαφής''.<br> '''σαφέστατος, -έρα, -έσερον (adjectif)''' : Comparatif de ''σαφής''.<br> '''σαφής, -ής, -ές (adjectif)''' : Clair, évident ; manifeste.<br> '''σαφῶς (adverbe)''' : Clairement, évidemment ; manifestement.<br> '''σεϐάζω (verbe)''' : respecter.<br> '''σεϐασμός, -οῦ (nom commun) (m)''' : respect.<br> '''σεϐαστός, -ός, -όν (adjectif)''' : respectable ; respecté.<br> '''σέϐομαι (verbe)''' : Craindre les dieux. Vénérer.<br> '''σείριος, -ίου (nom commun) (m)''' : destructeur.<br> '''σελάνα, -ας (nom commun) (f)''' : Forme dorienne de ''σελήνη''.<br> '''σελάννα, -ας (nom commun) (f)''' : Forme éolienne de ''σελήνη''.<br> '''σέλας, -τος (nom commun) (n)''' : Éclat, lumière ; lueur brillante.<br> '''σελάχιον, -ίου (nom commun) (n)''' : raie (poisson).<br> '''σέλαχος, -άχους (nom commun) (n)''' : requin.<br> '''σελήνη, -ης (nom commun) (f)''' : lune.<br> '''σεληνιακός, -ή, -όν (adjectif)''' : lunaire.<br> '''σέλινον, -ίνου (nom commun) (n)''' : céleri.<br> '''σελίς, -δος (nom commun) (f)''' : page. (Face d'une feuille de papier, de parchemin, de vélin, servant à l'écriture.)<br> '''σεμίδαλις, -άλεως (nom commun) (f)''' : semoule.<br> '''σεμνός, -ή, -όν (adjectif)''' : modeste.<br> '''σεμνότατα, -, - (adverbe)''' : Superlatif de ''σεμνῶς''.<br> '''σεμνότερον, -, - (adverbe)''' : Comparatif de ''σεμνῶς''.<br> '''σεμνότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''σεμνός''.<br> '''σεμνότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''σεμνός''.<br> '''σεμνότης, -τος (nom commun) (f)''' : modestie.<br> '''σεμνῶς (adverbe)''' : modestement.<br> '''σῆμα, -ήματος (nom commun) (n)''' : signe.<br> '''σημαντικός -ή -όν (adjectif)''' : significatif.<br> '''σημαντικῶς (adverbe)''' : significativement.<br> '''σημαντικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''σημαντικός''.<br> '''σημαντικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''σημαντικός''.<br> '''σημαντικώτατα, -, - (adverbe)''' : Superlatif de ''σημαντικῶς''.<br> '''σημαντικώτερον, -, - (adverbe)''' : Comparatif de ''σημαντικῶς''.<br> '''σημεῖον, -ίου (nom commun) (n)''' : signal.<br> '''σήμερον (adverbe)''' : aujourd’hui.<br> '''σημύδα, -ης (nom commun) (f)''' : bouleau.<br> '''σῆραγξ, -ήραγγος (nom commun) (f)''' : tunnel.<br> '''σήσαμον, άμου (nom commun) (n)''' : sésame.<br> '''σής, -τός (nom commun) (m)''' : mite.<br> '''σητόδοκις, -εως (nom commun) (f)''' : papillon.<br> '''σῆψις, -ήψεως (nom commun) (f)''' : putréfaction.<br> '''σιαγών, -όνος (nom commun) (f)''' : mâchoire.<br> '''σιηγών, -όνος (nom commun) (f)''' : Forme ionienne de ''σιαγών''.<br> '''σῖγμα (nom commun) (n)''' : sigma.<br> '''σικάριος, -ίου (nom commun) (m)''' : assassin.<br> '''σικελικός, -ή, -όν (adjectif)''' : sicilien.<br> '''σικυός, -οῦ (nom commun) (m)''' : concombre.<br> '''σικυώνιος, -ος, -ον (adjectif)''' : .<br> '''σίλφιον, -ίου (nom commun) (n)''' : silphium.<br> '''σιμός, -ή, -όν (adjectif)''' : Camus ; montant.<br> '''σιμῶ (verbe)''' : lever le nez.<br> '''σίναπι, -άπεως (nom commun) (n)''' : moutarde (plante).<br> '''σιός, -οῦ (nom commun) (m)''' : Forme laconienne de ''θεός''.<br> '''σίσυς, -ος (nom commun) (m)''' : fourrure.<br> '''-σις, -εως (suffixe) (f)''' : Suffixe formant des noms d'action.<br> '''σῖτος, -ίτου (nom commun) (m)''' : Grain, à la fois le blé et l'orge. (Par extension) Toute nourriture végétale (par opposition à la viande ou la boisson). Pension alimentaire. (Droit athénien) Distribution de blé aux indigents.<br> '''σιωπή, -ῆς (nom commun) (f)''' : calme, silence.<br> '''σιωπηρός, -ός, -όν (adjectif)''' : silencieux, tacite.<br> '''σιωπηρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''σαρκικός''.<br> '''σιωπηρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''σαρκικός''.<br> '''σιωπηρότατα, -, - (adverbe)''' : Superlatif de ''σαρκικῶς''.<br> '''σιωπηρότερον, -, - (adverbe)''' : Comparatif de ''σαρκικῶς''.<br> '''σιωπηρῶς (adverbe)''' : tacitement.<br> '''σιωπηρότης, -τος (nom commun) (f)''' : tacité.<br> '''σιωπῶ (verbe)''' : se taire.<br> '''σκαιός, -ά, -όν (adjectif)''' : qui est à gauche.<br> '''σκάνδαλον, -άλου (nom commun) (n)''' : Piège placé sur le chemin.<br> '''σκανδάληθρον, -ήθρου (nom commun) (n)''' : .<br> '''σκανδαλίζω (verbe)''' : Placer un piège sur le chemin.<br> '''σκαπανεύς, -έως (nom commun) (m)''' : .<br> '''σκαπάνη, -ης (nom commun) (f)''' : .<br> '''σκᾶπτρον, -άπτρου (nom commun) (n)''' : Forme dorienne de ''σκῆπτρον''.<br> '''σκάπτω (verbe)''' : creuser.<br> '''σκεδάννυμι (verbe)''' : disperser, répandre.<br> '''σκέλος, -ους (nom commun) (n)''' : (Anatomie) Jambe de l’homme et des animaux. (Au pluriel) Les murs (entre Athènes et le Pirée, entre Mégare et Nisæa).<br> '''σκεπτικός, -ή, -όν (adjectif)''' : observateur.<br> '''σκεπτικῶς (adverbe)''' : sceptiquement.<br> '''σκεπτικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''σκεπτικός''.<br> '''σκεπτικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''σκεπτικός''.<br> '''σκέπτομαι (verbe)''' : Considérer ; examiner avec soin.<br> '''σκευαρίδιον, -ίου (nom commun) (n)''' : .<br> '''σκευάριον, -ίου (nom commun) (n)''' : .<br> '''σκευωρία, -ας (nom commun) (f)''' : machination.<br> '''σκεῦος, -ύους (nom commun) (n)''' : ustensile.<br> '''σκέψις, -εως (nom commun) (f)''' : pensée. (opération de l’intelligence.)<br> '''σκηπτός, -οῦ (nom commun) (m)''' : ouragan.<br> '''σκῆπτρον, -ήπτρου (nom commun) (n)''' : Étai, sceptre.<br> '''σκήπτω (verbe)''' : Étayer, soutenir. Brandir.<br> '''σκίουρος, -ύρου (nom commun) (m)''' : écureuil.<br> '''σκολιός, -ά, -όν (adjectif)''' : tordu.<br> '''σκολόπαξ, -άκος (nom commun) (m)''' : bécasse.<br> '''σκολόπενδρα, -ένδρας (nom commun) (f)''' : scolopendre.<br> '''σκολοπένδριον, -ίου (nom commun) (n)''' : Diminutif de ''σκολόπενδρα''.<br> '''σκόλοψ, -πος (nom commun) (m)''' : écharde.<br> '''σκόπελος, -έλου (nom commun) (m)''' : écueil.<br> '''σκοπῶ (verbe)''' : observer.<br> '''σκόροδον, -όδου (nom commun) (n)''' : ail.<br> '''σκορπιός, -οῦ (nom commun) (m)''' : scorpion.<br> '''σκοτεινός, -ή, -όν (adjectif)''' : obscur.<br> '''σκοτεινῶς (adverbe)''' : obscurément.<br> '''σκοτεινώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''σκοτεινός''.<br> '''σκοτεινώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''σκοτεινός''.<br> '''σκότιος, -ία, -ότιον (adjectif)''' : bâtard.<br> '''σκότος, -ου (nom commun) (m)''' : obscurité.<br> '''σκυθικός, -ή, -όν (adjectif)''' : scythe.<br> '''σκυθικῶς (adverbe)''' : .<br> '''σκυθικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''σκυθικός''.<br> '''σκυθικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''σκυθικός''.<br> '''σκύλαξ, -κος (nom commun) (m)''' : chiot.<br> '''σκυλεύω (verbe)''' : dépouiller.<br> '''σκύλλω (verbe)''' : Déchirer, troubler.<br> '''σκῦλον, -ύλου (nom commun) (n)''' : butin.<br> '''σκῦτος, -ύτου (nom commun) (m)''' : .<br> '''σκώληξ, -κος (nom commun) (m)''' : ver.<br> '''σκῶμμα, -ώμματος (nom commun) (n)''' : .<br> '''σκωραμίς, -δος (nom commun) (f)''' : pot de chambre.<br> '''σκωρία, -ας (nom commun) (f)''' : scorie.<br> '''σκῶρ, -ατός (nom commun) (n)''' : excrément.<br> '''σκώψ, -πός (nom commun) (m)''' : hibou.<br> '''σμάραγδος, -άγδου (nom commun) (f)''' : émeraude.<br> '''σμάω (verbe)''' : frotter, nettoyer.<br> '''σμῆγμα, -ήγματος (nom commun) (n)''' : savon, détergent ; onguent.<br> '''σμήχω (verbe)''' : essuyer.<br> '''σμῖλαξ, -ίλακος (nom commun) (f)''' : if.<br> '''σμίλη, -ης (nom commun) (f)''' : Ciseau. Bistouri, lancette.<br> '''σμύραινα, -ίνης (nom commun) (f)''' : murène.<br> '''σμῶδιξ, -ώδιγγος (nom commun) (f)''' : contusion.<br> '''σμώχω (verbe)''' : frotter.<br> '''σοϐαρός, -ή, -όν (adjectif)''' : Effrayant. Fuyant, rapide. Hautain, dédaigneux ; pompeux.<br> '''σοϐαρῶς (adverbe)''' : Effrayamment, rapidement. Hautainement, dédaigneusement ; pompeusement.<br> '''σοϐαρώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''σοϐαρός''.<br> '''σοϐαρώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''σοϐαρός''.<br> '''σοϐῶ (verbe)''' : Chasser, effrayer les oiseaux. Bouger rapidement.<br> '''σαπρός, -ή, -όν (adjectif)''' : Pourri, putride<br> '''σαπρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''σαπρός''.<br> '''σαπρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''σαπρός''.<br> '''σαπρῶς (adverbe)''' : putridement.<br> '''σός, -ή, -όν (adjectif possessif)''' : ton.<br> '''σοφία, -ας (nom commun) (f)''' : sagesse.<br> '''σοφίη, -ης (nom commun) (f)''' : Forme ionienne de ''σοφία''.<br> '''σοφός, -ή, -όν (adjectif)''' : Habile. (En parlant de l’intelligence ou du caractère) Prudent, sage. (En particulier) Initié à la sagesse. Ingénieux, fin, rusé.<br> '''σοφῶς (adverbe)''' : Habilement, sagement. Ingénieusement, finement.<br> '''σοφώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''σοφός''.<br> '''σοφώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''σοφός''.<br> '''σπαδωνισμός, -οῦ (nom commun) (m)''' : castration.<br> '''σπάδων, -ος (nom commun) (m)''' : castrat ; eunuque.<br> '''σπάθη, -ης (nom commun) (f)''' : épée.<br> '''σπαθίον, -ου (nom commun) (m)''' : Diminutif de ''σπάθη''.<br> '''σπανακόν, -οῦ (nom commun) (n)''' : épinard.<br> '''σπάναξ, -κος (nom commun) (m)''' : épinard.<br> '''σπάνιος, -ία, -ιον (adjectif)''' : rare.<br> '''σπανίως (adverbe)''' : rarement.<br> '''σπανιώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''σπάνιος''.<br> '''σπανιώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''σπάνιος''.<br> '''σπαργάνιον, -ίου (nom commun) (n)''' : rubanier.<br> '''σπάργανον, -άνου (nom commun) (n)''' : lange.<br> '''σπάργω (verbe)''' : langer.<br> '''σπαρτιατικός, -ή, -όν (adjectif)''' : spartiate.<br> '''σπασμός, -οῦ (nom commun) (m)''' : spasme.<br> '''σπαστικός, -ή, -όν (adjectif)''' : .<br> '''σπάω (verbe)''' : briser.<br> '''σπεῖρα, -ίρας (nom commun) (f)''' : spire.<br> '''σπεῖρον, -ίρου (nom commun) (n)''' : .<br> '''σπέος, -ους (nom commun) (n)''' : grotte.<br> '''σπεύδω (verbe)''' : se hâter.<br> '''σπήλαιον, -ίου (nom commun) (n)''' : caverne, grotte ; cavité.<br> '''σπῆλυγξ, -ήλυγγος (nom commun) (m)''' : caverne, antre ; grotte.<br> '''σπογγιά, -ᾶς (nom commun) (f)''' : éponge.<br> '''σπόγγος, -ου (nom commun) (m)''' : éponge ; (anatomie) amygdale.<br> '''σποδός, -οῦ (nom commun) (m)''' : cendre.<br> '''σπολεύς, -έως (nom commun) (m)''' : sorte de pain.<br> '''σπονδεῖος, -ίου (nom commun) (m)''' : spondée.<br> '''σπόνδυλος, -ύλου (nom commun) (m)''' : Forme attique de ''σφόνδυλος''.<br> '''σπουδαῖος, -ία, -ῖον (adjectif)''' : important.<br> '''σπουδή, -ῆς (nom commun) (f)''' : hâte.<br> '''στάδιον, -ου (nom commun) (n)''' : stade. (env. 180 m)<br> '''σταγών, -όνος (nom commun) (f)''' : goutte.<br> '''στάζω (verbe)''' : couler goutte à goutte.<br> '''σταθερός, -ή, -όν (adjectif)''' : fixe, constant, ferme.<br> '''στακτός, -οῦ (nom commun) (m)''' : cendre.<br> '''στάλα, -ας (nom commun) (f)''' : Forme dorienne de ''στήλη''.<br> '''στάλαγμα, -άγματος (nom commun) (n)''' : goutte.<br> '''σταλαγμός, -οῦ (nom commun) (m)''' : écoulement, égouttage.<br> '''σταλάσσω (verbe)''' : tomber, couler.<br> '''στάλλα, -ας (nom commun) (f)''' : Forme éolienne de ''στήλη''.<br> '''στάσις, -εως (nom commun) (f)''' : .<br> '''σταυρός, -οῦ (nom commun) (m)''' : croix.<br> '''σταυρόω (verbe)''' : crucifier.<br> '''σταύρωσις, -ώσεως (nom commun) (f)''' : crucifixion.<br> '''σταφυλή, -ῆς (nom commun) (f)''' : grappe de raisin mûr.<br> '''σταφυλίς, -δος (nom commun) (f)''' : luette.<br> '''στέαρ, -ατος (nom commun) (n)''' : Graisse compacte ; lard ; suif. Graisse.<br> '''στεατοπυγός, -ός, -όν (adjectif)''' : Qui a de grosses fesses.<br> '''στέγασις, -άσεως (nom commun) (f)''' : accommodation.<br> '''στέγος, -ους (nom commun) (n)''' : Abri. Toit. Maison. Tombeau. Urne funéraire.<br> '''στέγω (verbe)''' : Couvrir. Supporter, résister.<br> '''στεῖρος, -ίρα, -ῖρον (adjectif)''' : stérile.<br> '''στειρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''στεῖρος''.<br> '''στειρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''στεῖρος''.<br> '''στείρως (adverbe)''' : stérilement.<br> '''στελεά, -ᾶς (nom commun) (f)''' : axe, pôle.<br> '''στελεόν, -οῦ (nom commun) (n)''' : manche.<br> '''στέλεχος, -έχους (nom commun) (n)''' : .<br> '''στέλλω (verbe)''' : .<br> '''στέμμα, -τος (nom commun) (n)''' : guirlande.<br> '''στεμματηφορῶ (verbe)''' : .<br> '''στεμματιαῖον, -ίου (nom commun) (n)''' : .<br> '''στεμματία, -ας (nom commun) (f)''' : .<br> '''στεμματοφορία, -ας (nom commun) (n)''' : .<br> '''στεμματοφόρος, -ό, -όν (adjectif)''' : étroit, resserré.<br> '''στεμματῶ (verbe)''' : .<br> '''στενός, -ή, -όν (adjectif)''' : étroit, resserré.<br> '''στενῶς (adverbe)''' : étroitement.<br> '''στενώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''στενός''.<br> '''στενώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''στενός''.<br> '''στερεός, -ά, -όν (adjectif)''' : ferme, dur.<br> '''στερέωμα, -ώματος (nom commun) (n)''' : firmament.<br> '''στερεῶς (adverbe)''' : fermement, durement.<br> '''στερεώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''στερεός''.<br> '''στερεώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''στερεός''.<br> '''στερεῶ (verbe)''' : .<br> '''στέφανος, -άνου (nom commun) (m)''' : cercle d'une armée sur un champ de bataille. Couronne.<br> '''στέφω (verbe)''' : couronner.<br> '''στηθόδεσμος -ου (nom commun) (m)''' : .<br> '''στῆθος, -ήθους (nom commun)''' : poitrine.<br> '''στήλη, -ης (nom commun) (f)''' : stèle.<br> '''στήνιον, -ίου (nom commun) (n)''' : sein.<br> '''στιϐάς, -δος (nom commun) (f)''' : .<br> '''στίϐι, -τος (nom commun) (n)''' : antimoine.<br> '''στιγμή, -ῆς (nom commun) (f)''' : moment.<br> '''στοργή, -ῆς (nom commun) (f)''' : amour familial.<br> '''στοιχεῖον, -ίου (nom commun) (n)''' : élément.<br> '''στοιχειωδέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''στοιχειώδης''.<br> '''στοιχειωδέστερος, -έρη, -έστερον (adjectif)''' : Comparatif de ''στοιχειώδης''.<br> '''στοιχειώδης, -ης, -ῶδες (m)''' : élémentaire.<br> '''στοιχειωδῶς (adverbe)''' : élémentairement.<br> '''στολίζω (verbe)''' : .<br> '''στόμα, -τος (nom commun) (n)''' : bouche.<br> '''στομάχιον, -ίου (nom commun) (n)''' : estomac.<br> '''στώμυλμα, -τος (nom commun) (n)''' : bavard.<br> '''στοχάζομαι (verbe)''' : Conjecturer. Viser.<br> '''στοχαστής, -οῦ (nom commun) (m)''' : Conjectureur, penseur.<br> '''στοχαστικός, -ή, -όν (adjectif)''' : Qui vise bien, qui tend directement vers. Habile à conjecturer, conjectural.<br> '''στοχαστικῶς (adverbe)''' : conjecturalement.<br> '''στοχαστικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''στοχαστικός''.<br> '''στοχαστικώτερος, -έρη, -ώτερον (adjectif)''' : Comparatif de ''στοχαστικός''.<br> '''στόχος, Cible, but, point visé. Conjecture.<br> '''στορέννυμι (verbe)''' : étendre, recouvrir.<br> '''στραγγαλίζω (verbe)''' : étrangler.<br> '''στραγγαλίς, -δος (nom commun) (f)''' : nœud.<br> '''στραγγαλοῦμαι (verbe)''' : tordre.<br> '''στραγγίζω (verbe)''' : essorer.<br> '''στραγγουρία, -ας (nom commun) (f)''' : strangurie.<br> '''στράγξ, -γός (nom commun) (f)''' : goutte.<br> '''στρατός, -οῦ (nom commun) (m)''' : armée.<br> '''στρατηγός, -οῦ (nom commun) (m)''' : général.<br> '''στραταγός, -οῦ (nom commun) (m)''' : Forme arcadienne et dorienne de ''στρατηγός''.<br> '''στρατήγημα, -ήματος (nom commun) (n)''' : stratagème.<br> '''στρατηγία, -ας (nom commun) (f)''' : stratégie.<br> '''στρέμμα, -τος (nom commun) (n)''' : Tournure ; rouleau. Conspiration.<br> '''στρεπτικός, -ή, -όν (adjectif)''' : .<br> '''στρεπτικῶς (adverbe)''' : .<br> '''στρεπτικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''στρεπτικός''.<br> '''στρεπτικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''στρεπτικός''.<br> '''στρεπτικώτατα, -, - (adverbe)''' : Superlatif de ''στρεπτικῶς''.<br> '''στρεπτικώτερον, -, - (adverbe)''' : Comparatif de ''στρεπτικῶς''.<br> '''στρεπτός, -ή, -όν (adjectif)''' : Tourné ; docile.<br> '''στρεπτῶς (adverbe)''' : docilement.<br> '''στρεπτώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''στρεπτός''.<br> '''στρεπτώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''στρεπτός''.<br> '''στρέφω (verbe)''' : Tourner, retourner.<br> '''στρέψις, -εως (nom commun) (f)''' : .<br> '''στρίζω (verbe)''' : strider.<br> '''στρίξ, -γός (nom commun) (f)''' : chouette.<br> '''στρόταγος, -άγου (nom commun) (m)''' : Forme éolienne de ''στρατηγός''.<br> '''στρατιώτης, -ου (nom commun) (m)''' : soldat.<br> '''στρόϐιλος, -ίλου (nom commun) (m)''' : Ce qui tourne ou tournoie. Toupie. Tourbillon, ouragan. Objet divers en spirale ou de forme conique. Pomme de pin ou fruit des arbres résineux. Coquillage en spirale. Enroulement du hérisson sur lui-même. Qui tournoie en spirale.<br> '''στροϐιλόω (verbe)''' : tourner.<br> '''στραγγός, -ή, -όν (adjectif)''' tordu.<br> '''στρογγύλλω (verbe)''' : arrondir.<br> '''στρογγύλος, -η, -ον (adjectif)''' : arrondi.<br> '''στρογγυλότης, -τος (nom commun) (f)''' : rondeur.<br> '''στρουθιοκάμηλος, -ήλου (nom commun) (m)''' : autruche.<br> '''στρουθίον, -ου (nom commun) (n)''' : moineau.<br> '''στροφή, -ῆς (nom commun) (f)''' : tour.<br> '''στρόφιγξ, -γος (nom commun) (m)''' : charnière.<br> '''στρόφιον, -ίου (nom commun) (n)''' : strophium.<br> '''στρόφος, -ου (nom commun) (m)''' : corde.<br> '''στύφω (verbe)''' : contracter.<br> '''στῦψις, -ύψεως (nom commun) (f)''' : contraction.<br> '''στρῶμα, -ώματος (nom commun) (n)''' : matelas.<br> '''στρώννυμι (verbe)''' : .<br> '''στυγερός, -ά, -όν (adjectif)''' : horrible.<br> '''στυγερώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''στυγερός''.<br> '''στυγερώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''στυγερός''.<br> '''στυγερῶς (adverbe)''' : horriblement.<br> '''στῦλος, -ύλου (nom commun) (m)''' : Pilier, colonne.<br> '''στῦσις, -ύσεως (nom commun) (f)''' : érection (action physiologique).<br> '''στύω (verbe)''' : avoir une érection.<br> '''συγάτηρ, -τρός (nom commun) (f)''' : Forme dorienne de ''θυγάτηρ''.<br> '''συγγνώμη, -ης (nom commun) (f)''' : .<br> '''συγγιγνώσκω (verbe)''' : .<br> '''συγκέντρωσις, -ώσεως (nom commun) (f)''' : concentration.<br> '''συγκεντρῶ (verbe)''' : concentrer.<br> '''συγκεράννυμι (verbe)''' : .<br> '''συγκρητισμός, -οῦ (nom commun) (m)''' : .<br> '''συγκινῶ (verbe)''' : émouvoir.<br> '''συγκίνησις, -ήσεως (nom commun) (f)''' : émotion.<br> '''συγκινητικός, -ή, -όν (adjectif)''' : émouvant.<br> '''συγκρίνω (verbe)''' : comparer.<br> '''σύγκρισις, -ίσεως (nom commun) (f)''' : comparaison.<br> '''συγκριτικός, -ή, -όν (adjectif)''' : comparatif.<br> '''σύγκρουσις, -ύσεως (nom commun) (f)''' : collision.<br> '''συγχώρησις, -εως (nom commun) (f)''' : .<br> '''συγχωρητέος, -α, -ον (adjectif)''' : .<br> '''συζήτησις, -ήσεως (nom commun) (f)''' : discussion, conversation ; débat.<br> '''συζητῶ (verbe)''' : discuter, converser ; débattre.<br> '''σῦκον, -ύκου (nom commun) (n)''' : Figue ; vulve.<br> '''συκοφάντης, -ου (nom commun) (m)''' : Délateur, calomniateur. Chicaneur de mauvaise foi.<br> '''σύκχος, -ους (nom commun) (n)''' : pantoufle.<br> '''συλάω (verbe)''' : Saisir, prendre ; emporter. Dépouiller, prendre les armes de son ennemi mort. Piller.<br> '''σύλη, -ης (nom commun) (f)''' : Prise ; saisie.<br> '''σύλησις, -ήσεως (nom commun) (f)''' : profanation.<br> '''σύλον, -ου (nom commun) (n)''' : Forme attique de ''ξύλον''.<br> '''συλλαμϐάνω (verbe)''' : .<br> '''σύλληψις, -ήψεως (nom commun) (f)''' : Action de prendre ensemble. Compréhension. Réunion par prononciation de deux voyelles. Action de s’emparer, de saisir. Conception dans le sein de la mère. Assistance, secours.<br> '''συμϐάλλω (verbe)''' : .<br> '''σύμϐασις, -άσεως (nom commun) (f)''' : convention.<br> '''συμϐίωσις, -ώσεως (nom commun) (f)''' : vie commune.<br> '''συμϐιῶ (verbe)''' : vivre ensemble.<br> '''συμϐόλαιον, -ίου (nom commun) (n)''' : contrat.<br> '''συμϐολικός, -ή, -όν (adjectif)''' : relatif aux signes de reconnaissance.<br> '''σύμϐολον, -όλου (nom commun) (n)''' : signe de reconnaissance.<br> '''συμμετρία, -ας (nom commun) (f)''' : bonne proportion.<br> '''συμπάθεια, -ίας (nom commun) (f)''' : Communauté de sentiments ou d’impressions. (Philosophie), (Terme stoïcien) Rapport de certaines choses entre elles.<br> '''συμπεραίνω (verbe)''' : accomplir, finir, trancher, décider.<br> '''συμπέρασμα, -άσματος (nom commun) (n)''' : conclusion.<br> '''συμπερασματικός, -ή, -όν (adjectif)''' : conclusif.<br> '''συμπερασματικῶς (adverbe)''' : conclusivement.<br> '''συμπεριφέρομαι (verbe)''' : se comporter.<br> '''συμπεριφορά, -ᾶς (nom commun) (f)''' : comportement.<br> '''συμπεριφορικός, -ή, -όν (adjectif)''' : comportemental.<br> '''συμπεριφορισμός, -οῦ (nom commun) (m)''' : comportementalisme.<br> '''συμπεριφοριστής, -οῦ (nom commun) (m)''' : comportementaliste.<br> '''συμπίνω (verbe)''' : festoyer.<br> '''συμπονῶ (verbe)''' : compatir.<br> '''συμπόσιον, -ίου (nom commun) (n)''' : Banquet, festin. (Collectif) Les convives. Salle de festin.<br> '''σύμπτωμα, -ώματος (nom commun) (n)''' : Accident, malchance ; symptôme.<br> '''σύμπτωσις, -ώσεως (nom commun) (f)''' : coïncidence.<br> '''συμπίπτω (verbe)''' : coïncider.<br> '''συμφορά, -ᾶς (nom commun) (f)''' : désastre.<br> '''συμφοράζω (verbe)''' : .<br> '''συμφοραίνω (verbe)''' : .<br> '''συμφορηδόν, -οῦ (nom commun) (n)''' : .<br> '''συμφόρημα, -ήματος (nom commun) (n)''' : .<br> '''συμφόρησις, -ήσεως (nom commun) (f)''' : congestion.<br> '''συμφορή, -ῆς (nom commun) (f)''' : Forme ionienne de ''συμφορά''.<br> '''συμφέρω (verbe)''' : accumuler.<br> '''συμφύρομαι (verbe)''' : .<br> '''σύμφυσις, -εως (nom commun) (f)''' : symphyse.<br> '''σύμφωνον, -ώνου (nom commun) (n)''' : consonne.<br> '''συναγωγή, -ῆς (nom commun) (f)''' : Rassemblement, assemblée de gens. Rassemblement, regroupement, mis en tas, etc., de choses.<br> '''συνάγω (verbe)''' : rassembler.<br> '''συναίσθημα, -ήματος (nom commun) (n)''' : émotion.<br> '''συναισθάνομαι (verbe)''' : .<br> '''σύν (préposition)''' : Avec, à côté de.<br> '''σύν- (préfixe)''' (Devient ''σύγ-'' devant ''γ'', ''κ'', ''ξ'', ''χ'' ; ''σύλ-'' devant ''λ'' ; ''σύμ-'' devant ''β'', ''π'', ''φ'', ''μ'', ''ψ''.) : syn-.<br> '''σύναψις, -άψεως (nom commun) (f)''' : connexion.<br> '''συνάπτω (verbe)''' : connecter.<br> '''συνέδριον, -ίου (nom commun) (n)''' : conseil, congrégation.<br> '''σύνεδρος, -έδρου (nom commun) (n)''' : conseiller, congrégationniste.<br> '''συνείδησις, -ήσεως (nom commun) (f)''' : conscience.<br> '''συνεργάτης, -ου (nom commun) (m)''' : collaborateur.<br> '''σύνεσις, -έσεως (nom commun) (f)''' : connexion.<br> '''συνίημι (verbe)''' : rejoindre.<br> '''συνίστημι (verbe)''' : .<br> '''συνουσία, -ας (nom commun) (f)''' : copulation.<br> '''συνουσιάζω (verbe)''' : copuler.<br> '''σύνοψις, -όψεως (nom commun) (f)''' : Vue d'ensemble. Coup d'œil général. Table des matières. (Figuré) Examen.<br> '''σύνταγμα, -άγματος (nom commun) (n)''' : constitution.<br> '''συνταγματικός, -ή, -όν (adjectif)''' : constitutionnel.<br> '''συνταγματικότατα, -, - (adverbe)''' : Superlatif de ''συνταγματικῶς''.<br> '''συνταγματικότερον, -, - (adverbe)''' : Comparatif de ''συνταγματικῶς''.<br> '''συνταγματικότης, -τος (nom commun) (f)''' : constitutionnalité.<br> '''συνταγματικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''συνταγματικός''.<br> '''συνταγματικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''συνταγματικός''.<br> '''συνταγματικῶς (adverbe)''' : constitutionnellement.<br> '''σύνταξις, -άξεως (nom commun) (f)''' : mise en ordre.<br> '''συντάσσω (verbe)''' : mettre en ordre.<br> '''συνύπαρξις, -άρξεως (nom commun) (f)''' : coexistence.<br> '''συνυπάρχω (verbe)''' : coexister.<br> '''συνωμοσία, -ας (nom commun) (f)''' : conspiration.<br> '''συνωμότης, -ου (nom commun) (m)''' : conspirateur.<br> '''συνωμότρια, -ας (nom commun) (f)''' : conspiratrice.<br> '''συνωμοτῶ (verbe)''' : conspirer.<br> '''σῦριγξ, -ύριγγος (nom commun) (f)''' : Roseau. (Musique) Flûte de Pan.<br> '''συριστί (adverbe)''' : .<br> '''σύρξ, -κός (nom commun) (f)''' : Forme éolienne de ''σάρξ''.<br> '''σύρραξις, -άξεως (nom commun) (f)''' : .<br> '''συρτός, -οῦ (nom commun) (m)''' : tiroir.<br> '''συσκευή, -ῆς (nom commun) (f)''' : appareil.<br> '''συσσώρευσις, -ύσεως (nom commun) (f)''' : accumulation.<br> '''σύσταμα, -άματος (nom commun) (n)''' : Forme dorienne de ''σύστημα''.<br> '''συστέλλω (verbe)''' : Resserrer, contracter. Réprimer.<br> '''σύστημα, -ήματος (nom commun) (n)''' : Réunion en un unique corps.<br> '''συστολή, -ῆς (nom commun) (f)''' : Resserrement, contraction. Répression.<br> '''σύ (pronom personnel)''' : tu.<br> '''σφαγεύς, -έως (nom commun) (m)''' : tueur.<br> '''σφαγή, -ῆς (nom commun) (f)''' : abattage.<br> '''σφάζω (verbe)''' : tuer, sacrifier.<br> '''σφαῖρα, -ίρας (nom commun) (f)''' : Balle, ballon ; globe.<br> '''σφάκελος, -έλου (nom commun) (m)''' : nécrose.<br> '''σφάλλω (verbe)''' : Faire tomber. faire chuter ; renverser. Défaire, avoir le dessus. Avoir lieu (bien ou mal tomber). Tromper, abuser. (Au passif) Se tromper, fauter. Emballer, rouler.<br> '''σφάλμα, -τος (nom commun) (n)''' : Chute, faux pas. Erreur. Perte.<br> '''σφεδανός, -ή, -όν (adjectif)''' : .<br> '''σφένδαμνος, -άμνου (nom commun) (f)''' : érable.<br> '''σφενδόνη, -ης (nom commun) (f)''' : fronde.<br> '''σφενδονήτης, -ου (nom commun) (m)''' : frondeur.<br> '''σφενδονητικός, -ή, -όν (adjectif)''' : frondeur.<br> '''σφενδονητικῶς (adverbe)''' : -ment.<br> '''σφενδονητικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''σφενδονητικός''.<br> '''σφενδονητικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''σφενδονητικός''.<br> '''σφενδονητικώτατα, -, - (adverbe)''' : Superlatif de ''σφενδονητικῶς''.<br> '''σφενδονητικώτερον, -, - (adverbe)''' : Comparatif de ''σφενδονητικῶς''.<br> '''σφήν, -ός (nom commun) (m)''' : coin (instrument).<br> '''σφηνάριον, -ίου (nom commun) (n)''' : .<br> '''σφηνεύς, -έως (nom commun) (m)''' : coin.<br> '''σφηνίσκος, -ου (nom commun) (m)''' : .<br> '''σφηνοειδής, -ής, -ές (adjectif)''' : cunéiforme.<br> '''σφηνοκέφαλος, -ος, -ον (adjectif)''' : .<br> '''σφηνόπους, -δός (nom commun) (m)''' : .<br> '''σφηνοπώγων, -ονος (nom commun) (m)''' : coin.<br> '''σφηνῶ (verbe)''' : .<br> '''σφήνωσις, -ώσεως (nom commun) (f)''' : .<br> '''σφήξ, -ῆκος (nom commun) (f)''' : guêpe.<br> '''σφίγγω (verbe)''' : attacher fortement.<br> '''σφιγκτήρ, -ῆρος (nom commun) (m)''' : sphincter.<br> '''σφιγμός, -οῦ (nom commun) (m)''' : .<br> '''σφόγγος, -ου (nom commun) (m)''' : Forme attique de ''σπόγγος''.<br> '''σφοδρός, -ά, -όν (adjectif)''' : véhément.<br> '''σφοδρότατα, -, - (adverbe)''' : Superlatif de ''σφοδρῶς''.<br> '''σφοδρότερον, -, - (adverbe)''' : Comparatif de ''σφοδρῶς''.<br> '''σφοδρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''σφοδρός''.<br> '''σφοδρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''σφοδρός''.<br> '''σφοδρότης, -τος (nom commun) (f)''' : véhémence.<br> '''σφοδρῶς (adverbe)''' : véhémentement.<br> '''σφόνδυλος, -ύλου (nom commun) (m)''' : vertèbre.<br> '''σφραγίς, -δος (nom commun) (f)''' : sceau.<br> '''σφράγισμα, -ατος (nom commun) (n)''' : .<br> '''σφραγισμός, -οῦ (nom commun) (m)''' : .<br> '''σφραγιστήρ, -ῆρος (nom commun) (m)''' : .<br> '''σφραγιστήριον, -ίου (nom commun) (n)''' : .<br> '''σφραγιστής, -οῦ (nom commun) (m)''' : .<br> '''σφραγιστός, -ή, -όν (adjectif)''' : .<br> '''σφυγμός, -οῦ (nom commun) (m)''' : pouls.<br> '''σφύζω (verbe)''' : .<br> '''σφύξις, -εως (nom commun) (f)''' : palpitation.<br> '''σφῦρα, -ύρας (nom commun) (f)''' : marteau.<br> '''σφώ (pronom personnel)''' : vous (vous deux).<br> '''σχεδίασμα, -τος (nom commun) (n)''' : caprice.<br> '''σχῆμα, -ήματος (nom commun) (n)''' : Manière d'être. Forme, figure, extérieur. Apparence, faux-semblant.<br> '''σχίζω (verbe)''' : Fendre, séparer en fendant. Séparer en douze parts, avec l’idée de violence. Déchirer la peau avec ses griffes. Fendre, séparer, partager en deux.<br> '''σχίσμα, -ατος (nom commun) (n)''' : division.<br> '''σχοῖνος, -ίνου (nom commun) (m)''' : corde.<br> '''σχολαστικός, -ή, -όν (adjectif)''' : Désœuvré. Inoccupé ; studieux.<br> '''σχολαστικός, -οῦ (nom commun) (m)''' : Homme d'étude. (Péjoratif) Homme d'étude détaché des réalités de la vie ; pédant, nigaud, etc.<br> '''σχολεῖον, -ίου (nom commun) (n)''' : école.<br> '''σχολή, -ῆς (nom commun) (f)''' : Repos. Temps libre. Philosophie, méditation. École.<br> '''σχολιάζω (verbe)''' : commenter.<br> '''σχολιαστής, -οῦ (nom commun) (m)''' : commentateur.<br> '''σχολιάστρια, -ας (nom commun) (f)''' : commentatrice.<br> '''σχολιογράφος, -ου (nom commun) (m/f)''' : chroniqueur.<br> '''σχόλιον, -ίου (nom commun) (n)''' : commentaire.<br> '''σῴζω (verbe)''' : sauver.<br> '''σωλήν, -ῆνος (nom commun) (m)''' : Tube ; tuyau.<br> '''σωληνοειδής -ής -ές (adjectif)''' : .<br> '''σῶμα, -ώματος (nom commun) (n)''' : corps.<br> '''σωματικός, -ή, -όν (adjectif)''' : corporel.<br> '''σωματικῶς (adverbe)''' : corporellement.<br> '''σωματικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''σωματικός''.<br> '''σωματικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''σωματικός''.<br> '''σωματικώτατα, -, - (adverbe)''' : Superlatif de ''σωματικῶς''.<br> '''σωματικώτερον, -, - (adverbe)''' : Comparatif de ''σωματικῶς''.<br> '''σωμάτιον, -ίου (nom commun) (n)''' : codex.<br> '''σώος, -α, -ον (adjectif)''' : sain.<br> '''σωτήρ, -ῆρος (nom commun) (m)''' : Sauveur ; libérateur.<br> '''σωφρονιστήριον, -ίου (nom commun) (n)''' : .<br> '''σωφρονιστήρ, -ῆρος (nom commun) (m)''' : .<br> '''σωφρονίζω (verbe)''' : modérer, tempérer.<br> '''σωφροσύνη, -ης (nom commun) (f)''' : modération, tempérence.<br> '''σώφρων, -ων, -ῶφρον (adjectif)''' : prudent.<br> '''σϝάδυς, -εια, -υ (adjectif)''' : Forme ancienne de ''ἡδύς''.<br> '''Σάϊς, -εως (nom commun) (f)''' : Saïs.<br> '''Σαλμακίς, - (nom commun) (f)''' : Salmacis.<br> '''Σαλομών, -ος (nom propre) (m)''' : Salomon.<br> '''Σαλμωνεύς, -έως (nom propre) (m)''' : Salmonée.<br> '''Σαμάρεια, -ίας (nom propre) (f)''' : Samarie.<br> '''Σαμοθρᾴκη, -ης (nom propre) (f)''' : Samothrace.<br> '''Σαμόθρᾳξ, -κος (nom commun) (m)''' : Samothracien.<br> '''Σάμος, -ου (nom propre) (f)''' : Samos.<br> '''Σανδρόκυπτος, -ύπτου (nom propre) (m)''' : Chandragupta.<br> '''Σαγχουνιάθων, - (nom propre) (m)''' : Sanchoniathon.<br> '''Σαούλ (nom propre) (m)''' : Saül.<br> '''Σαπφώ, -οῦς (nom propre) (f)''' : Sapphô.<br> '''Σαπώρης, -ου (nom commun) (m)''' : Shapur.<br> '''Σάρα, -ας (prénom) (f)''' : Sarah.<br> '''Σαρδόνιος, -ίου (nom commun) (m)''' : Sarde.<br> '''Σαρδώ, -οῦς (nom propre) (f)''' : Sardaigne.<br> '''Σαυρομάτης, -ου (nom commun) (m)''' : Sarmate.<br> '''Σαυροματία, -ας (nom propre) (f)''' : Sarmatie.<br> '''Σαυρομάτις, -δος (nom commun) (f)''' : Sarmate.<br> '''Σατάν (nom propre) (m)''' : Satan.<br> '''Σδεύς, -έως (nom propre) (f)''' : Autre forme éolienne de ''Ζεύς''.<br> '''Σεϐάστεια, -ίας (nom propre) (f)''' : Sivas.<br> '''Σεϐαστή, -ῆς (nom propre) (f)''' : .<br> '''Σεϐαστός, -οῦ (nom propre) (m)''' : Sébastien.<br> '''Σειρήν, -ῆνος (nom propre) (f)''' : sirène.<br> '''Σείριος, -ίου (nom propre) (m)''' : Sirius.<br> '''Σελεύκεια, -ίας (nom propre) (f)''' : Séleucie.<br> '''Σελεύκειος, -α, -ον (adjectif)''' : séleucien.<br> '''Σελευκεύς, -έως (nom commun) (m)''' : Séleucien.<br> '''Σελευκίδης, -ου (nom commun) (m)''' : Séleucide.<br> '''Σελευκίς, -δος (nom commun) (f)''' : Séleucienne.<br> '''Σέλευκος, -ύκου (nom propre) (m)''' : Séleuce.<br> '''Σελήνη, -ης (nom propre) (f)''' : [[wikt:Séléné|Séléné]].<br> '''Σεντικλῆς, -έους (nom propre) (m)''' : Senticlès.<br> '''Σέργιος, -ίου (nom propre) (m)''' : Serge.<br> '''Σέσορθος, -όρθου (nom commun) (m)''' : Djéser.<br> '''Σεύθης, -ου (nom commun) (m)''' : Seuthès.<br> '''Σευθόπολις, -όλεως (nom propre) (f)''' : .<br> '''Σῆθ (nom propre) (m)''' : Seth.<br> '''Σηρική, -ῆς (nom propre) (f)''' : Chine.<br> '''Σθεννώ, -οῦς (nom propre) (f)''' : Sthéno.<br> '''Σίϐυλλα, -ύλλης (nom propre) (f)''' : Sibylle.<br> '''Σιδών, -ῶνος (nom propre) (f)''' : Sidon.<br> '''Σικελία, -ας (nom propre) (f)''' : Sicile.<br> '''Σικελιώτης, -ου (nom commun) (m)''' : Sicéliote.<br> '''Σικελιῶτις, -ώτιδος (nom commun) (f)''' : Sicéliotide.<br> '''Σίκελος, -έλου (nom commun) (m)''' : Sicule.<br> '''Σικυών, -ῶνος (nom propre) (f)''' : Sicyone.<br> '''Σίσυφος, -ύφου (nom propre) (m)''' : Sisyphe.<br> '''Σίνη, -ης (nom propre) (f)''' : Chine.<br> '''Σíνων, -ος (nom propre) (m)''' : Sinon. (cousin d'Ulysse)<br> '''Σιός, -οῦ (nom propre) (m)''' : Autre forme béotienne de ''Ζεύς''.<br> '''Σίσυφος, -ύφου (nom propre) (m)''' : Sisyphe.<br> '''Σκορπιός, -οῦ (nom commun) (m)''' : Scorpion.<br> '''Σκύθαινα, -ίνης (nom propre) (f)''' : Scythe.<br> '''Σκύθης, -ου (nom propre) (m)''' : Scythe.<br> '''Σκυθία, -ας (nom propre) (f)''' : Scythie.<br> '''Σκύλλα, -ης (nom propre) (f)''' : Scylla.<br> '''Σκύλλη, -ης (nom propre) (f)''' : Forme homérique de ''Σκύλλα''.<br> '''Σόλλαξ, -κος (nom propre) (m)''' : Sollax (ancien nom du Tigre).<br> '''Σολομών, -ος (nom propre) (m)''' : Salomon.<br> '''Σόλων, -ος (nom propre) (m)''' : Solon. (cousin d’Ulysse)<br> '''Σούηϐος, -ήϐου (nom propre) (m)''' : Suève.<br> '''Σουοϐηνός, -οῦ (nom commun) (m)''' : Slave.<br> '''Σουσάννα, -ας (nom propre) (f)''' : Suzanne.<br> '''Σοῦφις, -ύφιδος (nom propre) (m)''' : Souphis.<br> '''Σοῦχος, -ύχου (nom propre) (m)''' : Sobek.<br> '''Σοφία, -ας (nom propre) (f)''' : Sophie.<br> '''Σοφοκλῆς, -έους (nom propre) (m)''' : Sophocle.<br> '''Σπάρτα, -ας (nom propre) (f)''' : Forme dorienne de ''Σπάρτη''.<br> '''Σπάρτη, -ης (nom propre) (f)''' : Sparte.<br> '''Σπαρτιάτης, -ου (nom commun) (m)''' : Spartiate.<br> '''Σπαρτιᾶτις, -άτιδος (nom commun) (f)''' : Spartiate.<br> '''Σταυανός, -οῦ (nom commun) (m)''' : Slave.<br> '''Στέφανος, -άνου (nom propre) (m)''' : Étienne ; Stéphane.<br> '''Στράϐων, -ος (nom propre) (m)''' : Strabon.<br> '''Στρογγύλη, ης (nom propre) (f)''' : Stromboli. (île)<br> '''Στρούθας, -ου (nom propre) (m)''' : Struthas.<br> '''Στύξ, -γός (nom propre) (f)''' : Styx.<br> '''Σύϐαρις, -άριδος (nom propre) (f)''' : Sybaris (ville).<br> '''Σύϐαρις, -άρεως (nom propre) (m)''' : Sybaris (fleuve).<br> '''Συδύκ (nom propre) (m)''' : Sydyk.<br> '''Συρία, -ας (nom propre) (f)''' : Syrie.<br> '''Συριακός, -ός, -όν (adjectif)''' : syrien.<br> '''Σύριος, -ίου (nom commun) (m)''' : Syrien.<br> '''Σῦριγξ, -ύριγγος (nom propre) (f)''' : Syrinx.<br> '''Σφίγξ, -γός (nom propre) (f)''' : Sphinx, Sphinge.<br> '''Σωσίας, -ου (nom propre) (m)''' : Sosie.<br> '''Σωσίπατρος, -άτρου (nom propre) (m)''' : Sosipatros.<br> ==Τ== '''τάγηνον, -ήνου (nom commun) (n)''' : Forme dorienne de ''τήγανον''.<br> '''τάγμα, -τος (nom commun) (n)''' : Arrangement. (Militaire) Régiment.<br> '''ταινία, -ας (nom commun) (f)''' : ruban.<br> '''ταινίη, -ης (nom commun) (f)''' : Forme ionienne de ''ταινία''.<br> '''τακτική, -ῆς (nom commun) (f)''' : tactique.<br> '''τακτικός, -ή, -όν (adjectif)''' : tactique.<br> '''τακτικῶς (adverbe)''' : tactiquement.<br> '''τακτικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''τακτικός''.<br> '''τακ τικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''τακτικός''.<br> '''τακτικώτατα, -, - (adverbe)''' : Superlatif de ''τακτικῶς''.<br> '''τακτικώτερον, -, - (adverbe)''' : Comparatif de ''τακτικῶς''.<br> '''τάλαντον, -άντου (nom commun) (n)''' : plateau de balance.<br> '''ταλαντοῦμαι (verbe)''' : osciller.<br> '''ταλάντωσις, -ώσεως (nom commun) (f)''' : oscillation.<br> '''ταμεῖον, -ίου (nom commun) (n)''' : .<br> '''ταμία, -ας (nom commun) (f)''' : maîtresse de maison.<br> '''ταμιακόν, -οῦ (nom commun) (m)''' : fisc.<br> '''ταμιακός, -ή, -όν (adjectif)''' : fiscal.<br> '''ταμιακότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ταμιακός''.<br> '''ταμιακότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ταμιακός''.<br> '''ταμιακῶς (adverbe)''' : fiscalement.<br> '''ταμίας, -ου (nom commun) (m)''' : Dispensateur, distributeur ; partageur. Intendant, économe. Gardien d’un trésor. Directeur, ordonnateur ; arbitre.<br> '''ταμιεῖον, -ίου (nom commun) (n)''' : caisse.<br> '''ταμιεύω (verbe)''' : .<br> '''τάμνω (verbe)''' : Forme homérique et ionienne de ''τέμνω''.<br> '''τάξις, -εως (nom commun) (f)''' : disposition.<br> '''τάξος, -ου (nom commun) (f)''' : if.<br> '''τάπης, -τος (nom commun) (m)''' : tapis.<br> '''τάραγμα, -άγματος (nom commun) (m)''' : inquiétude ; trouble.<br> '''ταραξίας, -ου (nom commun) (m)''' : trouble-fête.<br> '''τάραξις, -άξεως (nom commun) (f)''' : trouble.<br> '''ταράσσω (verbe)''' : troubler.<br> '''ταραχή, -ῆς (nom commun) (f)''' : trouble.<br> '''ταρταροῦχος, -ος, -ον (adjectif)''' : du Tartare.<br> '''τάσις, -εως (nom commun) (f)''' : tension.<br> '''τάσσω (verbe)''' : disposer.<br> '''τατᾶ (interjection)''' : papa ; maman.<br> '''ταταλίζω (verbe)''' : .<br> '''ταῦρος, -ύρου (nom commun) (m)''' : taureau.<br> '''ταυρῶ (verbe)''' : tirer.<br> '''ταῦ (nom commun) (n)''' : tau.<br> '''τάφος, -ου (nom commun) (m)''' : tombeau.<br> '''τάχα (adverbe)''' (Devient ''τάχ’'' devant un mot commençant par une voyelle à esprit doux.) : bientôt.<br> '''ταχέως (adverbe)''' : rapidement.<br> '''ταχύς, -εῖα, -ύ (adjectif)''' : rapide ; pressé.<br> '''ταχύτατος, -άτη, -ύτατον (adjectif)''' : Superlatif de ''ταχύς''.<br> '''ταχύτερος, -έρα, -ύτερον (adjectif)''' : Comparatif de ''ταχύς''.<br> '''ταχυτής, -ῆτος (nom commun) (f)''' : rapidité.<br> '''ταώς, -ώ (nom commun) (m)''' : paon.<br> '''τείνω (verbe)''' : étirer ; tendre.<br> '''τέκτων, -ονος (nom commun) (m)''' : Auteur, créateur. Ouvrier, artisan.<br> '''τεῖχος, -ίχους (nom commun) (n)''' : mur de ville.<br> '''τέλειος, -ία, -ιον (adjectif)''' : terminé ; parfait.<br> '''τελειότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''τέλειος''.<br> '''τελειότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''τέλειος''.<br> '''τελείως (adverbe)''' : parfaitement.<br> '''τελειῶ (verbe)''' : terminer.<br> '''τέλεσμα, -έσματος (nom commun) (n)''' : Paiement, taxe. Certificat.<br> '''τελεστιχίς, -δος (nom commun) (f)''' : téléstiche.<br> '''τελετή, -ῆς (nom commun) (f)''' : cérémonie.<br> '''τελευταῖος, -ία, -ῖον (adjectif)''' : dernier.<br> '''τελευτή, -ῆς (nom commun) (f)''' : fin ; finalité.<br> '''τελέω (verbe)''' : Accomplir. Mettre un terme à.<br> '''τέλος, -ους (nom commun) (n)''' : Achèvement ; accomplissement ; réalisation. Prix dans les luttes.<br> '''τέμαχος, -άχους (nom commun) (n)''' : tranche ; morceau.<br> '''τέμενος, -ένους (nom commun) (n)''' : téménos.<br> '''τέμνω (verbe)''' : couper.<br> '''τέρας, -τος (nom commun) (n)''' : Signe divin ; monstre.<br> '''τεράστιος -α -ον (adjectif)''' : monstrueux.<br> '''τερπνός, -ή, -όν (adjectif)''' : Amusant ; plaisant.<br> '''τερπνότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''τερπνός''.<br> '''τερπνότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''τερπνός''.<br> '''τερπνότης, -τος (nom commun) (f)''' : amusement.<br> '''τερπνῶς (adverbe)''' : plaisamment.<br> '''τέρπω (adverbe)''' : Prendre plaisir ; s’amuser.<br> '''τέσσαρες (adjectif numéral)''' : quatre.<br> '''τετράδιον, -ίου (nom commun) (n)''' : cahier.<br> '''τετραίνω (verbe)''' : trouer.<br> '''τετράλημμα, -ήμματος (nom commun) (n)''' : tétralemme.<br> '''τετράπους, -δος (nom commun) (m)''' : quadrupède.<br> '''τετράς, -δος (nom commun) (f)''' : .<br> '''τετράων, -ος (nom commun) (m)''' : coq de bruyère.<br> '''τετράστιχον, -ίχου (nom commun) (n)''' : quatrain.<br> '''τετταράκοντα (adjectif numéral)''' quarante.<br> '''τέττιξ, -γος (nom commun) (m)''' : cigale.<br> '''τεῦτλον, -ύτλου (nom commun) (n)'''' : blette.<br> '''τεῦχος, -ύχους (nom commun) (n)''' : Ustensile, instrument. (Au pluriel) Armes, armure. (Au pluriel) Agrès de navire (voiles, cordages, rames). Urne pour les libations. Urne funéraire. Baignoire. Tonneau de bois. Huche pour la farine. Ruche d’abeilles.(Par analogie) Vaisseau du corps. Enveloppe qui enferme les petits. Livre.<br> '''τεύχω (verbe)''' : .<br> '''τέφρα, -ας (nom commun) (f)''' : cendre.<br> '''τέφρη, -ης (nom commun) (f)''' : Forme homérique et ionienne de ''τέφρα''.<br> '''τεχνάζω (verbe)''' : faire avec art.<br> '''τέχνασμα, -άσματος (nom commun) (n)'''' : Artifice, machination, ruse.<br> '''τέχνη, -ης (nom commun) (f)''' : Art ; habileté.<br> '''τέχνημα, -ήματος (nom commun) (n)''' : artéfact.<br> '''τεχνητός, -ή, -όν (adjectif)''' : artificiel.<br> '''τεχνητῶς (adverbe)''' : artificiellement.<br> '''τεχνητώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''τεχνητός''.<br> '''τεχνητώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''τεχνητός''.<br> '''τεχνικός, -ή, -όν (adjectif)''' : artistique.<br> '''τεχνικῶς (adverbe)''' : artistiquement.<br> '''τεχνικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''τεχνικός''.<br> '''τεχνικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''τεχνικός''.<br> '''τεχνῶμαι (verbe)''' : .<br> '''τηγάνιον, -ίου (nom commun) (n)''' : Diminutif de ''τήγανον''.<br> '''τήγανον, -άνου (nom commun) (n)''' : poêle à frire.<br> '''τήκω (verbe)''' : fondre.<br> '''τῆλε (adverbe ; préposition)''' Loin, au loin. (Avec le génitif) Loin de.<br> '''τήμερον (adverbe)''' : Forme attique de ''σήμερον''.<br> '''-τήρ, -ῆρος (suffixe) (m)''' : Suffixe nominal.<br> '''-τής, -ῆτος (suffixe) (f)''' : Suffixe permettant de créer à partir d’un adjectif le nom désignant la qualité correspondante.<br> '''-της, -τος (suffixe) (f)''' : Suffixe de même usage que ''-τής''.<br> '''τίγρις, -εως (nom commun) (m/f)''' : Tigre ; tigresse.<br> '''τίθημι (verbe)''' : Poser ; placer.<br> '''τιθήνη, -ης (nom commun) (f)''' : nourrice.<br> '''τεκμηρίωσις, -ώσεως (nom commun) (f)''' : documentation.<br> '''τεκμηριῶ (verbe)''' : documenter.<br> '''τίκτω (verbe)''' : Engendrer, produire ; mettre au monde.<br> '''τιμή, -ῆς (nom commun) (f)''' : (Sens positif) Évaluation, estimation. Prix attaché à un honneur. Ce qui est tenu en honneur ; objet de l’estime, du respect ; autorité, magistrature. (Sens négatif) Peine, châtiment, vengeance.<br> '''τίμιος, -α, -ον (adjectif)''' : honnête.<br> '''τιμιότης, -τος (nom commun) (f)''' : honnêteté.<br> '''τιμωρητέος, -α, -ον (adjectif)''' : punissable.<br> '''τιμωρητικός, -ή, -όν (adjectif)''' : punitif.<br> '''τιμωρητικῶς (adverbe)''' : punitivement.<br> '''τιμωρητικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''τιμωρητικός''.<br> '''τιμωρητικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''τιμωρητικός''.<br> '''τιμωρητικώτατα, -, - (adverbe)''' : Superlatif de ''τιμωρητικῶς''.<br> '''τιμωρητικώτερον, -, - (adverbe)''' : Comparatif de ''τιμωρητικῶς''.<br> '''τιμωρία, -ας (nom commun) (f)''' : punition.<br> '''τιμωρῶ (verbe)''' : punir.<br> '''τιμῶ (verbe)''' : honorer.<br> '''τίνω (verbe)''' : Payer ; payer pour ses fautes, expier.<br> '''τιούχα, -ας (nom commun) (f)''' : Autre forme béotienne de ''τύχη''.<br> '''τίσις, -εως (nom commun) (f)''' : Paiement, récompense. Pénalité, vengeance.<br> '''τιταίνω (verbe)''' : étendre.<br> '''τίταξ, -κos (nom commun) (m)''' : roi.<br> '''τίτας, -αντος (nom commun) (m)''' : vengeur.<br> '''τίτης, -ου (nom commun) (m)''' : Forme dorienne de ''τίτας''.<br> '''τῖφος, -ίφου (nom commun) (m)''' : Étang, marais.<br> '''τίω (verbe)''' : rendre (i.e. payer) des hommages à quelqu’un, estimer une personne. Évaluer, estimer.<br> '''τμῆμα, -ήµατος (nom commun) (n)''' : Partie, secteur ; section.<br> '''τμῆσις, -ήσεως (nom commun) (f)''' : césure.<br> '''τοιοῦτος, -αύτη, -οῦτο (pronom)''' : .<br> '''τοῖχος, -ίχου (nom commun) (m)''' : Mur de maison ; bord ou paroi d’un navire.<br> '''τοιχωρύχημα, -ήµατος (nom commun) (n)''' : cambriolage.<br> '''τοιχώρυχος, -ύχου (nom commun) (m)''' : cambrioleur.<br> '''τοιχωρυχῶ (verbe)''' : cambrioler.<br> '''τοκογλυφία, -ας (nom commun) (f)''' : usure.<br> '''τοκογλυφικός, -ή, -όν (adjectif)''' : usurier.<br> '''τοκογλύφος, -ου (nom commun) (m)''' : usurier.<br> '''τόκος, -ου (nom commun) (m)''' : Parturition, accouchement. Descendance. Intérêt de l'argent prêté.<br> '''τόλμα, -ης (nom commun) (f)''' : Audace ; courage.<br> '''τολμηρός, -ή, -όν (adjectif)''' : hardi.<br> '''τολμηρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''τολμηρός''.<br> '''τολμηρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''τολμηρός''.<br> '''τολμηρότης, -τος (nom commun) (f)''' : hardiesse.<br> '''τολμηρῶς (adverbe)''' : hardiment.<br> '''τολμηρώτατα, -, - (adverbe)''' : Superlatif de ''τολμηρῶς''.<br> '''τολμηρώτερον, -, - (adverbe)''' : Comparatif de ''τολμηρῶς''.<br> '''τολμῶ (verbe)''' : oser.<br> '''-τομία, -ας (suffixe) (f)''' : Suffixe signifiant « coupure », « césure ».<br> '''τόμος, -ου (nom commun) (m)''' : Tranche, pièce ; chose coupée.<br> '''τομός, -οῦ (nom commun) (m)''' : Coupure, action de couper.<br> '''τοπικός, -ή, -όν (adjectif)''' : local.<br> '''τοπικῶς (adverbe)''' : localement.<br> '''τοπικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''τοπικός''.<br> '''τοπικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''τοπικός''.<br> '''τοπικώτατα, -, - (adverbe)''' : Superlatif de ''τοπικῶς''.<br> '''τοπικώτερον, -, - (adverbe)''' : Comparatif de ''τοπικῶς''.<br> '''τοξάριον, -ίου (nom commun) (n)''' : archet.<br> '''τοξικός, -ή, -όν (adjectif)''' : qui convient pour un arc ou pour des flèches.<br> '''τόξον, -ου (nom commun) (n)''' : arc ; arc-en-ciel.<br> '''τοξότης, -ου (nom commun) (m)''' : archer.<br> '''τὸ (article défini)''' : le (neutre).<br> '''τούχα, -ας (nom commun) (f)''' : Forme béotienne de ''τύχη''.<br> '''τράγημα, -ατος (nom commun) (n)''' : friandise.<br> '''τραγικός, -ή, -όν (adjectif)''' : tragique.<br> '''τραγικότατα, -, - (adverbe)''' : Superlatif de ''τραγικῶς''.<br> '''τραγικότερον, -, - (adverbe)''' : Comparatif de ''τραγικῶς''.<br> '''τραγικῶς (adverbe)''' : comiquement.<br> '''τραγικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''τραγικός''.<br> '''τραγικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''τραγικός''.<br> '''τραγίσκος, -ου (nom commun) (m)''' : chevreau.<br> '''τράγος, -ου (nom commun) (m)''' : bouc.<br> '''τραγῳδία, -ας (nom commun) (f)''' : tragédie.<br> '''τραγωδῶ (verbe)''' : chanter.<br> '''τράπεζα, -ης (nom commun) (f)''' : table.<br> '''τραυλίζω (verbe)''' : bégayer, bafouiller.<br> '''τραυλισμός, -οῦ (nom commun) (m)''' : bégaiement, bafouillis.<br> '''τραυλός, -οῦ (nom commun) (m)''' : bègue, bafouilleur.<br> '''τραῦμα, -ύματος (nom commun) (n)''' : Blessure. Déroute, désastre.<br> '''τράχηλος, -ήλου (nom commun) (m)''' : Cou. (En particulier) Derrière du cou, nuque.<br> '''τραχύς, -εῖα, -ύ (adjectif)''' : rude.<br> '''τράχω (verbe)''' : Forme dorienne de ''τρέχω''.<br> '''τρεῖς (adjectif numéral)''' : trois.<br> '''τρέμω (verbe)''' : trembler, s’agiter ; s’ébranler.<br> '''τρέπω (verbe)''' : tourner.<br> '''τρέστης, -ου (nom commun) (m)''' : couard ; peureux.<br> '''τρέφω (verbe)''' : Rendre compact. Rendre gras, engraisser, nourrir. Nourrir, élever. (Par extension) Élever, former, façonner, instruire. Pourvoir aux besoins de. S’épaissir, se condenser. Être nourri ou élevé.<br> '''τρέχω (verbe)''' : courir.<br> '''τρέω (verbe)''' : avoir peur.<br> '''τρῆμα, -ήµατος (nom commun) (n)''' : trou.<br> '''τρηρός, -ή, -όν (adjectif)''' : fou.<br> '''τρήρων, -ος (nom commun) (m/f)''' : timide.<br> '''τριάκοντα (adjectif numéral)''' : trente.<br> '''τρίϐω (verbe)''' : frotter.<br> '''τρίλημμα, -ήμματος (nom commun) (n)''' : trilemme.<br> '''τρίμμα, -τος (nom commun) (n)''' : .<br> '''τρίπος, -ου (nom commun) (m)''' : trépied.<br> '''τρίπους, -δος (adjectif)''' : tripède.<br> '''τρισκελής, -οῦ (nom commun) (m)''' : triskèle.<br> '''τρισκέλιον, -ίου (nom commun) (n)''' : Diminutif de ''τρισκελής''.<br> '''τριταγωνιστής, -οῦ (nom commun) (m)''' : tritagoniste.<br> '''τρίτος, -η, -ον (adjectif numéral)''' : troisième.<br> '''τρίφυλλον, -ύλλου (nom commun) (n)''' : trèfle.<br> '''-τρον, -ου (suffixe) (n)''' : Suffixe servant à former des noms d’instruments.<br> '''τρόπαιον, -ίου (nom commun) (n)''' : trophée.<br> '''τροπή, -ῆς (nom commun) (f)''' : Tour. Fuite. Révolution, changement. (Rhétorique) Tournure de phrase.<br> '''τροπικός, -ή, -όν (adjectif)''' : tournant.<br> '''τρόπος, -ου (nom commun) (m)''' : Tour, direction ; façon, mode, manière.<br> '''τροχαῖος, -ίου (nom commun) (m)''' : trochée.<br> '''τροχαλία, -ας (nom commun) (f)''' : poulie.<br> '''τροχίλος, -ου (nom commun) (m)''' : poulie.<br> '''τρόχος, -ου (nom commun) (m)''' : blaireau.<br> '''τροχός, -οῦ (nom commun) (m)''' : Roue. Tour de potier. Pain (de forme ronde) de suif ou de cire.<br> '''τρύϐλιον, -ίου (nom commun) (n)''' : bol ; coupe.<br> '''τρυγόνιον, -ίου (nom commun) (n)''' : Diminutif de ''τρυγών ''.<br> '''τρυγών, -όνος (nom commun) (f)''' : tourterelle.<br> '''τρύζω (verbe)''' : .<br> '''τρῦπα, -ύπας (nom commun) (f)''' : trou.<br> '''τρύπημα, -ήματος (nom commun) (n)''' : trou.<br> '''τρύω (verbe)''' : user.<br> '''τύρρις, -ος (nom commun) (f)''' : variante de ''τύρσις''.<br> '''τύρσις, -ος (nom commun) (f)''' : tour (construction élevée).<br> '''τρύφαξ, -κος (nom commun) (m)''' : débauché.<br> '''τρυφερός, -ά, -όν (adjectif)''' : délicat.<br> '''τρυφερότης, -τος (nom commun) (f)''' : délicatesse.<br> '''τρυφερώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''τρυφερός''.<br> '''τρυφερώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''τρυφερός''.<br> '''τρυφερῶς (adverbe)''' : délicatement.<br> '''τρυφή, -ῆς (nom commun) (f)''' : Douceur, mollesse. Luxe, délicatesse. Dissolution, débauche.<br> '''τρύφημα, -ήματος (nom commun) (n)''' : orgueil.<br> '''τρυφητής, -ής, -ές (adjectif)''' : voluptueux.<br> '''τρυφῶ (verbe)''' : être extravagant, se donner des airs.<br> '''τρῦχος, -ύχους (nom commun) (n)''' : Haillon, lambeau.<br> '''τρύχω (verbe)''' : épuiser, user.<br> '''τρώγω (verbe)''' : ronger, grignoter.<br> '''τρωϊκός, -ή -όν (adjectif)''' : troyen.<br> '''τρῶ (verbe)''' : avoir peur.<br> '''τῦκον, -ύκου (nom commun) (m)''' : Forme béotienne de ''σῦκον''.<br> '''τύμϐος, -ου (nom commun) (m)''' : tumulus.<br> '''τυνδάρειος, -ος, -ον (nom commun) (m)''' : tyndaréen.<br> '''τυπικός, -ή -όν (adjectif)''' : figuré.<br> '''τυπικῶς (adverbe)''' : figurativement.<br> '''τυπικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''τυπικός''.<br> '''τυπικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''τυπικός''.<br> '''τυπικώτατα, -, - (adverbe)''' : Superlatif de ''τυπικῶς''.<br> '''τυπικώτερον, -, - (adverbe)''' : Comparatif de ''τυπικῶς''.<br> '''τύπος, -ου (nom commun) (m)''' : Coup ; frappe. Frappe, marque du coup ; sceau, impression.<br> '''τύπτω (verbe)''' : frapper.<br> '''τύραννος, -άννου (nom commun) (m)''' : Maître, dominateur. (Péjoratif) Tyran, dictateur ; despote.<br> '''τύρϐη, -ης (nom commun) (f)''' : tumulte, désordre.<br> '''τυρός, -οῦ (nom commun) (m)''' : fromage.<br> '''τυτώ, -οῦς (nom commun) (f)''' : chouette.<br> '''τύ (pronom personnel)''' : Forme dorienne de ''σύ''.<br> '''τυφλός, -ή -όν (adjectif)''' : aveugle.<br> '''τῦφος, -ύφου (nom commun) (m)''' : fumée, vapeur qui monte au cerveau ; orgueil.<br> '''τῦφω (verbe)''' : enfumer.<br> '''τυχαῖος, -ία, -ῖον (adjectif)''' : chanceux.<br> '''τυχερῶς (adverbe)''' : .<br> '''τύχη, -ης (nom commun) (f)''' : chance.<br> '''τυχηρός, -ά, -όν, (adjectif)''' : chanceux.<br> '''τύψις, -εως (nom commun) (f)''' : remords.<br> '''Ταλθύϐιος, -ίου (nom propre) (m)''' : Talthybios.<br> '''Τάλως, -ώ (nom propre) (m)''' : Talos.<br> '''Τάμεσις, -έσεως (nom propre) (f)''' : Tamise.<br> '''Τάναϊς, -άϊδος (nom propre) (m)''' : Tanaïs.<br> '''Τάν, -ός (nom propre) (m)''' : Forme crétoise de ''Ζεύς''.<br> '''Ταραντῖνος, -ίνου (nom commun) (m)''' : Tarentin.<br> '''Τάρας, -αντος (nom propre) (m)''' : Tarente.<br> '''Τάρταρος, -άρου (nom propre) (m)''' : Tartare.<br> '''Ταῦρος, -ύρου (nom propre) (m)''' : Taureau.<br> '''Τειρεσίας, -ου (nom propre) (m)''' : Tirésias.<br> '''Τεΐσπης, -ου (nom propre) (m)''' : Teispès.<br> '''Τελεύτας, -αντος (nom propre) (m)''' : Téleutas.<br> '''Τελευτίας, -ου (nom propre) (m)''' : Téleutias.<br> '''Τερψιχόρα, -ας (nom propre) (f)''' : Terpsichore.<br> '''Τεύτων, -ονος (nom commun) (m)''' : Teuton.<br> '''Τηθύς, -ος (nom propre) (f)''' : [[wikt:Téthys|Téthys]].<br> '''Τηλέγονος, -όνου (nom propre) (m)''' : Télégonos.<br> '''Τηλέμαχος, -άχου (nom propre) (m)''' : Télémaque.<br> '''Τηρεύς, -έως (nom propre) (m)''' : Térée.<br> '''Τίγρης, -τος (nom propre) (m)''' : Tigre (fleuve du Moyen-Orient).<br> '''Τίγρις, -δος (nom propre) (f)''' : Forme alternative de ''Τίγρης''.<br> '''Τιθωνός, -οῦ (nom propre) (m)''' : Tithon.<br> '''Τιμασίθεος, -έου (nom propre) (m)''' : Timasithée.<br> '''Τιμόθεος, -έου (nom propre) (m)''' : Timothée.<br> '''Τίμων, -ωνος (nom propre) (m)''' : Timon.<br> '''Τισαμενός, -οῦ (nom propre) (m)''' : Tisamène.<br> '''Τίσανδρος, -άνδρου (nom propre) (m)''' : Tisandre.<br> '''Τισίας, -ου (nom propre) (m)''' : Tisias.<br> '''Τισικράτης, -ου (nom propre) (m)''' : Tisicrate.<br> '''Τισιφόνη, -ης (nom propre) (f)''' : Tisiphone (une des Érynies).<br> '''Τισσαφέρνης, -ου (nom propre) (m)''' : Tissapherne.<br> '''Τιτάν, -ᾶνος (nom propre) (m)''' : Titan.<br> '''Τιτανίς, -δος (nom propre) (f)''' : Titanide.<br> '''Τιτυός, -οῦ (nom propre) (m)''' : Tityos.<br> '''Τόσορθρος, -όρθου (nom commun) (m)''' : Djéser.<br> '''Τοξότης, -ου (nom propre) (m)''' : Sagittaire.<br> '''Τρίπολις, -όλεως (nom propre) (f)''' : Tripoli.<br> '''Τρίτων, -ος (nom propre) (m)''' : Triton.<br> '''Τροία, -ας (nom propre) (f)''' : Troie.<br> '''Τρωάς, -δος (nom commun) (f)''' : Troyenne.<br> '''Τρώς, -ός (nom commun) (m)''' : Troyen.<br> '''Τῦϐι (nom propre) (m)''' : Tybi.<br> '''Τυδεύς, -έως (nom propre) (m)''' : Tydée.<br> '''Τυνδάρεως, -εω (nom propre) (m)''' : Tyndare.<br> '''Τυνδαρίδης, -ου (nom propre) (m)''' : Tyndaride.<br> '''Τυνδαρίς, -δος (nom propre) (f)''' : Tyndaride.<br> '''Τυφάων, -ος (nom propre) (m)''' : Forme de ''Τυφῶν''.<br> '''Τυφωεύς, -έως (nom propre) (m)''' : Forme de ''Τυφῶν''.<br> '''Τυφώς, - (nom propre) (m)''' : Forme de ''Τυφῶν''.<br> '''Τυφῶν, -ος (nom propre) (m)''' : Typhon.<br> '''Τύχη, -ης (nom propre) (f)''' : [[wikt:Tyché|Tyché]].<br> '''Τύχων, -ος (nom propre) (m)''' : Tychon.<br> ==Υ== '''ὕαινα, -ίνης (nom commun) (f)''' : hyène.<br> '''ὕαλος, -άλου (nom commun) (m)''' : verre. (matière)<br> '''ὑϐριζω (verbe)''' : maltraiter, outrager.<br> '''ὕϐρις, -εως (nom commun) (f)''' : démesure, violence ; excès, outrage.<br> '''ὑγίεια, -ίας (nom commun) (f)''' : propreté.<br> '''ὑγιεινή, -ῆς (nom commun) (f)''' : santé.<br> '''ὑγιεινός, -ή, -όν (adjectif)''' : salubre.<br> '''ὑγραίνω (verbe)''' : humidifier.<br> '''ὑγρασία, -ας (nom commun) (f)''' : humidité.<br> '''ὑγρός, -ά, -όν (adjectif)''' : humide.<br> '''ὑγρότατα, -, - (adverbe)''' : Superlatif de ''ὑγρῶς''.<br> '''ὑγρότερον, -, - (adverbe)''' : Comparatif de ''ὑγρῶς''.<br> '''ὑγρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ὑγρός''.<br> '''ὑγρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''ὑγρός''.<br> '''ὑγρῶς (adverbe)''' : humidement.<br> '''ὑδραγωγεῖον, -ίου (nom commun) (n)''' : aqueduc.<br> '''ὑδράργυρος, -ύρου (nom commun) (m)''' : mercure.<br> '''ὑδρόμελι, -τος (nom commun) (n)''' : Boisson à base d'eau et de miel.<br> '''ὑδρο- (préfixe)''' : hydro-.<br> '''ὕδωρ, -ατος (nom commun) (n)''' : Eau ; sueur.<br> '''ὕενος, -ένου (nom commun) (m)''' : mercure.<br> '''υἱός, -οῦ (nom commun) (m)''' : fils.<br> '''ὕλη, -ης (nom commun) (f)''' : matière ; bois.<br> '''ὑμεῖς (pronom personnel)''' : vous.<br> '''ὑμέτερος, -έρα, -έτερον (adjectif possessif)''' : votre.<br> '''ὑμήν, -ένος (nom commun) (m)''' : Membrane ; pellicule enveloppant les organes du corps.<br> '''ὕμνος, -ου (nom commun) (m)''' : trame ; chant.<br> '''ὑμνῳδία, -ας (nom commun) (f)''' : hymne.<br> '''ὑμνῶ (verbe)''' : .<br> '''ὔμοι (adverbe)''' : Forme éolienne de ''ὁμοῦ''.<br> '''ὔμοιος, -, - (adjectif)''' : Forme éolienne de ''ὅμοιος''.<br> '''ὑμοῖος, -, -ῖον (adjectif)''' : Forme arcado-chypriote de ''ὅμοιος''.<br> '''ὑπαγόρευσις, -ύσεως (nom commun) (f)''' : dictée.<br> '''ὑπάγω (verbe)''' : mener sous.<br> '''ὑπακτικός -ή -όν (adjectif)''' : .<br> '''ὑπακοή, -ῆς (nom commun) (f)''' : obéissance.<br> '''ὑπάκουος, -η, -ον (adjectif)''' : obéissant.<br> '''ὑπακούω (verbe)''' : obéir.<br> '''ὑπαρξιακός, -ή, -όν (adjectif)''' : existentiel.<br> '''ὕπαρξις, -άρξεως (nom commun) (f)''' : existence.<br> '''ὑπάρχω (verbe)''' : exister.<br> '''ὑπεξαίρεσις, -έσεως (nom commun) (f)''' : malversation.<br> '''ὑπεξαιρῶ (verbe)''' : .<br> '''ὑπερκόσμιος, -α, -ο (adjectif)''' : .<br> '''ὑπέρ (adverbe ; préposition)''' : au-dessus.<br> '''ὑπερϐάλλω (verbe)''' : exagérer.<br> '''ὑπερϐολή, -ῆς (nom commun) (f)''' : exagération.<br> '''ὑπερϐολικός, -ή, -όν (adjectif)''' : excessif.<br> '''ὑπερθετικός, -ή, -όν (adjectif)''' : superlatif.<br> '''ὑπεριώδης, -ης, -ες (adjectif)''' : ultraviolet.<br> '''ὑπεροπτικός, -ή, -όν (adjectif)''' : arrogant.<br> '''ὑπέροπτος, -ος, -ον (adjectif)''' : .<br> '''ὑπεροψία, -ας (nom commun) (f)''' : arrogance.<br> '''ὑπέρυθρος, -η, -ον (adjectif)''' : infrarouge.<br> '''ὑπερφυσικός, -ή, -όν (adjectif)''' : surnaturel.<br> '''ὑπεύθυνος, -ος, -ον (adjectif)''' : responsable.<br> '''ὑπευθυνότητα, -ας (nom commun) (f)''' : responsabilité.<br> '''ὑπηρεσία, -ας (nom commun) (f)''' : service.<br> '''ὑπηρέτης, -ου (nom commun) (m)''' : serviteur.<br> '''ὑπηρετικός, -ή, -όν (adjectif)''' : de service.<br> '''ὑπηρετικῶς (adverbe)''' : -ment.<br> '''ὑπηρετικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ὑπηρετικός''.<br> '''ὑπηρετικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ὑπηρετικός''.<br> '''ὑπηρετικώτατα, -, - (adverbe)''' : Superlatif de ''ὑπηρετικῶς''.<br> '''ὑπηρετικώτερον, -, - (adverbe)''' : Comparatif de ''ὑπηρετικῶς''.<br> '''ὑπηρέτρια, -ας (nom commun) (f)''' : servante.<br> '''ὑπηρετῶ (verbe)''' : servir.<br> '''ὑπνολαλία, -ας (nom commun) (f)''' : somniloquie.<br> '''ὑπνολαλῶ (verbe)''' : somniloquer.<br> '''ὕπνωσις, -ώσεως (nom commun) (f)''' : hypnose.<br> '''ὑπνωτικός, -ή, -όν (adjectif)''' : hypnotique.<br> '''ὑπνῶ (adjectif)''' : hypnotiser.<br> '''ὑπόϐαθρον, -άθρου (nom commun) (n)''' : arrière-plan.<br> '''ὑπόγειον, -ίου (nom commun) (n)''' : cave.<br> '''ὑπόδειγμα, -ίγματος (nom commun) (n)''' : exemple.<br> '''ὑποδειγματικός, -ή, -όν (adjectif)''' : exemplaire.<br> '''ὑποδείκνυμι (verbe)''' : .<br> '''ὑπόδημα, -ήματος (nom commun) (n)''' : chaussure.<br> '''ὑποδηματοποιεῖον, -ίου (nom commun) (n)''' : boutique du cordonnier.<br> '''ὑποδηματοποιός, -οῦ (nom commun) (m)''' : cordonnier.<br> '''ὑποζύγιον, -ίου (nom commun) (n)''' : attelage.<br> '''ὑπόθεσις, -έσεως (nom commun) (f)''' : supposition.<br> '''ὑποκινῶ (verbe)''' : .<br> '''ὑποκορίζομαι (verbe)''' : parler comme un enfant.<br> '''ὑποκόρισμα, -τος (nom commun) (n)''' : sobriquet.<br> '''ὑποκοριστικός, -ή, -όν (adjectif)''' : caressant, propre à atténuer.<br> '''ὑποκρίνομαι (verbe)''' : jouer une pièce.<br> '''ὑπόκρισις, -ίσεως (nom commun) (f)''' : Réponse. Action de jouer un rôle, une pièce, une pantomime. Débit théâtral, déclamation. Feinte, faux-semblant.<br> '''ὑποκριτής, -οῦ (nom commun) (m)''' : Donneur de réponse. Acteur, comédien.<br> '''ὑπόκωφος, -η, -ον (adjectif)''' : sourd.<br> '''ὑποκώφως (adverbe)''' : sourdement.<br> '''ὑπολογίζομαι (verbe)''' : calculer.<br> '''ὑπολογισμός, -οῦ (nom commun) (m)''' : calcul.<br> '''ὑπομιμνήσκω (verbe)''' : .<br> '''ὑπομονή, -ῆς (nom commun) (f)''' : .<br> '''ὑπόμνημα, -ήματος (nom commun) (n)''' : .<br> '''ὑπόνομος, -ου (nom commun) (m)''' : égout.<br> '''ὑπόστασις, -άσεως (nom commun) (f)''' : .<br> '''ὑποταγή, -ῆς (nom commun) (f)''' : Subordination, soumission.<br> '''ὑποτάσσω (verbe)''' : Subordonner, soumettre. Dominer, contrôler.<br> '''ὑποτίθημι (verbe)''' : supposer.<br> '''ὑπότριμμα, -ίμματος (nom commun) (n)''' : Sauce aux herbes, sauce verte et piquante.<br> '''ὑπουργεῖον, -ίου (nom commun) (n)''' : ministère.<br> '''ὑπουργικός, -ή, -όν (adjectif)''' : ministériel.<br> '''ὑπουργός, -οῦ (nom commun) (m)''' : ministre.<br> '''ὑποχώρησις, -ήσεως (nom commun) (f)''' : régression.<br> '''ὑποχωρητικός, -ή, -όν (adjectif)''' : régressif.<br> '''ὑποψήφιος, -ίου (nom commun) (m)''' : candidat.<br> '''ὑπό (adverbe ; préposition)''' : en dessous.<br> '''ὑπο- (préfixe)''' : relatif au dessous.<br> '''ὕραξ, -κος (nom commun) (m)''' : souris.<br> '''ὕσσωπος, -ώπου (nom commun) (f)''' : hysope.<br> '''ὕστατος, -η, -ον (adjectif)''' : dernier.<br> '''ὑστερέω (verbe)''' : .<br> '''ὑστέρησις, -ήσεως (nom commun) (f)''' : hystérèse.<br> '''ὑστερικός, -ή, -όν (adjectif)''' : utérin ; hystérique.<br> '''ὑστερο- (préfixe)''' : suivant ; tardif.<br> '''ὕστερος, -α, -ον (adjectif)''' : postérieur.<br> '''ὕστερος, -έρου (nom commun) (m)''' : matrice ; utérus.<br> '''ὑστέρως (adverbe)''' : .<br> '''ὕστριξ, -χός (nom commun) (m/f)''' : porc-épic.<br> '''ὗς, -ός (nom commun) (m/f)''' : Porc, sanglier. Truie, laie.<br> '''ὑφαίνω (verbe)''' : tisser.<br> '''ὕφαλος, -άλου (nom commun) (m)''' : récif.<br> '''ὑφή, -ῆς (nom commun) (f)''' : toile d’araignée.<br> '''ὕφος, -ους (nom commun) (n)''' : tissu.<br> '''ὑψηλός, -ή, -όν (adjectif)''' : .<br> '''ὕψι (adverbe)''' : en haut.<br> '''ὖ ψιλόν (nom commun) (n)''' : upsilon.<br> '''ὑψίτερος, -έρη, -ερον (adverbe)''' : Comparatif de ''ὕψι''.<br> '''ὕψιστος, -ίστη, -ιστον (adverbe)''' : Superlatif de ''ὕψι''.<br> '''ὕψος, -ους (nom commun) (n)''' : hauteur.<br> '''ὕψωμα, -ώματος (nom commun) (n)''' : élévation.<br> '''ὕψωσις, -ώσεως (nom commun) (f)''' : élévation.<br> '''ὑψῶ (verbe)''' : élever.<br> '''ὕω (verbe)''' : pleuvoir.<br> '''Ὕϐρις, -εως (nom propre) (f)''' : Hybris.<br> '''Ὑδροχόος, -ου (nom propre) (m)''' : Verseau.<br> '''Ὑγίεια, -ίας (nom propre) (f)''' : [[wikt:Hygie|Hygie]].<br> '''Ὕηττος, -ήττου (nom propre) (m)''' : Hyettos.<br> '''Ὑκσώς, -οῦς (nom commun) (m)''' : Hyksôs.<br> '''Ὕλλος, -ου (nom propre) (m)''' : Hyllos.<br> '''Ὑμέναιος, -ίου (nom propre) (m)''' : [[wikt:Hyménée|Hyménée]].<br> '''Ὑμήν, -ένος (nom propre) (m)''' : Variante de ''Ὑμέναιος''.<br> '''Ὑπερίων, -ος (nom propre) (m)''' : Hypérion.<br> '''Ὕπνος, -ου (nom propre) (m)''' : [[wikt:Hypnos|Hypnos]].<br> '''Ὑστάσπης, -ου (nom propre) (m)''' : Hystaspès.<br> '''Ὕψιστος, -ίστου (nom propre) (m)''' : Très-Haut.<br> ==Φ== '''φαγός, -οῦ (nom commun) (m)''' : Forme dorienne de ''φηγός''.<br> '''φαιδρός, -ίδρα, -ιδρόν (adjectif)''' : brillant ; rayonnant, enjoué ; gai, jovial.<br> '''φαίνεσθαι (verbe)''' : se montrer.<br> '''φαινόμενον, -ένου (nom commun) (n)''' : phénomène.<br> '''φαίνω (verbe)''' : faire briller.<br> '''φακός, -οῦ (nom commun) (m)''' : Lentille. (Anatomie) Cristallin. Tache de rousseur.<br> '''φακόχοιρος, -ίρου (nom commun) (m)''' : phacochère.<br> '''φάλαγξ, -γος (nom commun) (f)''' : phalange.<br> '''φάλλαινα, -ίνης (nom commun) (f)''' : baleine.<br> '''φαλλός, -οῦ (nom commun) (m)''' : phallus.<br> '''φάμη, -ης (nom commun) (f)''' : Forme dorienne de ''φήμη''.<br> '''φαμί (verbe)''' : Forme dorienne de ''φημί''.<br> '''φάναξ, -κος (nom commun) (m)''' : .<br> '''φανερός, -ά, -όν (adjectif)''' : Apparent. En vue.<br> '''φανερῶς (adverbe)''' : .<br> '''φανερώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''φανερός''.<br> '''φανερώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''φανερός''.<br> '''φανερῶ (verbe)''' : .<br> '''φανός, -οῦ (nom commun) (m)''' : .<br> '''φάνταγμα, -άγματος (nom commun) (n)''' : Forme ionienne de ''φάντασμα''.<br> '''φαντάζω (verbe)''' : Dénoncer ; Se montrer, apparaître.<br> '''φαντασία, -ας (nom commun) (f)''' : imagination.<br> '''φάντασμα, -άσματος (nom commun) (n)''' : Apparition, vision, songe ; fantôme, spectre.<br> '''φανταστής, -οῦ (nom commun) (m)''' : vantard.<br> '''φανταστικός, -ή, -όν (adjectif)''' : imaginaire.<br> '''φάραγξ, -γος (nom commun) (m)''' : canyon.<br> '''φαραώ (nom commun) (m)''' : pharaon.<br> '''φαρέτρα, -ας (nom commun) (f)''' : carquois.<br> '''φαρέτρη, -ης (nom commun) (f)''' : Forme dorienne de ''φαρέτρα''.<br> '''φαρετρεών, -ῶνος (nom commun) (m)''' : .<br> '''φαρισαϊκός, -ή, -όν (adjectif) (f)''' : pharisien.<br> '''φαρισαϊκότατα, -, - (adverbe)''' : Superlatif de ''φαρισαϊκῶς''.<br> '''φαρισαϊκότερον, -, - (adverbe)''' : Comparatif de ''φαρισαϊκῶς''.<br> '''φαρισαϊκῶς (adverbe)''' : pharisiennement.<br> '''φαρισαϊκώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''φαρισαϊκός''.<br> '''φαρισαϊκώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''φαρισαϊκός''.<br> '''φαρισαῖος, -ίου (nom commun) (m)''' : pharisien.<br> '''φαρμακεία, -ας (nom commun) (f)''' : ensemble des médicaments.<br> '''φαρμακεύς, -έως (nom commun) (m)''' : Apothicaire, empoisonneur. Sorcier.<br> '''φαρμακευτικός, -ή, -όν (adjectif) (f)''' : de remède.<br> '''φαρμακευτικότατα, -, - (adverbe)''' : Superlatif de ''φαρμακευτικῶς''.<br> '''φαρμακευτικότερον, -, - (adverbe)''' : Comparatif de ''φαρμακευτικῶς''.<br> '''φαρμακευτικῶς (adverbe)''' : .<br> '''φαρμακευτικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''φαρμακευτικός''.<br> '''φαρμακευτικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''φαρμακευτικός''.<br> '''φαρμακίς, -δος (nom commun) (f)''' : Apothicaire, empoisonneuse. Sorcière.<br> '''φάρμακον, -άκου (nom commun) (n)''' : Médicament, remède ; poison, préparation magique. Teinture, fard.<br> '''φαρμακοποσία, -ας''' : action de boire une potion.<br> '''φαρμακοπώλης, -ου (nom commun) (m)''' : pharmacien.<br> '''φαρμακός, -οῦ (nom commun) (m)''' : victime expiatoire.<br> '''φαρμακοτρίϐης, -ου (nom commun) (m)''' : laborantin.<br> '''φαρμακώδης, -ης, -ες (adjectif)''' : médicinal ; vénéneux.<br> '''φαρμακῶ (verbe)''' : empoisonner.<br> '''φάρυγξ, -γος (nom commun) (m)''' : gosier.<br> '''φάσηλος, -ήλου (nom commun) (m)''' : haricot sec.<br> '''φασιανικός, -ή, -όν (adjectif)''' : phasianien.<br> '''φασιανός, -οῦ (nom commun) (m)''' : faisan.<br> '''φάκελος, -έλου (nom commun) (m)''' : fagot, faisceau.<br> '''φάσκος, -ου (nom commun) (m)''' : .<br> '''φασκώλιον, -ίου (nom commun) (n)''' : valisette.<br> '''φάσκωλος, -ώλου (nom commun) (m)''' : valise.<br> '''φάσμα, -τος (nom commun) (n)''' : spectre.<br> '''φασματικός, -ή, -όν (adjectif)''' : spectral.<br> '''φασματικώτατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''φασματικός''.<br> '''φασματικώτερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''φασματικός''.<br> '''φασματικῶς (adverbe)''' : spectralement.<br> '''φασματικώτατα, -, - (adverbe)''' : Superlatif de ''φασματικῶς''.<br> '''φασματικώτερον, -, - (adverbe)''' : Comparatif de ''φασματικῶς''.<br> '''φάτις, -εως (nom commun) (f)''' : rumeur, parole.<br> '''φάττα, -ης (nom commun) (f)''' : palombe ; ramier.<br> '''φαῦλος, -ύλη, -ῦλον (adjectif)''' : vicieux.<br> '''φέγγος, -ους (nom commun) (n)''' : .<br> '''φέρετρον, -έτρου (nom commun) (n)''' : cercueil.<br> '''φέρω (verbe)''' : porter.<br> '''φεύγω (verbe)''' : fuir (prendre la fuite).<br> '''φεῦξις, -ύξεως (nom commun) (f)''' : échappée, évasion ; fuite.<br> '''φεῦ (interjection)''' : Hélas ; ah.<br> '''φή (conjonction)''' : Forme homérique de ''ὡς''.<br> '''φηγός, -οῦ (nom commun) (f)''' : chêne.<br> '''φηλητής, -οῦ (nom commun) (m)''' : trompeur.<br> '''φῆλος, -ος, -ον (adjectif)''' : trompeur.<br> '''φήμη, -ης (nom commun) (f)''' : Voix prophétique, oracle. Rumeur, réputation.<br> '''φημί (verbe)''' : dire.<br> '''φήρ, -ός (nom commun) (m)''' : Forme éolienne de ''θήρ''.<br> '''φθέγγομαι (verbe)''' : proférer.<br> '''φθειρρός, -οῦ (nom commun) (m)''' : pou.<br> '''φθείρω (verbe)''' : user.<br> '''φθινόπωρον, -ώρου (nom commun) (n)''' : automne.<br> '''φθίσις, -εως (nom commun) (f)''' : Déclin, ruine. Atrophie, consomption. Contraction, réduction de la pupille.<br> '''φθίω (verbe)''' : périr, disparaitre.<br> '''φθόγγος, -ου (nom commun) (m)''' : son.<br> '''φθονερός, -ή, -όν (adjectif) (f)''' : envieux.<br> '''φθόνησις, -ήσεως (nom commun) (f)''' : dénégation.<br> '''φθόνος, -ου (nom commun) (m)''' : envie.<br> '''φθονῶ (verbe)''' : envier.<br> '''φθορά, -ᾶς (nom commun) (f)''' : Perdition, perte, ruine, destruction. Action de corrompre, corruption, séduction. (Peinture) Dégradation de couleur, affaiblissement de teinte.<br> '''φῖ (nom commun) (n)''' : phi.<br> '''φίλαμα, -άματος (nom commun) (n)''' : Forme dorienne de ''φίλημα''.<br> '''φιλαδελφία, -ας (nom commun) (f)''' philadelphie.<br> '''φιλανδρία, -ας (nom commun) (f)''' philandrie.<br> '''φιλανθρωπία, -ας (nom commun) (f)''' philanthropie.<br> '''φιλάνθρωπος, -ος, -ον (adjectif)''' : Humain, bon ; bienveillant, affable. Qui aime les hommes (en parlant des dieux). Qui plaît aux hommes, agréable.<br> '''φιλαργυρία, -ας (nom commun) (f)''' : avarice.<br> '''φιλάργυρος, -ος, -ον (adjectif)''' : avare.<br> '''φίλειμι (verbe)''' : Forme béotienne de ''φιλῶ''.<br> '''φίλημμι (verbe)''' : Forme éolienne de ''φιλῶ''.<br> '''φιλία, -ας (nom commun) (f)''' : amitié, amour absolu, plaisir de la compagnie.<br> '''φιλίη, -ης (nom commun) (f)''' : Forme ionienne de ''φιλία''.<br> '''φίλημα, -ήματος (nom commun) (n)''' : baiser.<br> '''φίλημμι (verbe)''' : Forme éolienne de ''φιλῶ''.<br> '''φιλόγελως, -ωτος (nom commun) (m)''' : Amateur d'histoires drôles.<br> '''φιλόπαις, -δός (nom commun) (m)''' : philopaide.<br> '''φίλος, -η, -ον (adjectif)''' : amical.<br> '''φίλος, -ου (nom commun) (m)''' : ami.<br> '''φιλο- (préfixe)''' : qui aime.<br> '''φιλογυνία, -ας (nom commun) (f)''' : philogynie.<br> '''φιλοπαιδία, -ας (nom commun) (f)''' : philopaidie.<br> '''φιλόπαις, -αίδος (nom commun) (m)''' : philopaide.<br> '''φιλοσοφία, -ας (nom commun) (f)''' : philosophie.<br> '''φιλοσοφικός, -ή, -όν (adjectif)''' : philosophique.<br> '''φιλοσοφικότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''φιλοσοφικός''.<br> '''φιλοσοφικότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''φιλοσοφικός''.<br> '''φιλοσοφικῶς (adverbe)''' : philosophiquement.<br> '''φιλοσοφικώτατα, -, - (adverbe)''' : Superlatif de ''φιλοσοφικῶς''.<br> '''φιλοσοφικώτερον, -, - (adverbe)''' : Comparatif de ''φιλοσοφικῶς''.<br> '''φιλόσοφος, -όφου (nom commun) (m)''' : philosophe.<br> '''φιλοσοφῶ (verbe)''' : philosopher.<br> '''φιλότης, -τος (nom commun) (f)''' : Amitié ; relation sexuelle.<br> '''φιλύρα, -ας (nom commun) (f)''' : tilleul.<br> '''φιλῶ (verbe)''' : Aimer d'amitié. Éprouver de l'amitié. Traiter en ami, regarder comme un ami. Donner un signe d'amitié. Aimer d'amour. (Par extension) Aimer. Voir volontiers, accueillir avec plaisir, approuver, agréer. Rechercher, poursuivre. Se plaire à.<br> '''φίλως ‎(adverbe)''' : amicalement.<br> '''φιμός, -οῦ (nom commun) (m)''' : .<br> '''φίμωσις, -ώσεως (nom commun) (f)''' : musellement.<br> '''φίμωτρον, -ου (nom commun) (m)''' : muselière.<br> '''φιμῶ (verbe)''' : museler.<br> '''φιτύω (verbe)''' : engendrer.<br> '''φλέγμα, -τος (nom commun) (n)''' : flegme.<br> '''φλέγω (verbe)''' : brûler.<br> '''φλέψ, -ϐός (nom commun) (f)''' : veine (vaisseau sanguin).<br> '''φλέω (verbe)''' : sourdre.<br> '''φλίϐω (verbe)''' : étendre, presser.<br> '''φλόγωσις, -ώσεως (nom commun) (m)''' : inflammation.<br> '''φλογῶ (verbe)''' : flamber.<br> '''φλοιός, -οῦ (nom commun) (m)''' : écorce.<br> '''φλόξ, -γός (nom commun) (m)''' : flamme.<br> '''φλύαρος, -ος, -ον (adjectif)''' : bavard.<br> '''φλυαρῶ (verbe)''' : bavarder.<br> '''φλύκταινα, -ίνας (nom commun) (f)''' : cloque.<br> '''φλύζω (verbe)''' : Forme de ''φλύω''.<br> '''φλύω (verbe)''' : couler.<br> '''φοϐερός, -ά, -όν (adjectif)''' : effrayant.<br> '''φόϐος, -ου (nom commun) (m)''' : peur.<br> '''φοῖϐος, -η, -ον (adjectif)''' : .<br> '''φοῖνιξ, -ίνικος (nom commun) (m)''' : palmier-dattier ; phénix.<br> '''φονεύς, -έως (nom commun) (m)''' : meurtrier.<br> '''φονεύω (verbe)''' : assassiner.<br> '''φονικός, -ή, -όν (adjectif)''' : meurtrier.<br> '''φόνος, -ου (nom commun) (m)''' : meurtre.<br> '''φόρημα, -ήματος (nom commun) (n)''' : .<br> '''φόρμιγξ, -γος (nom commun) (f)''' : (poésie) lyre.<br> '''φορτίζω (verbe)''' : charger.<br> '''φόρτισις, -ίσεως (nom commun) (f)''' : charge.<br> '''φόρτος, -ου (nom commun) (m)''' : .<br> '''φοῦκτα, -ύκτας (nom commun) (m)''' : poignée de main.<br> '''φοῦρνος, -ύρνου (nom commun) (m)''' : four.<br> '''φραγή, -ῆς (nom commun) (f)''' : bloc.<br> '''φράγμα, -ατος (nom commun) (n)''' : clôture.<br> '''φραγμός, -οῦ (nom commun) (m)''' : bloc.<br> '''φράν, -ός (nom commun) (f)''' : Forme dorienne de ''φρήν''.<br> '''φράσις, -εως (nom commun) (f)''' : Suite de mots.<br> '''φράσσω (verbe)''' : déclarer.<br> '''φράτηρ, -ερος (nom commun) (m)''' : Membre d'une phratrie.<br> '''φρατήρ, -έρος (nom commun) (m)''' : Forme dorienne de ''φράτηρ''.<br> '''φρατρία, -ας (nom commun) (f)''' : phratrie.<br> '''φρέαρ, -τος (nom commun) (n)''' : puits.<br> '''φρενητικός, -ή, -όν (adjectif)''' : délirant.<br> '''φρενητικῶς (adverbe)''' : -ment.<br> '''φρενητικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''φρενητικός''.<br> '''φρενητικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''φρενητικός''.<br> '''φρενητικώτατα, -, - (adverbe)''' : Superlatif de ''φρενητικῶς''.<br> '''φρενητικώτερον, -, - (adverbe)''' : Comparatif de ''φρενητικῶς''.<br> '''φρενῖτις, -ίτιδος (nom commun) (f)''' : délire.<br> '''φρήν, -ενός (nom commun) (f)''' : Toute membrane qui enveloppe un organe. (Au pluriel) Viscères, entrailles. (Par suite) (Poésie) Cœur, âme.<br> '''φρήτηρ, -ερος (nom commun) (m)''' : Forme ionienne de ''φράτηρ''.<br> '''φρίκη, -ης (nom commun) (f)''' : terreur.<br> '''φρίξ, -ικός (nom commun) (f)''' : terreur.<br> '''φριξός, -ή, -όν (adjectif)''' : terrifiant.<br> '''φρίσσω (verbe)''' : terroriser.<br> '''φρόνημα, -ήματος (nom commun) (n)''' : Intelligence, pensée. Manière de penser.<br> '''φρόνησις, -ήσεως (nom commun) (f)''' : Pensée, dessein. Intelligence raisonnable, sagesse. Intelligence (ou sagesse) divine.<br> '''φρόνιμος, -ος, -ον (adjectif)''' : sensé.<br> '''φρονῶ (verbe)''' : Penser, avoir la faculté de penser ou de sentir, vivre. Être dans son bon sens. Penser. Être sensé. Avoir dans l’esprit. Songer à, projeter de.<br> '''φρουρά, -ᾶς (nom commun) (m)''' : garde (corps d’armée).<br> '''φρουρή, -ῆς (nom commun) (m)''' : Forme ionienne de ''φρουρή''.<br> '''φρούρημα, -ήματος (nom commun) (n)''' : bannissement.<br> '''φρούρησις, -ήσεως (nom commun) (f)''' : fuite, bannissement.<br> '''φρουρητός, -ός, -όν (adjectif)''' : banni.<br> '''φρούριον, -ίου (nom commun) (n)''' : forteresse.<br> '''φρουρός, -οῦ (nom commun) (m)''' : garde (surveillant).<br> '''φρουρῶ (verbe)''' : bannir.<br> '''φρύγω (verbe)''' : rôtir.<br> '''φρῦνος, -ύνου (nom commun) (m)''' : crapaud.<br> '''φυγάς, -δος (nom commun) (m)''' : fugitif.<br> '''φυγή, -ῆς (nom commun) (f)''' : fuite, bannissement.<br> '''φύζω (verbe)''' : Forme ionienne de ''φεύγω''.<br> '''φυίω (verbe)''' : Forme éolienne de ''φύω''.<br> '''φυλακή, -ῆς (nom commun) (f)''' : garde, surveillance ; vigilance.<br> '''φυλακτήριον, -ίου (nom commun) (n)''' : amulette.<br> '''φυλακτήρ, -ῆρος (nom commun) (m)''' : garde.<br> '''φυλάξις, -εως (nom commun) (f)''' : garde.<br> '''φύλαξ, -κος (nom commun) (m)''' : observateur, garde ; protecteur.<br> '''φυλάσσω (verbe)''' : garder.<br> '''φυλάττω (verbe)''' : Forme attique de ''φυλάσσω''.<br> '''φυλετικός, -ή, -όν (adjectif)''' : racial.<br> '''φυλή, -ῆς (nom commun) (f)''' : Tribu, groupe de familles de même races ; (Militaire) Corps de troupes au nombre de 10. (Par extension) Classe, genre ; espèce.<br> '''φύλλον, -ου (nom commun) (n)''' : feuille.<br> '''φυλλόω (verbe)''' : .<br> '''φῦλον, -ύλου (nom commun) (n)''' : groupe, tribu ; nation.<br> '''φῦμα, -ύματος (nom commun) (n)''' : .<br> '''φυμάτιον, -ίου (nom commun) (n)''' : .<br> '''φύραμα, -τος (nom commun) (n)''' : .<br> '''φυράω (verbe)''' : .<br> '''φύρδην (adverbe)''' : .<br> '''φυρατέον, -ου (nom commun) (n)''' : .<br> '''φυρατής, -οῦ (nom commun) (m)''' : .<br> '''φύρμα, -τος (nom commun) (n)''' : .<br> '''φυρμός, -οῦ (nom commun) (m)''' : .<br> '''φύρσιμος, -ίµου (nom commun) (m)''' : .<br> '''φύρσις, -εως (nom commun) (f)''' : .<br> '''φύρω (verbe)''' : .<br> '''φυσσαλίς, -δος (nom commun) (m)''' : bulle.<br> '''φῦσα, -ύσας (nom commun) (f)''' : .<br> '''φυσάω (verbe)''' : .<br> '''φυσητήρ, -ῆρος (nom commun) (m)''' : soupirail.<br> '''φῦσιγξ, -ύσιγγος (nom commun) (m)''' : cartouche.<br> '''φύσις, -εως (nom commun) (f)''' : nature.<br> '''φυσικός, -ή, -όν, (adjectif)''' : naturel.<br> '''φυσικῶς (adverbe)''' : naturellement.<br> '''φυσικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''φυσικός''.<br> '''φυσικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''φυσικός''.<br> '''φυσικώτατα, -, - (adverbe)''' : Superlatif de ''φυσικῶς''.<br> '''φυσικώτερον, -, - (adverbe)''' : Comparatif de ''φυσικῶς''.<br> '''φύσκα, -ας (nom commun) (f)''' : Forme dorienne de ''φύσκη''.<br> '''φύσκη, -ης (nom commun) (f)''' : .<br> '''φύτευμα, -ύματος (nom commun) (n)''' : raiponce.<br> '''φυτεύω (verbe)''' : planter.<br> '''φυτόν, -οῦ (nom commun) (n)''' : végétal, plante.<br> '''φυτο- (préfixe)''' : relatif aux plantes.<br> '''φῦ (interjection)''' : pouah.<br> '''φύω (verbe)''' : croître.<br> '''φώκη, -ης (nom commun) (f)''' : phoque.<br> '''φώκιος, -ος, -ον (adjectif)''' : phocidien.<br> '''φωλεός, -οῦ (nom commun) (m)''' : tanière, terrier.<br> '''φωνήεις, -σσα, -ῆεν (adjectif)''' : vocalique.<br> '''φωνῆεν, -ήεντος (nom commun) (n)''' : voyelle.<br> '''φωνή, -ῆς (nom commun) (f)''' : voix.<br> '''φώνημα, -ήματος (nom commun) (n)''' : phonème.<br> '''φωνητικός, -ή, -όν (adjectif)''' : phonétique.<br> '''φωνητικῶς (adverbe)''' : phonétiquement.<br> '''φωνητικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''φωνητικός''.<br> '''φωνητικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''φωνητικός''.<br> '''φωνῶ (verbe)''' : Faire entendre un son de voix. Parler haut, dire d'une voix forte, élever la voix Ordonner, commander, prescrire. Parler de. Chanter.<br> '''φώς, -τός (nom commun) (m)''' : homme.<br> '''φῶς, -τός (nom commun) (n)''' : lumière, éclair.<br> '''φωσφορίζων, -ουσα, -ον (adjectif)''' : fluorescent.<br> '''φωσφορίζω (verbe)''' : fluorescer.<br> '''φωσφόρος, -ος, -ον (adjectif)''' : qui apporte la lumière.<br> '''Φαέθουσα, -ας (nom propre) (f)''' : Phaéthuse.<br> '''Φαέθων, -οντος (nom propre) (m)''' : Phaéton.<br> '''Φαίδρα, -ας (nom propre) (f)''' : Phèdre.<br> '''Φαῖδρος, -ίδρου (nom propre) (f)''' : Phèdre.<br> '''Φαιδρία, -ας (nom propre) (f)''' : Phédrie.<br> '''Φαμενώθ (nom propre) (m)''' : Phaminoth.<br> '''Φαντασός, -οῦ (nom propre) (m)''' : Phantasos.<br> '''Φάρος, -ου (nom propre) (f)''' : Pharos.<br> '''Φαρμουθί (nom propre) (m)''' : Pharmouti.<br> '''Φασιανός, -οῦ (nom commun) (m)''' : Phasien.<br> '''Φᾶσις, -άσιος (nom propre) (m)''' : Phase.<br> '''Φαῶφι (nom propre) (m)''' : Phaophi.<br> '''Φειδίας, -ου (nom propre) (m)''' : Phidias.<br> '''Φερεκύδης, -ου (nom propre) (m)''' : Phérécyde.<br> '''Φερενίκη, -ης (nom propre) (f)''' : Véronique.<br> '''Φηγεύς, -έως (nom propre) (m)''' : Phégée.<br> '''Φθόνος, -ου (nom propre) (m)''' : [[wikt:Phtonos|Phtonos]].<br> '''Φιλάμμων, -ονος (nom propre) (m)''' : Philammon. (Demi-frère d'Autolycos.)<br> '''Φιλέας, -ου (nom propre) (m)''' : Philéas.<br> '''Φίλιππος, -ίππου (nom propre) (m)''' : Philippe.<br> '''Φιλόγελως, -τος (nom propre) (m)''' : Philogélos. (Recueil d’histoires drôles probablement rédigé au V{{e}} siècle apr. J.-C., attribué à Hiéroclès et Philagrios)<br> '''Φιλοκτήτης, -ου (nom propre) (m)''' : Philoctète.<br> '''Φιλομήλη, -ης (nom propre) (f)''' : Philomèle.<br> '''Φιλότης, -τος (nom propre) (f)''' : [[wikt:Philotès|Philotès]].<br> '''Φίλων, -ος (nom propre) (m)''' : Philo.<br> '''Φιλώτας, -ου (nom propre) (m)''' : Philinte.<br> '''Φινεές, -οῦ (nom propre) (m)''' : Phinées.<br> '''Φινεύς, -έως (nom propre) (m)''' : Phinée.<br> '''Φίξ, -γγός (nom propre) (f)''' : Forme béotienne de ''Σφίγξ''.<br> '''Φλεγέθων, -οντος (nom propre) (m)''' : Phlégéthon.<br> '''Φλεγύας, -ντος (nom propre) (m)''' : Phlégias. (père de Coronis)<br> '''Φλέγων, -ος (nom propre) (m)''' : Phlégon.<br> '''Φοϐητώρ, -όρος (nom propre) (m)''' : Phobétor.<br> '''Φοίϐη, -ης (nom propre) (f)''' : [[wikt:Phœbé|Phœbé]].<br> '''Φοιϐίδας, -ου (nom propre) (m)''' : [[wikt:Phébidas|Phébidas]].<br> '''Φοῖϐος, -ίϐου (nom propre) (m)''' : [[wikt:Phébus|Phébus]].<br> '''Φοῖνιξ, -ίνικος (nom commun) (m/f)''' : Phénicien. Carthaginois. (les descendants de Phénicie.)<br> '''Φόϐος, -ου (nom propre) (m)''' : Phobos.<br> '''Φραόρτης, -ου (nom propre) (m)''' : .<br> '''Φρυγία, -ας (nom propre) (f)''' : Phrygie.<br> '''Φρύξ, -γός (nom commun) (m)''' : Phrygien.<br> '''Φυλεύς, -έως (nom propre) (m)''' : Phylée (fils d’Augias).<br> '''Φυλλίς, -δος (nom propre) (f)''' : Phyllis.<br> '''Φυσίγναθος, -άθου (nom propre) (f)''' : Physignathe.<br> '''Φωκεύς, -έως (nom commun) (m)''' : Phocidien.<br> '''Φώκαια, -ίας (nom propre) (f)''' : Phocée. (Ancienne cité grecque d’Asie Mineure.)<br> '''Φωκαιεύς, -έως (nom commun) (m)''' : Phocéen.<br> '''Φωκαιίς, -δος (nom commun) (f)''' : Phocéenne.<br> '''Φωκίς, -δος (nom propre) (f)''' : Phocide.<br> '''Φῶκος, -ώκου (nom propre) (m)''' : Phocus.<br> '''Φορμίων, -ος (nom propre) (m)''' : Phormion.<br> '''Φωτεινή, -ῆς (nom propre) (f)''' : Photine.<br> ==Χ== '''χαίνω (verbe)''' : .<br> '''χαῖρε (interjection)''' (Devient ''χαίρετε'' au pluriel.) : bonjour ; salut.<br> '''χαίρω (verbe)''' : se réjouir ; être joyeux. Se réjouir d'ordinaire, se plaire d'ordinaire à ou dans. Avoir sujet de se réjouir.<br> '''χάλαζα, -άζης (nom commun) (f)''' : grêle.<br> '''χαλαρός, -ά, -όν (adjectif)''' : détendu.<br> '''χαλαρότης, -τος (nom commun) (f)''' : détente.<br> '''χαλάρωσις, -ώσεως (nom commun) (f)''' : détente.<br> '''χαλαρῶς (adverbe)''' : .<br> '''χαλαρῶ (verbe)''' : détendre.<br> '''χαλάω (verbe)''' : Lâcher, relâcher. Laisser tomber, baisser, rabaisser. Laisser aller. (Au passif) Être adouci. Être indulgent. Céder le passage. Affaiblir.<br> '''χάλασις, -άσεως (nom commun) (f)''' : Relâchement, relaxation.<br> '''χαλεπός, -ή, -όν (adjectif)''' : difficile.<br> '''χαλεπῶς (adverbe)''' : difficilement.<br> '''χαλεπώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''χαλεπός''.<br> '''χαλεπώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''χαλεπός''.<br> '''χάλιξ, -κος (nom commun) (m/f)''' : galet ; gravier.<br> '''χαλκεύς, -έως (nom commun) (m)''' : forgeron.<br> '''χαλκός, -οῦ (nom commun) (m)''' : cuivre ; bronze, fer.<br> '''χαλυϐήϊος, -ΐα, -ήϊον (adjectif)''' : d’acier.<br> '''χάλυψ, -ϐος (nom commun) (m)''' : acier.<br> '''χαμᾶζε (adverbe)''' : à terre (avec mouvement).<br> '''χαμαί (adverbe)''' : à terre (sans mouvement).<br> '''χαμαικέρασος, -άσου (nom commun) (f)''' : fraise.<br> '''χαμαιλέων, -οντος (nom commun) (m)''' : caméléon.<br> '''χαμαίμηλον, -ήλου (nom commun) (f)''' : camomille.<br> '''χαμαιτυπεῖον, -ίου (nom commun) (n)''' : lupanar.<br> '''χαμαιτύπη, -ης (nom commun) (f)''' : prostituée.<br> '''χάν, -ός (nom commun) (m/f)''' : Forme dorienne de ''χήν''.<br> '''χάος, -ους (nom commun) (n)''' : chaos.<br> '''χαρά, -ᾶς (nom commun) (f)''' : joie ; plaisir.<br> '''χαρακτηρίζω (verbe)''' : inscrire, marquer.<br> '''χαρακτήρ, -ῆρος (nom commun) (m)''' : Fer pour marquer le bétail, marque faite au fer rouge. Marque, signe, empreinte, stigmate. Cachet, caractère, genre de style, style.<br> '''χαράσσω (verbe)''' : Aiguiser. Gratter, couper.<br> '''χάραξ, -κος (nom commun) (m)''' : pieu.<br> '''χαριέντως (adverbe)''' : gracieusement.<br> '''χαρίεις, -εσσα, -εν (adjectif)''' : gracieux.<br> '''χαρίϝεις, -εσσα, -εν (adjectif)''' : Forme homérique de ''χαρίεις''.<br> '''χαριέστατος, -άτη, -έστατον (adjectif)''' : Superlatif de ''χαρίεις''.<br> '''χαριέστερος, -έρα, -ερον (adjectif)''' : Comparatif de ''χαρίεις''.<br> '''χαρίϝεττα, -, - (adjectif)''' : Forme béotienne de ''χαρίεις''.<br> '''χαρίζομαι (verbe)''' : .<br> '''χάρις, -τος (nom commun) (f)''' : Ce qui brille ; ce qui réjouit. Grâce.<br> '''χάρισμα, -ίσματος (nom commun) (n)''' : grâce accordée par Dieu.<br> '''χαριτῶ (verbe)''' : .<br> '''χάρμα, -τος (nom commun) (n)''' : source de joie, délice.<br> '''χάσμα, -τος (nom commun) (n)''' : béance, ouverture ; creux, gouffre. Abysse.<br> '''χάσκω (verbe)''' : bayer, béer.<br> '''χαῦνος, -ύνη, -ῦνον (adjectif)''' : .<br> '''χαυνότης, -τος (suffixe) (f)''' : .<br> '''χαυνῶ (verbe)''' : .<br> '''χέζω (verbe)''' : chier.<br> '''χεῖμα, -ίματος (nom commun) (n)''' : hiver.<br> '''χείμαρρος, -άρρου (nom commun) (m)''' : torrent.<br> '''χειμών, -ῶνος (nom commun) (m)''' : (sens propre) Mauvais temps. (sens figuré) Trouble.<br> '''χειραφέτησις, -ήσεως (nom commun) (f)''' : émancipation.<br> '''χείριστος, -ίστη, -ίριστον (adjectif)''' : Superlatif de ''κακός''.<br> '''χείρ, -ός (nom commun) (f)''' : main.<br> '''χειρόγραφον, -άφου (nom commun) (n)''' : manuscrit.<br> '''χειρόγραφος, -η, -ον (adjectif)''' : manuscrit.<br> '''χείρων, -ων, -ῖρον (adjectif)''' : Comparatif de ''κακός''.<br> '''χελιδών, -ονός (nom commun) (f)''' : hirondelle.<br> '''χελώνη, -ης (nom commun) (f)''' : tortue.<br> '''χερνίϐιον, -ίου (nom commun) (n)''' : pot de chambre.<br> '''χερσόνησος, -ήσου (nom commun) (f)''' : péninsule.<br> '''χέρσος, -ος, -ον (adjectif)''' : sec ; stérile.<br> '''χέω (verbe)''' : jouir. (Profiter d'une chose que l'on possède.)<br> '''χηλή, -ῆς (nom commun) (f)''' : pince ; serre de certains animaux.<br> '''χηλός, -οῦ (nom commun) (m)''' : coffre.<br> '''χήν, -ός (nom commun) (m/f)''' : jars ; oie.<br> '''χήρα, -ας (nom commun) (f)''' : veuve.<br> '''χῆρος, -ήρου (nom commun) (m)''' : veuf.<br> '''χθές (adverbe)''' : hier.<br> '''χθόνιος, -α, -ον (adjectif)''' : Relatif aux divinités infernales.<br> '''χθών, -ονός (nom commun) (f)''' : Sol, terre. Terre, pays, contrée. Ensemble du sol terrestre, terre entière. Terre comme séjour des vivants et des morts.<br> '''χῖ (nom commun) (n)''' : chi.<br> '''χίλιοι (adjectif numéral)''' : mille.<br> '''χιόνεος, -έα, -εον (verbe)''' : enneigé.<br> '''χιονίζω (verbe)''' : enneiger.<br> '''χιονόχρως (adjectif)''' : blanc comme neige.<br> '''χιτών, -ῶνος (nom commun) (m)''' : chiton.<br> '''χιών, -όνος (nom commun) (f)''' : neige.<br> '''χλαμύς, -δος (nom commun) (n)''' : chlamyde.<br> '''χλευάζω (verbe)''' : se moquer.<br> '''χλευασία, -ας (nom commun) (f)''' : moquerie.<br> '''χλευασμός, -οῦ (nom commun) (m)''' : Moquerie ; blague.<br> '''χλιαρός, -ή, -όν (adjectif)''' : tiède.<br> '''χλωμός -ή -όν (adjectif)''' : pâle.<br> '''χλωρός, -ά, -όν (adjectif)''' : Vert ; jaune verdâtre.<br> '''χοῖρος, -ίρου (nom commun) (m)''' : Petit cochon. (Par extension) Cochon engraissé, porc.<br> '''χόνδρος, -ου (nom commun) (m)''' : Petit corps dur et rond, grain. Grain de froment et d’épeautre. Froment, épeautre. Cartilage.<br> '''χονδρός, -ά, -όν (adjectif)''' : gros.<br> '''χονδρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''χονδρός''.<br> '''χονδρότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''χονδρός''.<br> '''χονδρύνω (verbe)''' : grossir.<br> '''χονδρῶς (adverbe)''' : .<br> '''χοραύλης, -ου (nom commun) (m)''' : choraule.<br> '''χοραυλικός, -ή, -όν (adjectif)''' : choraulique.<br> '''χορδή, -ῆς (nom commun) (f)''' : ficelle.<br> '''χορεία, -ας (nom commun) (f)''' : danse.<br> '''χορεῖος, -ίου (nom commun) (m)''' : chorée.<br> '''χορευτής, -οῦ (nom commun) (m)''' : danseur.<br> '''χορεύω (verbe)''' : danser.<br> '''χορήγιον, -ίου (nom commun) (m)''' : chorégie.<br> '''χορηγός, -οῦ (nom commun) (m)''' : chorège.<br> '''χορικός, -ή, -όν (adjectif)''' : chorique.<br> '''χοροκιθαριστής, -οῦ (nom commun) (m)''' : chorocithariste.<br> '''χορός, -οῦ (nom commun) (m)''' : danse en ronde.<br> '''χόρτος, -ου (nom commun) (m)''' : Enclos. Pré clôturé ; pâturage. Nourriture.<br> '''χορῳδία, -ας (nom commun) (f)''' : .<br> '''χράω (verbe)''' : Frapper, attaquer. Infliger, asséner. Désirer ardemment. Proclamer. (Au passif) Être déclaré par un oracle. (Voix moyenne) Consulter un oracle, être averti par un oracle. Fournir, prêter. Utiliser. Avoir besoin de.<br> '''χρεία, -ας (nom commun) (f)''' : Usage, emploi. Manière dont on fait usage. Profit qu'on retire d'un usage. Besoin, nécessité.<br> '''χρείη, -ης (nom commun) (f)''' : Forme ionienne de ''χρεία''.<br> '''χρεώ (verbe)''' : avoir besoin.<br> '''χρῄζω (verbe)''' : nécessiter, désirer ; vouloir.<br> '''χρή (verbe)''' : il faut.<br> '''χρῆμα, -ήματος (nom commun) (n)''' : Chose dont on se sert, ou dont on a besoin. (Au singulier) Ce dont on se sert, chose, affaire. Évènement, occurrence. (Au pluriel) Bien, avoir.<br> '''χρῆσις, -ήσεως (nom commun) (f)''' : .<br> '''χρησμός, -οῦ (nom commun) (f)''' : oracle.<br> '''χρηστομάθεια, -ίας (nom commun) (f)''' : savoir utile.<br> '''χρηστός, -ή -όν (adjectif)''' : Dont on peut se servir. Qui rend service.<br> '''χρηστότης, -τος (nom commun) (f)''' : Bonne qualité, bonté. (En particulier) Bonté de cœur.<br> '''χρίζω (verbe)''' : oindre.<br> '''χρῖσμα, -ίσματος (nom commun) (n)''' : onction.<br> '''χρονικός, -ή -όν (adjectif)''' : temporel.<br> '''χρονικῶς (adverbe)''' : temporellement.<br> '''χρονικώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''χρονικός''.<br> '''χρονικώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''χρονικός''.<br> '''χρόνιος, -ία -όνιον (adjectif)''' : tardif.<br> '''χρονίως (adverbe)''' : tardivement.<br> '''χρονιώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''χρονίως''.<br> '''χρονιώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''χρονίως''.<br> '''χρόνος, -ου (nom commun) (m)''' : temps (durée).<br> '''χρυσαίετος, -ου (nom commun) (m)''' : aigle royal.<br> '''χρυσάνθεμον, -έμου (nom commun) (n)''' : chrysanthème.<br> '''χρυσόγονον, -όνου (nom commun) (n)''' : navet noir.<br> '''χρυσομηλιά, -ᾶς (nom commun) (f)''' : orange.<br> '''χρυσός, -οῦ (nom commun) (m)''' : or.<br> '''χρῶμα, -ώματος (nom commun) (n)''' : couleur.<br> '''χυδαῖος, -ίη ,-ῖον (adjectif)''' : s’affaissant ; commun. Vulgaire.<br> '''χυδαιολογία, -ας (nom commun) (f)''' : .<br> '''χυλός, οῦ (nom commun) (m)''' : gruau.<br> '''χυλοπίτα, -ας (nom commun) (f)''' : .<br> '''χυλώδης, -ης, -ες (adjectif)''' : .<br> '''χύλωμα, -τος (nom commun) (n)''' : .<br> '''χυλώνω (verbe)''' : .<br> '''χύμα, -τος (nom commun) (n)''' : suc.<br> '''χυμεία, -ας (nom commun) (f)''' : .<br> '''χυµός, -οῦ (nom commun) (m)''' : jus.<br> '''χωλαίνω (verbe)''' : boiter.<br> '''χωλίαμϐος, -άμϐου (nom commun) (m)''' : choliambe.<br> '''χωλός, -ή, -όν (adjectif)''' : boiteux. (En parlant de l'intelligence) Dont l'esprit cloche, infirme d'esprit. Mal équilibré, instable, chancelant.(Rhétorique) Boiteux. (Métrique) Qui n'est pas sur ses pieds, boiteux.<br> '''χωλότης, -τος (nom commun) (f)''' : .<br> '''χωλῶς (adverbe)''' : en boitant.<br> '''χωλότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''χωλός''.<br> '''χωλότερος, -έρα, -ότερον (adjectif)''' : Comparatif de ''χωλός''.<br> '''χῶμα, -ώματος (nom commun) (n)''' : (Militaire) Terrassement. (Par extension) Toute jetée, même en pierres, môle.<br> '''κώμη, -ης (nom commun) (f)''' : village.<br> '''χώρα, -ας (nom commun) (f)''' : Lieu. Place, endroit. (Militaire) Poste, position. (Au sens abstrait) Moment. Pays, région. Campagne. Champ, ferme.<br> '''χώρη, -ης (nom commun) (f)''' : Forme ionienne de ''χώρα''.<br> '''χωρίζω (verbe)''' : séparer.<br> '''χωρίον, -ου (nom commun) (n)''' : district.<br> '''χωρισμός, -οῦ (nom commun) (m)''' : séparation.<br> '''χωρίς (adverbe)''' : Séparément ; à part. (Avec le génitif) sans. (Par suite) différemment.<br> '''Χαιρέας, -ου (nom propre) (m)''' : Chéréas.<br> '''Χαιρεφῶν, -ῶντος (nom propre) (m)''' : Chariphon.<br> '''Χαιρώνεια, -ίας (nom propre) (f)''' : Chéronée (cité de Béotie).<br> '''Χαιρωνεύς, -έως (nom propre) (m)''' : Chéronéen.<br> '''Χαλδαία, -ας (nom propre) (f)''' : Chaldée.<br> '''Χαλδαῖα, -ίας (nom commun) (f)''' : Chaldéenne.<br> '''Χαλδαϊκός, -ή, -όν (adjectif)''' : chaldéen.<br> '''Χαλδαῖος, -ίου (nom commun) (m)''' : Chaldéen.<br> '''Χαλκηδών, -όνος (nom commun) (f)''' : Chalcédoine.<br> '''Χαλκίς, -δος (nom commun) (f)''' Chalcis.<br> '''Χάλυψ, -ϐος (nom propre) (m)''' : Chalybe.<br> '''Χαπύ (nom propre) (m)''' : Hâpy.<br> '''Χάρις, -τος (nom propre) (f)''' : Charite.<br> '''Χαρίτων, -ος (nom propre) (m)''' : Chariton.<br> '''Χάρυϐδις, -ύϐδεως (nom propre) (f)''' : Charybde.<br> '''Χάρων, -ος (nom propre) (m)''' : Charon. (nocher des Enfers)<br> '''Χέϐρης, -ου (nom propre) (m)''' : Toutânkhamon.<br> '''Χείρων, -ος (nom propre) (m)''' : Chiron.<br> '''Χένερης, -ου (nom propre) (m)''' : Khâsekhemoui.<br> '''Χέοψ, -πος (nom propre) (m)''' : Khéops.<br> '''Χεφρήν, -ένος (nom propre) (m)''' : Khéphren.<br> '''Χθών, -ονός (nom propre) (f)''' : Chthon.<br> '''Χιόνη, -ης (nom propre) (f)''' : Chioné.<br> '''Χλόη, -ης (nom propre) (f)''' : Chloé.<br> '''Χλωρίς, -δος (nom propre) (f)''' : Chloris (nymphe).<br> '''Χνοῦϐις, -ύϐιδος (nom propre) (m)''' : [[wikt:Khnoum|Khnoum]].<br> '''Χοίακ (nom propre) (m)''' : Choeac.<br> ‎ '''Χοσρόης, -ου (nom propre) (m)''' : Chosroès.<br> ‎ '''Χριστόφορος, -όρου (prénom) (m)''' : Christophe.<br> '''Χριστός, -οῦ (nom commun) (m)''' : Christ.<br> '''Χρυσάωρ, -ου (nom propre) (m)''' : Chrysaor.<br> '''Χρύσιππος, -ίππου (nom propre) (m)''' : Chrysippe.<br> '''Χρυσόμαλλον Δέρας (locution nominale)''' : Toison d'or.<br> '''Χρυσόμαλλος, -ου (nom propre) (m)''' : Chrysomallos.<br> '''Χρυσόπολις, -όλεως (nom propre) (m)''' : Üsküdar.<br> ==Ψ== '''ψάλλω (verbe)''' : chanter.<br> '''ψαλμός, -οῦ (nom commun) (m)''' : psaume.<br> '''ψαλτήριον, -ίου (nom commun) (n)''' : psaltérion.<br> '''ψάλτιγξ, -γος (nom commun) (m)''' : psaltinx.<br> '''ψάρ, -ός (nom commun) (m)''' : étourneau.<br> '''ψαρός, -ά, -όν (adjectif)''' : .<br> '''ψαῦμα, -ύματος (nom commun) (n)''' : palpation.<br> '''ψαῦσις, -ύσεως (nom commun) (f)''' : palpation.<br> '''ψαύω (verbe)''' : palper.<br> '''ψᾶφαξ, -άφακου (nom commun) (m)''' : Forme éolienne de ''ψῆφος''.<br> '''ψᾶφος, -άφου (nom commun) (m)''' : Forme dorienne de ''ψῆφος''.<br> '''ψάω (verbe)''' : Frotter, gratter.<br> '''ψέγω (verbe)''' : Blâmer, reprocher.<br> '''ψευδής, -ής, -ές (adjectif)''' : faux.<br> '''ψεύδομαι (verbe)''' : mentir.<br> '''ψεῦδος, -ύδους (nom commun) (n)''' : tromperie.<br> '''ψευδῶς (adverbe)''' : faussement.<br> '''ψευδώτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ψευδής''.<br> '''ψευδώτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ψευδής''.<br> '''ψεύδω (verbe)''' : tromper.<br> '''ψεῦσμα, -ύσματος (nom commun) (n)''' : mensonge.<br> '''ψεύστης, -ου (nom commun) (m)''' : menteur.<br> '''ψεύστρα, -ας (nom commun) (f)''' : menteuse.<br> '''ψῆγμα, -ήγματος (nom commun) (n)''' : pépite.<br> '''ψηλάφησις, -ήσεως (nom commun) (f)''' : palpation.<br> '''ψηλαφῶ (verbe)''' : palper.<br> '''ψήρ, -ός (nom commun) (m)''' : Forme ionienne de ''ψάρ''.<br> '''ψῆφος, -ήφου (nom commun) (m)''' : Galet, caillou, pierre, en particulier utilisée pour le calcul. Gemme, pierre précieuse.<br> '''ψήχω (verbe)''' : racler.<br> '''ψῖ (nom commun) (n)''' : psi.<br> '''ψιλός, -ή, -όν (adjectif)''' : Nu ; simple.<br> '''ψίξ, -χός (nom commun) (m/f)''' : Mie ; miette.<br> '''ψιττακός, -οῦ (nom commun) (m)''' : perroquet.<br> '''ψιχίον, -ου (nom commun) (n)''' : miette.<br> '''ψίω (verbe)''' : .<br> '''ψόα, -ας (nom commun) (f)''' : lombes.<br> '''ψόγος, -ου (nom commun) (m)''' : Blâme, reproche.<br> '''ψόλος, -ου (nom commun) (m)''' : suie.<br> '''ψό (interjection)''' : beurk.<br> '''ψυχεινός, -ή, -όν (adjectif)''' : frais.<br> '''ψυχή, -ῆς (nom commun) (f)''' : Âme ; papillon.<br> '''ψύθος, -ους (nom commun) (n)''' : Forme homérique de ''ψεῦδος''.<br> '''ψυχοπομπός, -ός, -όν (adjectif)''' : psychopompe.<br> '''ψυχοπομπός, -οῦ (nom commun) (m)''' : psychopompe.<br> '''ψῦχος, -ύχους (nom commun) (n)''' : fraîcheur.<br> '''ψυχραίνω (verbe)''' : refroidir.<br> '''ψυχρός, -ά, -όν (adjectif)''' : Froid ; glacial.<br> '''ψυχρότατος, -άτη, -ότατον (adjectif)''' : Superlatif de ''ψυχρός''.<br> '''ψυχρότερος, -έρη, -ότερον (adjectif)''' : Comparatif de ''ψυχρός''.<br> '''ψυχρῶς (adverbe)''' : Froidement ; glacialement.<br> '''ψύχω (verbe)''' : Souffler, respirer. Se refroidir.<br> '''ψχέντ (nom commun) (m)''' : pschent.<br> '''ψωμός, -οῦ (nom commun) (m)''' : bouchée de pain.<br> '''Ψαπφώ, -οῦς (nom propre) (f)''' : Forme éolienne de ''Σαπφώ''.<br> '''Ψίλαξ, -κος (nom propre) (m)''' : Psilax.<br> '''Ψιχάρπαξ, -γος (nom propre) (m)''' : Psicharpax.<br> '''Ψουσέννης, -ου (nom propre) (m)''' : Psousennès.<br> '''Ψυχή, -ῆς (nom propre) (f)''' : Psyché.<br> '''Ψωφίς, -δος (nom propre) (f)''' : Psophis.<br> ==Ω== '''ᾠδή, -ῆς (nom commun) (f)''' : chant.<br> '''ὠδυσάμην, - ()''' : .<br> '''ὠθῶ (verbe)''' : pousser, forcer ; (militaire) repousser l’ennemi.<br> '''ὠκεανός, -οῦ (nom commun) (m)''' : océan.<br> '''ὠκέως (adverbe)''' : rapidement.<br> '''ὠκύς, -εῖα, -ύ (adjectif)''' : rapide.<br> '''ὠκύτατος, -άτη, -ώτατον (adjectif)''' : Superlatif de ''ὠκύς''.<br> '''ὠκύτερος, -έρα, -ώτερον (adjectif)''' : Comparatif de ''ὠκύς''.<br> '''ὦλαξ, ὤλακος (nom commun) (m)''' : Forme dorienne de ''αὖλαξ''.<br> '''ὠλένη, -ης (nom commun) (f)''' : coude, coudée ; avant-bras.<br> '''ὠμοπλάτη, -ης (nom commun) (f)''' : omoplate.<br> '''ὦμος, ὤμου (nom commun) (m)''' : épaule.<br> '''ὠνέομαι (verbe)''' : acheter.<br> '''ὠνητής, -οῦ (nom commun) (m)''' : client.<br> '''ὦνος, ὤνου (nom commun) (m)''' : prix.<br> '''ᾠόν, -οῦ (nom commun) (n)''' : œuf.<br> '''ὦ μέγα (nom commun) (n)''' : oméga.<br> '''ὤρα, -ας (nom commun) (f)''' : soin ; souci.<br> '''ὥρα, -ας (nom commun) (f)''' : heure.<br> '''ὡραῖος, -ία, -ῖον (adjectif)''' : Qui est de la saison. Qui se fait à une époque, dans une saison déterminée. Qui est dans la fleur de l’âge.<br> '''ὠρανός, -οῦ (nom commun) (m)''' : Forme dorienne et béotienne de ''οὐρανός''.<br> '''ὡρεῖον‎, -ίου (nom commun) (n)''' : grenier.<br> '''ὤρη, -ης (nom commun) (f)''' : Forme ionienne de ''ὤρα''.<br> '''ὥρη, -ης (nom commun) (f)''' : Forme ionienne de ''ὥρα''.<br> '''ὥριμος, -ος, -ον (adjectif)''' : mûr.<br> '''ὡρολόγιον, -ίου (nom commun) (n)''' : horloge.<br> '''ὡσαννά (interjection)''' : hosanna.<br> '''ὦσις, ὤσεως (nom commun) (f)''' : poussée.<br> '''ὦς, -τός (nom commun) (n)''' : Forme dorienne de ''οὖς''.<br> '''ὡς (adverbe ; conjonction)''' : .<br> '''ὥτερος, -έρα, -ερον (adjectif)''' : Autre forme dorienne de ''ἕτερος''.<br> '''ὠτικός, -ή, -όν (adjectif)''' : otique.<br> '''ὠτίον, -ίου (nom commun) (n)''' : Diminutif de '' οὖς''.<br> '''ὠτίς, -δος (nom commun) (f)''' : outarde.<br> '''ὦτος, ὤτου (nom commun) (m)''' : hibou.<br> '''ὠφέλεια, -ίας (nom commun) (f)''' : Aide ; secours.<br> '''ὠφέλημα, -ήματος (nom commun) (n)''' : .<br> '''ὠφέλησις, -ήσεως (nom commun) (f)''' : Aide ; secours.<br> '''ὠφελῶ (verbe)''' : Aider ; secourir.<br> '''ὠχρός, -ά, -όν (adjectif)''' : pâle.<br> '''ὤψ, -πός (nom commun) (f)''' : Vue ; visage.<br> '''ὦ (particule)''' : ô.<br> '''ὤ (interjection)''' : ah !, oh !<br> '''Ὠγυγία, -ας (nom propre) (f)''' : Ogygie.<br> '''Ὠγυγίη, -ης (nom propre) (f)''' : Forme ionienne de ''Ὠγυγία''.<br> '''Ὠκεανίς, -δος (nom propre) (f)''' : Océanide.<br> '''Ὠκεανός, -οῦ (nom propre) (m)''' : Océan.<br> '''Ὠρανός, -οῦ (nom propre) (m)''' : Forme dorienne et béotienne de ''Οὐρανός''.<br> '''Ὠρείθυια, -ίας (nom commun) (f)''' : Orithye (fille d'Érechthée).<br> '''Ὠριγένης, -ου (nom propre) (m)''' : Origène.<br> '''Ὠρομέδων, -οντος (nom propre) (m)''' : Oromédon.<br> '''Ὧρος, Ὥρου (nom propre) (m)''' : [[wikt:Horus|Horus]].<br> siulqlif69ryizp1rgd5pq4jzzvhl65 Livre de cuisine/Spritz 0 34367 744182 710312 2025-06-05T21:19:36Z Ptyx 24987 relu 744182 wikitext text/x-wiki {{livre de cuisine}} [[File:Spritz canelle.jpg|thumb|Spritz et ancien ustensile permettant de les façonner]] Les '''spritz''' ou '''sprits''' sont de petits gâteaux traditionnellement préparés au moment de Noël en Alsace, en Moselle et en Allemagne. == Ingrédients == * 500 g de {{i|farine}} ; * 250 g de {{i|sucre}} ; * 250 g de {{i|beurre}} ; * 2 [[w:œuf (cuisine)|œuf]]s ; * 125 g de d’amandes moulues ou de la {{i|noix de coco}} râpée. == Préparation == # Mélanger le beurre fondu avec le sucre, puis ajouter les œufs entiers. # Incorporer ensuite la farine et enfin des amandes moulues ou de la noix de coco. # Faire une boule de pâte et la laisser reposer une heure. # Si on préfère, à la place des amandes moulues ou de la {{i|noix de coco}} râpée, on peut utiliser de la cannelle. Dans ce cas, il faut utiliser une cuillère à café bombée de {{i|cannelle}} et ajouter 75 grammes de farine et 50 grammes de sucre. # Former de longues bandes de pâte d'une trentaine de centimètres de long. Pour cela, il faut se servir d'un hachoir à viande électrique ou à manivelle, muni d'un embout à la forme des spritz (ou une poche à douille, mais c'est moins pratique). # Répartir ces formes sur une tôle à pâtisserie. Il est possible de les serrer, car les spritz ne gonflent quasiment pas. # Cuire 20 minutes à 180°C et laisser refroidir dans une boîte en métal ouverte. Une fois enfermés dans la boîte, les gâteaux peuvent se conserver toute une année. '''Attention :''' il faut absolument enlever les gâteaux de la tôle lorsqu'ils sont encore chaud, car sinon ils vont coller. == Conservation == Ils peuvent se conserver plusieurs mois (voir une année) en les gardant dans une boîte métallique. Mettre un morceau de sucre dans la boîte métallique. [[Catégorie:Desserts|Spritz]] [[Catégorie:Recettes de Noël]] [[Catégorie:Recettes végétariennes|Spritz]] gmwudywdo29r126o3igg3gt2td1co4v Astrologie/Préliminaires astronomiques/La mesure du temps/Le temps stellaire et le temps sidéral 0 55241 744064 415014 2025-06-03T18:56:24Z Kad'Astres 30330 744064 wikitext text/x-wiki {{SI|refonte totale}} temps stellaire // culmination d'une étoile de référence temps sidéral // culmination du point vernal (assimilé à une étoile) [[Catégorie:Astrologie]] czwztj0zp5smgorjasyvvl9iw44sq1y 744074 744064 2025-06-03T19:14:46Z Kad'Astres 30330 744074 wikitext text/x-wiki {{SI|refonte totale}} ehonxiv34l7r9zetnh7ih45v7soi8vy Astrologie/Préliminaires astronomiques/La mesure du temps/Le jour sidéral et le jour solaire vrai 0 55242 744065 415013 2025-06-03T18:57:21Z Kad'Astres 30330 744065 wikitext text/x-wiki {{SI|refonte totale}} jour sidéral // temps requis pour revenir à angle droit d'une étoile jour solaire vrai : prise en compte du Soleil comme une étoile particulière [[Catégorie:Astrologie]] idpyez2k0r7rciogenbwkhtq418jq3p 744073 744065 2025-06-03T19:14:23Z Kad'Astres 30330 744073 wikitext text/x-wiki {{SI|refonte totale}} ehonxiv34l7r9zetnh7ih45v7soi8vy Astrologie/Préliminaires astronomiques/La mesure du temps/Le jour solaire moyen et l'équation du temps 0 55243 744066 743751 2025-06-03T18:58:12Z Kad'Astres 30330 744066 wikitext text/x-wiki {{SI|refonte totale}} jour solaire moyen: prise en compte d'un Soleil fictif (à marche régulière) équation du temps : passage du temps du Soleil moyen (celui de nos horloges, avec une marche régulière de 24 heures) au temps des cadrans solaires (celui mesuré par la position réelle du Soleil dans le ciel : temps solaire vrai), et réciproquement. [[Catégorie:Astrologie]] 1bnjbfbyjkrrr9vk6uj4kdw4zdfxsfu 744072 744066 2025-06-03T19:14:00Z Kad'Astres 30330 Contenu remplacé par « {{SI|refonte totale}} » 744072 wikitext text/x-wiki {{SI|refonte totale}} ehonxiv34l7r9zetnh7ih45v7soi8vy Fonctionnement d'un ordinateur 0 65764 744155 727979 2025-06-05T13:50:39Z Mewtow 31375 /* Liens divers */ 744155 wikitext text/x-wiki {{Page de garde|image=Personal computer, exploded 6.svg|description= Dans ce cours, vous allez apprendre quels sont les composants d'un ordinateur et comment ceux-ci fonctionnent. Ce cours commencera par des choses simples, comme le binaire, pour arriver progressivement jusqu'au fonctionnement des derniers processeurs, en passant par plein de choses passionnantes comme l'assembleur, les mémoires caches, etc. Ce cours est accessible à n'importe qui, sans prérequis, mais se veut cependant assez complet et riche en informations. |avancement=Terminé |cdu= * {{CDU item|6/68/681|681.3/681.31}} |versions= {{version imprimable|page=Fonctionnement d'un ordinateur/Version imprimable 2}} {{version PDF}} }} __NOTOC__ : '''L'auteur du livre tient à remercier vivement Dominus Carnufex et Vayel, qui se sont chargés de la relecture et de la correction orthographique d'une ancienne version de ce cours. Merci à eux pour le travail titanesque qui a été fourni.''' {{/Sommaire}} ==Liens vers ressources externes== ===Sur wikilivres=== * [[Les cartes graphiques|Les cartes graphiques]], un livre du même auteur qui aborde spécifiquement l'architecture des cartes vidéo. * [[Monter_un_PC|Monter un PC]], pour une approche bien plus pratique et utile. * [[Les systèmes d'exploitation|Les systèmes d'exploitation]], un cours qui explique l'interaction entre systèmes d'exploitation et matériel. Le sujet (les systèmes d'exploitation) est si lié au matériel informatique qu'il peut être vu comme un prolongement du présent cours, ou tout du moins comme un très bon complément. * [[Électronique numérique : logique|Électronique numérique : logique]], un cours d'électronique numérique, disponible sur Wikilivre. Un excellent complément pour les premiers chapitres du cours. ===Liens divers=== * [http://users.ece.cmu.edu/~koopman/stack_computers/index.html Stack Computers: the new wave] : un livre sur les architectures à pile. * [https://homes.cs.washington.edu/~levy/capabook/ Capability-Based Computer Systems] : un livre sur les architectures à capacités. * [http://www.analogmuseum.org/english/ Museum of analog computing]. Ce site en anglais parle d'un sujet qui n'a pas été abordé dans ce livre : les calculateurs analogiques. * [https://www.icsa.inf.ed.ac.uk/research/groups/hase/models/ Des simulateurs pour des architectures réelles ou fictives.] {{AutoCat}} [[Catégorie:Informatique]] [[Catégorie:Électronique]] kn44yolhq0v9e6gtl6rxrrwfu6rguk6 Fonctionnement d'un ordinateur/La carte mère, chipset et BIOS 0 65773 744186 738688 2025-06-06T00:16:53Z Mewtow 31375 /* Le Management Engine d'Intel et l'AMD Platform Security Processor */ 744186 wikitext text/x-wiki Dans un ordinateur, les composants sont placés sur un circuit imprimé (la '''carte mère'''), un circuit sur lequel on vient connecter les différents composants d'un ordinateur, et qui les relie via divers bus. Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. Une observation plus poussée de la carte mère vous permettra de remarquer quelques puces électroniques soudées à la carte mère. Elles ont des fonctions très diverses mais sont indispensables à son bon fonctionnement. Un bon exemple est celui du '''circuit d'alimentation''', qui est en charge de la gestion de la tension d'alimentation. Il contient des composants aux noms à coucher dehors pour qui n'est pas électronicien : régulateurs de tension, convertisseurs alternatif vers continu, condensateurs de découplage, et autres joyeusetés. Il y a aussi le BIOS, des générateurs de fréquence, des circuits support pour le processeur et les mémoires, et d'autres, que nous détaillerons dans la suite du chapitre. Enfin, et surtout, une carte mère est là où se trouvent les bus qui interconnectent tout ce beau monde. Si vous observez la carte mère de près, vous verrez des lignes métalliques, de couleur cuivre, qui ne sont autre que les bus en question. Une ligne métallique est un fil qui transmet un courant électrique, qui sert à faire passer un bit d'un composant/connecteur à un autre. L'organisation de ce chapitre est la suivante : nous allons d'abord voir les circuits soudés sur la carte mère, avant de parler de la manière dont les bus sont organisés sur la carte mère. À la fin de ce chapitre, nous allons voir que la façon dont les composants sont connectés entre eux par des bus a beaucoup changé au fil du temps et que l'organisation de la carte mère a évoluée au fil du temps. Les cartes mères se sont d'abord complexifiées, pour faire face à l'intégration de plus en plus de périphériques et de connecteurs. Mais par la suite, les processeurs ayant de plus en plus de transistors, ils ont incorporé des composants autrefois présents sur la carte mère, comme le contrôleur mémoire. ==Le Firmware : BIOS et UEFI== La plupart des ordinateurs contiennent une mémoire ROM qui lui permet de fonctionner. Les plus simples stockent le programme à exécuter dans cette ROM, et n'utilisent pas de mémoire de masse. On pourrait citer le cas des appareils photographiques numériques, qui stockent le programme à exécuter dans la ROM. D'autres utilisent cette ROM pour amorcer le système d'exploitation : la ROM contient le programme qui initialise les circuits de l'ordinateur, puis exécute un mini programme qui démarre le système d'exploitation (OS). Cette ROM, et par extension le programme qu'elle contient, est appelée le '''firmware'''. Le firmware est placé sur la carte mère, du moins sur les ordinateurs qui ont une carte mère. Sur les PC modernes, ce firmware s'occupe du démarrage de l'ordinateur et notamment du lancement de l'OS. Il existe quelques standards de firmware, utilisés sur les ordinateurs PC, utilisés pour garantir la compatibilité entre ordinateurs, leur permettre d'accepter divers OS, et ainsi de suite. Il existe deux standards : le BIOS, format ancien pour le firmware qui a eu son heure de gloire, et l'EFI ou UEFI, utilisés sur les ordinateurs récents. ===Le BIOS, l'EFI et l'UEFI=== Sur les PC avec un processeur x86, il existe un programme, lancé automatiquement lors du démarrage, qui se charge du démarrage avant de rendre la main au système d'exploitation. Ce programme s'appelle le '''BIOS système''', communément appelé BIOS (''Basic Input-Output System''). Ce programme est mémorisé dans de la mémoire EEPROM, ce qui permet de mettre à jour le programme de démarrage : on appelle cela flasher le BIOS. De nos jours, il tend à être remplacé par l'EFI et l'UEFI, qui utilise un standard différent, mais n'est pas différent dans les grandes lignes. L'EFI (Extensible Firmware Interface) est un nouveau standard de firmware, similaire au BIOS, mais plus récent et plus adapté aux ordinateurs modernes. Le BIOS avait en effet quelques limitations, notamment le fait que la table des partitions utilisée par le BIOS ne permettait pas de gérer des partitions de plus de 2,1 téraoctets. De plus, le BIOS devait gérer les anciens modes d'adressage mémoire des PC x86 : mémoire étendue, haute, conventionnelle, ce qui forçait le BIOS à utiliser des registres 16 bits lors de l’amorçage, ainsi qu'un ancien jeu d'instruction aujourd’hui obsolète. L'EFI a été conçu sans ces limitations, lui permettant d'utiliser tout l'espace d'adressage 64 bits, et sans limitations de taille de partition. Les normes de l'EFI et de l'UEFI (une version plus récente) vont plus loin que simplement modifier le BIOS. Ils ajoutent diverses fonctionnalités supplémentaire, qui ne sont pas censées être du ressort d'un firmware de démarrage. Certains UEFI disposent de programmes de diagnostic mémoire, de programmes de restauration système, de programmes permettant d’accéder à internet et bien d'autres. L'EFI peut ainsi être vu comme un logiciel intermédiaire entre le firmware et l'OS. Cependant, l'UEFI gère la rétrocompatibilité avec les anciens BIOS, ce qui fait qu'ils conservent les anciennes fonctionnalités du BIOS. Aussi, tout ce qui est dit dans cette section sera aussi valide pour l'UEFI, dans une certaine mesure. En plus du BIOS système, les cartes d'extension peuvent avoir un BIOS. Par exemple, les cartes graphiques actuelles contiennent toutes un '''BIOS vidéo''', une mémoire ROM ou EEPROM qui contient des programmes capables d'afficher du texte et des graphismes monochromes ou 256 couleurs à l'écran. Lors du démarrage de l'ordinateur, ce sont ces routines qui sont utilisées pour gérer l'affichage avant que le système d'exploitation ne lance les pilotes graphiques. On peut aussi citer le cas des cartes réseaux, certaines permettant de démarrer un ordinateur sur le réseau. Ces BIOS sont ce qu'on appelle des '''BIOS d'extension'''. Le contenu des BIOS d'extension dépend fortement du périphérique en question, contrairement au BIOS système dont le contenu est relativement bien standardisé. ===L'accès au BIOS=== [[File:OrganisationMémoirePC.png|vignette|Organisation de la mémoire d'un PC doté d'un BIOS.]] Il faut noter que le processeur démarre systématiquement en mode réel, un mode d'exécution spécifique aux processeurs x86, où le processeur n'a accès qu'à 1 mébioctet de mémoire (les adresses font 20 bits maximum). C'est un mode de compatibilité qui existe parce que les premiers processeurs x86 avaient des adresses de 20 bits, ce qui fait 1 mébioctet de mémoire adressable. En mode réel, Le premier mébioctet de mémoire est décomposé en deux portions de mémoire : les premiers 640 kibioctets sont ce qu'on appelle la mémoire '''conventionnelle''', alors que les octets restants forment la '''mémoire haute'''. Les deux premiers kibioctets de la mémoire conventionnelle sont réservés au BIOS, le reste est utilisé par le système d'exploitation (MS-DOS, avant sa version 5.0) et le programme en cours d’exécution. Pour être plus précis, les premiers octets contiennent non pas le BIOS, mais la BIOS Data Area utilisée par le BIOS pour stocker des données diverses, qui commence à l'adresse 0040:0000h, a une taille de 255 octets, et est initialisée lors du démarrage de l'ordinateur. La mémoire haute est réservée pour communiquer avec les périphériques. On y trouve aussi le BIOS de l'ordinateur, mais aussi les BIOS des périphériques (dont celui de la carte vidéo, s'il existe), qui sont nécessaires pour les initialiser et parfois pour communiquer avec eux. De plus, on y trouve la mémoire de la carte vidéo, et éventuellement la mémoire d'autres périphériques comme la carte son. Par la suite, le BIOS démarre le système d'exploitation, qui bascule en mode protégé, un mode d'exécution où il peut utiliser des adresses mémoires de 32/64 bits et utiliser la '''mémoire étendue''' au-delà du premier mébioctet. ===Le démarrage de l'ordinateur=== Au démarrage de l'ordinateur, le processeur est initialisé de manière à commencer l'exécution des instructions à partir de l'adresse 0xFFFF:0000h là où se trouve le BIOS. Pour info, cette adresse est l'adresse maximale en mémoire réelle moins 16 octets. Le BIOS s’exécute et initialise l'ordinateur avant de laisser la main au système d'exploitation. Le BIOS commence la séquence de démarrage avec le '''POST''' ('''Power On Self Test'''), qui effectue quelques vérifications. Il commence par vérifier que le BIOS est OK, en vérifiant une somme de contrôle présente à la fin du BIOS lui-même. Il vérifie ensuite l'intégrité des 640 premiers kibioctets de la mémoire. Ensuite, les périphériques sont détectés, testés et configurés pour garantir leur fonctionnement. Pour cela, le BIOS explore la mémoire haute pour '''détecter les BIOS d'extension'''. Si un BIOS d'extension est détecté, le BIOS système lui passe la main, grâce à un branchement vers l'adresse du code du BIOS d'extension. Ce BIOS peut alors faire ce qu'il veut, mais il finit par rendre la main au BIOS (avec un branchement) quand il a terminé son travail. Pour détecter les BIOS d'extension, le BIOS lit la mémoire haute par pas de 2 kibioctets. En clair, il analyse toutes les adresses multiples de 2 kibioctets, dans la mémoire haute. Par exemple, le BIOS regarde s'il y a un BIOS vidéo aux adresses mémoire 0x000C:0000h et 0x000E:0000h. Il y recherche une valeur bien précise qui indique qu'une ROM est présente à cet endroit : la valeur en question vaut 0x55AA. Cette valeur est suivie par un octet qui indique la taille de la ROM, lui-même suivi par le code du BIOS d'extension. Ensuite, le BIOS effectue quelques opérations de configuration assez diverses, aux description assez barbares (initialiser le vecteur d'interruption de l'ordinateur, passage en mode protégé, et bien d'autres). En cas d'erreur à cette étape, le BIOS émet une séquence de bips, la séquence dépendant de l'erreur et de la carte mère. Pour cela, le BIOS est relié à un buzzer placé sur la carte mère. Si vous entendez cette suite de bips, la lecture du manuel de la carte mère vous permettra de savoir quelle est l'erreur qui correspond. Si tout fonctionne bien, une '''interface graphique''' s'affiche. La majorité des cartes mères permettent d'accéder à une interface pour configurer le BIOS, en appuyant sur F1 ou une autre touche lors du démarrage. Cette interface donne accès à plusieurs options modifiables, qui permettent de configurer le matériel. Le BIOS utilise une interface assez basique, limitée à du texte, alors que l'UEFI gère une vraie interface graphique, avec un affichage pixel par pixel. Par la suite, le BIOS démarre le système d'exploitation. Le processus est totalement différent entre BIOS et UEFI. Dans les deux cas, le BIOS lit une structure de données sur le disque dur, qui contient toutes les informations pertinentes pour lancer le système d'exploitation. Elle est appelée le MBR pour le BIOS, la GPT pour l'UEFI. La première est limitée à des partitions de 2 téraoctets, pas la seconde, la structure n'est pas la même, de même que le mécanisme de boot. Mais on rentre alors dans un domaine différent, celui du fonctionnement logiciel des systèmes d'exploitation. Je renvoie ceux qui veulent en savoir plus à mon wikilivre sur les systèmes d'exploitation, et plus précisément au chapitre sur [[Les systèmes d'exploitation/Le démarrage de l'ordinateur|Le démarrage d'un ordinateur]]. ===Les paramètres du BIOS=== Si vous avez déjà fouillé dans l'interface graphique du BIOS, vous avez remarqué que celui-ci fournit beaucoup d'options de configuration. Ils sont peu nombreux sur les PC constructeurs, mais en grand nombre sur les PC montés à la main. La raison est que les PC constructeurs utilisent des BIOS personnalisés, qui réduisent volontairement le nombre d'options accessibles à l'utilisateur. Le but est de réduire les appels au SAV ou les retour garanties faisant suite à une mauvaise manipulation du BIOS. Les cartes mères vendues à l'unité, dans les PC fait maison, n'ont pas ces contraintes et fournissent toutes les options disponibles. Mais le fait qu'il y ait des options dans le BIOS devrait nous poser une question. Le BIOS est stocké dans une mémoire ROM, qu'on peut lire, mais pas modifier. Vous me rétorquerez sans doute que le fait qu'on puisse flasher le BIOS contredit cela, que le BIOS est stocké dans une FLASH, pas dans de la ROM. Mais malgré tout, cela n'est pas compatible avec une modification rapide des options du BIOS : on n'efface pas toute la FLASH du BIOS en modifiant une simple option. Alors où sont stockés ces paramètres de configuration ? La réponse est qu'ils sont stockés dans une mémoire FLASH ou EEPROM séparée du BIOS, appelée la '''''Non-volatile BIOS memory'''''. L'implémentation exacte dépend du BIOS. Au tout début, sur les premiers PC IBM et autres, il s'agissait d'une EEPROM séparée. Mais rapidement, elle a été fusionnée avec d'autres mémoires naturellement présentes sur la carte mère. Elle a ensuite été fusionnée avec la CMOS RAM, une mémoire RAM que nous verrons plus bas dans la suite du chapitre. De nos jours, elle est intégrée dans le ''chipset'' de la carte mère, avec la CMOS RAM et bien d'autres composants. ===Une fonction obsolète : la gestion des périphériques=== Autrefois, la gestion des périphériques était intégralement le fait du BIOS. Ce n'est pas pour rien que « BIOS » est l'abréviation de ''Basic Input Output System'', ce qui signifie « programme basique d'entrée-sortie ». Pour cela, il intégrait des morceaux de code dédiés qui servaient à gérer le disque dur, la carte graphique, etc. Intuitivement, si je dis morceau de code, les programmeurs se disent qu'il doit s'agir de fonctions logicielles, en référence à une fonctionnalité commune de tous les langages de programmation modernes. Pour être plus précis, il s'agit en réalité de routines d'interruptions, mais la différence sera expliquée dans un chapitre ultérieur portant justement sur les interruptions, dans lequel nous étudierons rapidement les interruptions du BIOS. ==Les circuits de surveillance matérielle : RESET et NMI== Les circuits de surveillance matérielle vérifient en permanence la tension d'alimentation, la fréquence d'horloge, les températures, le bon fonctionnement de la mémoire, et bien d'autres choses. En cas de problèmes, ils peuvent redémarrer l'ordinateur ou l'éteindre. Pour cela, ces circuits communiquent directement avec le processeur, grâce à deux entrées sur processeur : l'entrée RESET, et l'entrée d'interruption non-masquable NMI (''Non-Maskable Interrupt''). L'entrée RESET a nom un assez transparent et on comprend qu'elle redémarre le processeur. L'entrée d'interruption non-masquable mérite cependant quelques explications. ===L'entrée RESET du processeur=== Le processeur dispose d'une '''entrée RESET''' qui, comme son nom l'indique, le réinitialise quand on met le niveau logique ou front adéquat dessus. Lorsqu'on envoie le signal adéquat sur l'entrée RESET, le processeur remet à zéro tous ses registres et lance la procédure d'initialisation du ''program counter''. Il peut être initialisé de deux façons différentes. Avec la première, il est initialisé à une valeur fixe, déterminée lors de la conception du processeur, souvent l'adresse 0. L'autre solution ajoute une indirection, elle précise l'adresse d’initialisation dans le firmware. Le processeur lit le firmware à une adresse fixée à l'avance, pour récupérer l'adresse de la première instruction et effectuer un branchement. L'entrée RESET est lié de près ou de loin au bouton d'alimentation de l'ordinateur. Quand vous allumez votre ordinateur, cette broche RESET est activée, le processeur démarre. Aussi, si vous appuyez environ 10/15 secondes sur le bouton d'alimentation, l'ordinateur redémarre. C'est parce que l'entrée RESET a été activé par l'appui continu du bouton. Attention cependant, certains ordinateurs ou certaines consoles de jeu vidéo avaient un bouton RESET directement connectée au signal RESET : appuyer et relâcher le bouton active le signal RESET sans délai. Le signal RESET n'est pas produit directement par le bouton d'allumage. En effet, au démarrage de l’ordinateur, le processeur ne peut pas être RESET immédiatement. Il doit attendre que la tension d'alimentation se stabilise, que le signal d'horloge se stabilise, etc. Pour cela, des circuits aux noms barbares de ''Power On Reset'' et d'''Oscilator startup timer'' vérifient la stabilité de la tension et de l'horloge. Le signal RESET n'est généré que si les conditions adéquates sont remplies. Le signal RESET est donc produit au démarrage, mais il peut aussi être produit lors du fonctionnement de l'ordinateur, pour redémarrer en urgence l'ordinateur en cas de gros problème matériel. Par exemple, en cas de défaillance de l'alimentation, un signal RESET peut être produit pour limiter les dégats. Nous verrons aussi l'exemple du ''watchdog timer'' dans ce qui suit. Pour résumer, le signal RESET est produit en combinant plusieurs signaux, provenant de circuits de surveillance matérielle dispersés sur la carte mère. Nous verrons ceux-ci dans la suite du chapitre, car nous les verrons indépendamment les uns des autres. Vous vous demandez sans doute pourquoi j'ai parlé de redémarrage d'urgence en cas de problème, au lieu d'un banal redémarrage. La raison est que les deux ne sont pas du tout les mêmes, surtout au regarde de l'entrée RESET. Le redémarrage via l'entrée de RESET est aussi appelée un ''reset hardware'', et on l'oppose au ''reset'' logiciel. Un ''reset'' logiciel est simplement le ''reset'' qui a lieu quand vous redémarrez votre ordinateur normalement, en demandant à Windows/linux de redémarrer. Il n'implique pas l'usage de l'entrée RESET, du moins il n'est pas censé le faire. Les méthodes pour RESET un processeur de manière logicielle dépendent beaucoup du processeur considéré. Sur les processeurs x86, il a une demi-douzaine de méthodes différentes. Une méthode courante sur les CPU x86 et ARM utilise un '''registre de reset'''. Les processeur écrivent dans ce registre pour déclencher un RESET. Suivant ce qu'ils écrivent dedans, ils peuvent déclencher tel ou tel type de reset (''cold reset'', ''warm reset'', éteindre l'ordinateur, autres). Avec l'UEFI, le firwmare dispose d'une fonction faite pour, que le système d'exploitation peut appeler à volonté. Il peut aussi tenter d'exécuter des branchements spécifiques. Mais un tel reset logiciel ne fait pas usage de l'entrée RESET proprement dit. Il y avait cependant une exception de taille, où le logiciel pouvait déclencher un ''reset hardware'', par l'intermédiaire d'un circuit appelé le contrôleur de clavier 8279. Le contrôleur de clavier 8279, comme son nom l'indique, est un circuit connecté au port clavier/souris. Les anciens PC avaient des ports PS/2 pour le clavier et la souris, et le contrôleur de clavier 8279 était situé de l'autre côté du connecteur. Il s'agissait d'un microcontroleur qui recevait les touches appuyées sur le clavier, configurait les LED pour le verr num, l'arret defil et autres. Mais une des broche de sortie de ce microcontroleur était directement reliée à l'entrée RESET du processeur, il y avait juste quelques portes logiques entre les deux. En configurant le controleur de clavier, on pouvait lui faire faire un RESET via l'entrée RESET ! ===L'entrée NMI d'interruption non-masquable=== L'entrée RESET est plus rarement utilisée lorsqu'une défaillance matérielle irrécupérable est détectée. Le résultat de telles défaillances est que l'ordinateur est arrêté de force, redémarré de force, ou affiche un écran bleu. Redémarrer l'ordinateur est possible avec un signal RESET, mais pas l'affichage d'un écran bleu ou éteindre l'ordinateur. Pour cela, le processeur dispose d'une seconde entrée, séparée du RESET, appelée l''''entrée NMI'''. Pour simplifier, il s'agit d'une entrée pour l'arrêt d'urgence. Lorsqu'on envoie le signal adéquat sur l'entrée NMI, le processeur stoppe immédiatement ce qu'il est en train de faire, puis exécute un programme d'arrêt urgence. Ce dernier détecte l'origine de l'erreur et réagit en conséquence : soit en réparant l'erreur, soit en affichant un écran bleu, soit en éteignant l'ordinateur. : Nous verrons dans quelques chapitres le concept d'interruption, et précisément d'interruption non-masquable. Pour simplifier, une interruption est ce qui permet de stopper le processeur pour lui faire exécuter un programme d'urgence, avant de reprendre l'exécution. L'acronyme NMI signifie ''Non Maskable Interrupt'', ce qui veut dire interruption non-masquable, non-masquable dans le sens où l'interruption ne peut pas être ignorée ou retardée. Les deux entrées NMI et RESET semblent foncièrement différentes et s'utilisent dans des circonstances distinctes. Cependant, quelques circuits sur la carte mère sont reliées aux deux entrées. C'est le cas des circuits qui surveillent la tension d'alimentation et l'horloge. Un ordinateur ne peut pas fonctionner si la tension d'alimentation n'est pas stable, idem pour la fréquence d'horloge, idem si les températures sont trop élevées. Si les conditions ne sont pas remplies, l'ordinateur ne peut pas démarrer. De même, en cas de défaillance de la tension d'alimentation ou de la fréquence, le processeur doit être éteint via l'entrée NMI. Aussi, divers circuits vérifient ces paramètres en permanence. Ils autorisent le démarrage de l’ordinateur via l'entrée RESET, mais peuvent aussi le redémarrer ou activer l'entrée NMI si besoin. Les entrées NMI et RESET sont donc reliées à des circuits communs. ===Le ''watchdog timer'' est reliée à l'entrée RESET=== Un autre exemple d'utilisation de l'entrée RESET du processeur est lié au ''watchdog timer''. Pour rappel, le ''watchdog timer'' est un mécanisme de sécurité qui redémarre automatiquement l'ordinateur s'ils suspecte que celui-ci a planté. Le ''watchdog timer'' est un compteur/décompteur qui est connecté à l'entrée RESET du processeur. Si le compteur/décompteur déborde (au sens débordement d'entier), alors il génère un signal RESET pour redémarrer le processeur. On part du principe que si l'ordinateur ne réinitialise par le ''watchdog timer'', c'est qu'il a planté. Le processeur réinitialise le ''watchdog timer'' régulièrement, ce qui signifie que le compteur est remis à zéro avant de déborder, et le système n'est pas censé redémarrer. Pour cela, il utilise l'entrée NMI, d'une manière assez particulière. Régulièrement, un ''timer'' séparé envoie un 1 sur l'entrée NMI. Le processeur exécute alors son programme d'urgence, qui cherche la source de l'interruption. Il remarque alors que l'activation de l'entrée NMI provient de ce ''timer''. Le programme d'urgence réinitialise alors le ''watchdog timer''. [[File:SimpleWatchdogTimer.gif|centre|vignette|upright=2|Le ''Watchdog Timer'' et l'ordinateur.]] ==La gestion des fréquences et les ''timers''== Les composants d'un ordinateur sont cadencés à des fréquences très différentes. Par exemple, le processeur fonctionne avec une fréquence plus élevée que l'horloge de la mémoire RAM. Les différents signaux d'horloge sont générés par la carte mère. Intuitivement, on se dit qu'il y a un circuit dédié par fréquence. Mais c'est en fait une erreur : en réalité, il n'y a qu'un seul générateur d'horloge. Il produit une horloge de base, qui est « transformée » en plusieurs horloges, grâce à des montages électroniques spécialisés. Les avantages de cette méthode sont la simplicité et l'économie de circuits. ===Les multiplieurs et diviseurs de fréquence=== La fréquence de base est souvent très petite comparée à la fréquence du processeur ou de la mémoire, ce qui est contre-intuitif. Mais la fréquence de base est multipliée par les circuits transformateurs pour obtenir la fréquence du processeur, de la RAM, etc. Ainsi, la fréquence du processeur et de la RAM sont des multiples de cette fréquence de base. Naturellement, les circuits de conversion de fréquence sont donc appelés des '''multiplieurs de fréquence'''. [[File:Génération des signaux d'horloge d'un ordinateur.png|centre|vignette|upright=2|Génération des signaux d'horloge d'un ordinateur]] De nos jours, les ordinateurs font faire la multiplication de fréquence par un composant appelé une '''PLL''' (''Phase Locked Loop''), qui sont des composants assez versatiles et souvent programmables, mais il est aussi possible d'utiliser des circuits à base de portes logiques plus simples mais moins pratiques. Comprendre le fonctionnement des PLLs et des générateurs de fréquence demande des bases assez solides en électronique analogique, ce qui fait que nous n'en parlerons pas en détail dans ce cours. Une carte mère peut aussi contenir des diviseurs de fréquences, pour générer des fréquences très basses. C'était surtout le cas avec les anciens systèmes, où certains bus allaient à quelques kiloHertz. Les diviseurs de fréquences sont fabriqués avec des compteurs, comme nous l'avions vu dans le chapitre sur les ''timers'' et diviseurs de fréquence. Vu que nous avons déjà abordé ces composants, nous ne reviendrons pas dessus. ===Le générateur de fréquence : un oscillateur à Quartz=== Le '''générateur de fréquence''' est le circuit qui génère le signal d'horloge envoyé au processeur, la mémoire RAM, et aux différents bus. Sans lui, le processeur et la mémoire ne peuvent pas fonctionner, vu que ce sont des circuits synchrones dans les PC actuels. Il existe de nombreux circuits générateurs de fréquence, qui sont appelés des '''oscillateurs''' en électronique. Ils sont très nombreux, tellement qu'on pourrait écrire un livre entier sur le sujet. Entre les oscillateurs basés sur un circuit RLC (avec une résistance, un condensateur et une bobine), ceux basés sur une résistance négative, ceux avec des amplificateurs opérationnels, ceux avec des lampes à néon, et j'en passe ! Mais nous n'allons pas parler de tous les oscillateurs, la plupart n'étant pas utilisés dans les ordinateurs modernes. [[File:3Com OfficeConnect ADSL Wireless 11g Firewall Router 2012-10-28-0866.jpg|vignette|Oscillateur à Quartz, sur une carte mère.]] La quasi-totalité des générateurs de fréquences des ordinateurs modernes sont des '''oscillateurs à quartz''', similaires à celui présent dans les montres électroniques. Ils sont fabriqués en combinant un amplificateur avec un cristal de Quartz. Ils fournissent une fréquence de base qui varie suivant le modèle considéré, mais qui est souvent de 32 768 Hertz, soit 2^15 cycles d'horloge par seconde. Le cristal de Quartz a une forme facilement reconnaissable, comme montré dans l'image ci-contre. Vous pouvez le repérer assez facilement sur une carte mère si jamais vous en avez l'occasion. : Pour ceux qui voudraient en savoir plus sur le sujet, sachez que le wikilivre d'électronique a un chapitre dédié à ce sujet, disponible via le lien suivant. Attention cependant : le chapitre n'est compréhensible que si vous avez déjà lu les chapitres précédents du wikilivre sur l'électronique et il est recommandé d'avoir une bonne connaissance des circuits RLC/LC, sans quoi vous ne comprendrez pas grand-chose au chapitre. * [[Électronique/Les oscillateurs (générateurs de fréquence)]] ===Les ''timers'' intégrés à la carte mère=== Le générateur de fréquence est souvent combiné à des ''timers'', des circuits qui comptent des durées bien précises et sont capables de générer des fréquences. Pour rappel, les ''timers'' sont des compteurs/décompteurs qui génèrent un signal quand ils atteignent une valeur limite. Ils permettent de compter des durées, exprimées en cycles d’horloge. Les fonctions de Windows ou de certains logiciels se basent là-dessus, comme celles pour baisser la luminosité à une heure précise, passer les couleurs de l'écran en mode nuit, certaines notifications, les tâches planifiées, et j'en passe. Ils permettent aussi d’exécuter un tâche précise à intervalle régulier, ou après une certaine durée. Par exemple, on peut vouloir générer une interruption à une fréquence de 60 Hz, pour gérer le rafraichissement de l'écran. Une telle fonctionnalité s'utilisait autrefois sur les anciens ordinateurs ou sur les anciennes consoles de jeux vidéo et portait le nom de ''raster interrupt''. Un ordinateur est rempli de ''timers'' divers, qui se trouvent sur la carte mère ou dans le processeur, tout dépend du ''timer''. Sur les anciens PC, la carte mère incorpore deux ''timers'' : l'horloge temps réel et le PIT. L'horloge temps réel génère une fréquence de 1024 Hz, alors que le PIT est un Intel 8253 ou un Intel 8254 programmable par l'utilisateur. Les PC récents n'ont qu'un seul ''timer'' sur la carte mère, qui remplace les deux précédents : le ''High Precision Event Timer''. Un ordinateur contient d'autres ''timers'', comme le ''timer'' ACPI, le ''timer'' APIC, ou le ''Time Stamp Counter'', mais ces derniers sont intégrés dans le processeur et non sur la carte mère. Plus rarement, certaines cartes mères possèdent un ''watchdog timer''. ===L'''Oscillator start-up timer'' : la stabilité de l'horloge au démarrage=== Au démarrage de l'ordinateur, la tension d'horloge n'est pas stable. Il faut un certain temps pour que les circuits de génération d'horloge se stabilisent et fournissent un signal d'horloge stable. Et tant que le signal d'horloge n'est pas stable, le processeur n'est pas censé démarrer. L''''''Oscillator start-up timer''''' est un circuit qui temporise en attendant que le signal d'horloge se stabilise. Le signal RESET, nécessaire pour démarrer le processeur, n'est mis à 1 que si l'''Oscillator start-up timer'' lui donne le feu vert. Dans son implémentation la plus simple, il s'agit d'un simple ''timer'', un vulgaire compteur qui attend qu'un certain nombre de cycles d'horloge se soient écoulés. Il est supposé que la fréquence est stable après ce nombre de cycles. Par exemple, sur les microcontrôleurs PIC 8-bits, l'OST compte 1024 cycles d'horloge avant d'autoriser le RESET. D'autres processeurs attendent durant un nombre de cycles plus important, le nombre de cycles exact dépend de la fréquence. Notez que l'OST attend un certain nombre de cycles. Les premiers cycles sont irréguliers, le tout se stabilise vers la fin, ce qui ne correspond pas à un temps bien défini, une petite variabilité est toujours présente. ===Un exemple de circuit générateur de fréquence : l'Intel 8284=== L'''Oscillator start-up timer'' est parfois fusionné avec d'autres circuits, dont des multiplieurs/divisieurs de fréquence et des ''timers''. Un bon exemple est celui de l''''Intel 8284''', un circuit qui fusionne ''Oscillator start-up timer'', diviseur de fréquence et générateur de fréquence. [[File:Intel 8284.svg|thumb|Intel 8284]] Il est possible de le relier à un cristal de Quartz sur deux entrées nommée X1 et X2, et il génère alors un signal d'horloge à partir de ce qu'il reçoit du cristal. Le signal d'horloge généré est alors disponible sur une sortie dédiée, la sortie OSC. C'est la fonction générateur d'horloge. Dans le détail, pour générer une fréquence, il faut combiner un cristal de Quartz avec un circuit dit oscillateur. L'Intel 8284 incorpore l’oscillateur, mais pas le cristal de Quartz. Il est aussi possible de l'utiliser en tant que diviseur de tension, bien que ce soit rudimentaire. La fréquence d'entrée est divisée par trois et le résultat est présenté sur la sortie PCLK. La fréquence de sortie a alors un rapport cyclique de 1/3. L'implémentation de la division par trois se fait avec un simple compteur. Un second signal d'horloge est disponible sur la sortie nommée CLK. Il a une de fréquence deux fois moindre que le premier, soit 6 fois moins que la fréquence d'entrée, et a un rappoort cyclique de 50% (signal carré). Un point important est que la fréquence d'entrée peut provenir de deux sources différentes. En premier lieu, elle peut être présentée sur une broche séparée, appelée l'entrée EFI. En second lieu, elle peut provenir de l’oscillateur à Qaurtz intégré au 8284. Le choix entre les deux se fait avec l'entrée F/C : oscillateur si c'est un 1, entrée EFI si c'est un 0. L'intérieur du circuit est assez simple : un ''timer'' pour l'OST, un oscilateur à Quartz, un multiplexeur pour choisir la fréquence d'entrée, deux compteurs pour les diviseurs de fréquences. ===Annexe : le bouton Turbo des vieux PC=== [[File:PC-Front IMGP5531 smial wp.jpg|vignette|Exemple de façade de PC avec un bouton Turbo.]] Si vous êtes assez vieux, vous avez peut-être déjà utilisé un PC qui disposait d'un bouton Turbo à côté du bouton ON/OFF. Vous êtes vous êtes demandé ce à quoi servait ce bouton ? Et surtout : saviez-vous que contre-intuitivement, il ralentissait l'ordinateur ? La raison à cela est partiellement liée à la fréquence du processeur : le bouton Turbo réduisait la fréquence du processeur (sauf exceptions) ! La raison est une question de compatibilité logicielle avec les processeurs 8086 et 8088 d'Intel. A l'époque, de nombreux jeux ou logiciels interactifs se basaient sur la fréquence du CPU pour timer des actions/évènements. Mais lors du passage au processeurs 286, 396 et 486, la fréquence du CPU a augmenté. Les logiciels allaient alors plus rapidement, les jeux vidéos étaient accélérés au point d'en devenir injouables. L'effet était un peu similaire à la différence entre jeux en 50 et 60 Hz, sauf qu'ici, la fréquence était multipliée par 2, 4, voire 10 ! Le 8088 avait une fréquence de 4,77 MHz et le 8086 allait à 5 MHz. Le 186 allait à 6 MHz, le 286 allait à 10 ou 12.5 MHz selon la version, le 386 allait de 12.5 MHz à 40 MHz selon la version, et le 486 allait de 16 à 100 MHz. Pour éviter cela, les ordinateurs ont ajouté un bouton Turbo, qui était en réalité un bouton de compatibilité. Lorsqu'on l'appuyait, la vitesse de l'ordinateur était réduite de manière à faire tourner les anciens jeux/logiciels à la bonne vitesse. En clair, le bouton était mal nommé et faisait l'inverse de ce qu'on peut croire intuitivement. Du moins, c'était le principe. Quelques ordinateurs fonctionnaient à vitesse réduite à l'état normal et il fallait appuyer sur le bouton Turbo pour retrouver une vitesse normale. Et le bouton Turbo agissait sur la fréquence du CPU. Il baissait sa fréquence pour le faire descendre aux 4,77/5 MHz adéquats. Du moins, certaines cartes mères faisaient ainsi. Des rumeurs prétendent que certains carte mères faisaient autrement, en désactivant le cache du processeur, ou en réduisant la fréquence effective du bus (en ajoutant des ''wait state'', des cycles où le bus est inutilisé). Mais dans la majorité des cas, on peut supposer que la réduction de la fréquence était belle et bien utilisée. Et pour cela, il fallait relier le bouton Turbo à des circuits diviseurs de fréquence pour réduire la fréquence du CPU. Qu'un bouton soit relié, même indiretcement aux circuits d'horloge, est tout de même quelque chose d'assez inattendu. Imaginez si les PC actuels avaient un bouton "Power Saving" qui réduisait la fréquence du processeur. ==L'horloge temps réel et la CMOS RAM== Parmi tous les ''timers'' présents sur la carte mère, l''''horloge temps réel''' se démarque des autres. Dans ce qui suit, nous la noterons RTC, ce qui est l'acronyme du terme anglais ''Real Time Clock''. La RTC est cadencée à fréquence de 1 024 Hz, soit près d'un Kilohertz, ou du moins un circuit capable de l'émuler. La RTC est parfois connectée à l'entrée d'interruption non-masquable, car elle est utilisée pour des fonctions importantes du système d'exploitation, comme la commutation entre les processus, et bien d'autres. Mais son fonction principale est toute autre. La RTC est utilisée par le système pour compter les secondes, afin que l'ordinateur soit toujours à l'heure. Vous savez déjà que l'ordinateur sait quelle heure il est (vous pouvez regarder le bureau de Windows dans le coin inférieur droit de votre écran pour vous en convaincre) et il peut le faire avec une précision de l'ordre de la seconde. ===La CMOS RAM=== Pour savoir quel jour, heure, minute et seconde il est, l'ordinateur utilise la RTC, ainsi qu'un circuit pour mémoriser la date. La '''CMOS RAM''' mémorise la date exacte à la seconde près. Son nom nous dit qu'elle est fabriquée avec des transistors CMOS, mais aussi qu'il s'agit d'une mémoire RAM. Mais attention, il s'agit d'une mémoire RAM ''non-volatile'', c'est à dire qu'elle ne perd pas ses données quand on éteint l'ordinateur. Nous expliquerons dans la section suivante comment cette RAM fait pour être non-volatile. La ''CMOS RAM'' est adressable, mais on y accède indirectement, comme si c'était un périphérique, à savoir que la CMOS RAM est mappée en mémoire. On y accède via les adresses 0x0007 0000 et 0x0007 0001 (ces adresses sont écrites en hexadécimal). Elle mémorise, outre la date et l'heure, des informations annexes, comme les paramètres du BIOS (voir plus bas). Oui, vous avez bien lu : la CMOS RAM est utilisée pour stocker les paramètres du BIOS vu plus haut, elle sert de ''non-volatile BIOS memory''. Il s'agit là d'une optimisation : au lieu d'utiliser une ''non-volatile BIOS memory'' et une CMOS RAM séparée, on utilise une seule mémoire non-volatile pour les deux. Mais la manière de stocker les paramètres du BIOS dans la CMOS RAM a beaucoup changé dans le temps. Les anciens PC avaient un bus ISA, ancêtre du bus PCI. Et le BIOS devait mémoriser la configuration de bus, ainsi que l'ensemble des périphériques installé sur ce bus. Pour cela, ces données de configuration étaient stockées dans la CMOS RAM. Elles suivaient le standard dit d'''Extended System Configuration Data''. Il fournissait un format standard pour stocker les paramètres du bus ISA, l'adresse où placer ces données, et trois fonctions/interruptions du BIOS pour récupérer ces données. Les données de configuration ISA prenaient les 128 octets à la fin de CMOS ROM. Les bus plus récents ne mémorisent plus de données de configuration dans la CMOS RAM, ni même dans le BIOS. ===La source d'alimentation de la RTC et de la CMOS RAM=== [[File:Inside the Real-time clock IC vnutri u nei neonka.jpg|vignette|RTC avec pile au lithium intégrée.]] L'horloge temps réel, l’oscillateur à Quartz et la CMOS RAM fonctionnent en permanence, même quand l'ordinateur est éteint. Mais cela implique que ces composants doivent être alimenté par une source d'énergie qui fonctionne lorsque l'ordinateur est débranché. Cette source d'énergie est souvent une petite pile au lithium localisée sur la carte mère, plus rarement une petite batterie. Elle alimente les trois composants en même temps, vu que tous les trois doivent fonctionner ordinateur éteint. Elle est facilement visible sur la carte mère, comme n'importe quelle personne qui a déjà ouvert un PC et regardé la carte mère en détail peut en témoigner. : Au passage : plus haut, nous avions dit que la CMOS RAM est une RAM non-volatile, c'est à dire qu'elle ne s'efface pas quand on éteint l’ordinateur. Et bien si elle l'est, c'est en réalité car elle est alimentée en permanence par une source secondaire de courant. Sur la plupart des cartes mères, la RTC et la CMOS RAM sont fusionnées en un seul circuit qui s'occupe de la gestion de la date et des durées. Il arrive rarement que la pile au lithium soit intégrée dans ce circuit, mais c'est très rare. La plupart des concepteurs de carte mère préfèrent séparer la pile au lithium de la RTC/CMOS RAM pour une raison simple : on peut changer la pile au lithium en cas de problèmes. Ainsi, si la pile au lithium est vide, on peut la remplacer. Enlever la pile au lithium permet aussi de résoudre certains problèmes, en réinitialisant la CMOS RAM. L'enlever et la remettre réinitialise la ''CMOS RAM'', ce qui remet à zéro la date, mais aussi les paramètres du BIOS. ==Le ''chipset'' de la carte mère== L'organisation des cartes mères des ordinateurs personnels a évolué au cours du temps pendant que de nombreux bus apparaissaient. Les premiers ordinateurs faisaient avec un simple bus système qui connectait processeur, mémoire et entrée-sortie. Mais avec l'augmentation du nombre de périphériques et de composants systèmes, l'organisation des bus s'est complexifiée. ===La première génération : les bus partagés=== Pour les bus de première génération, un seul et unique bus reliait tous les composants de l'ordinateur. Ce bus s'appelait le '''bus système''' ou ''backplane bus''. Ces bus de première génération avaient le fâcheux désavantage de relier des composants allant à des vitesses très différentes : il arrivait fréquemment qu'un composant rapide doive attendre qu'un composant lent libère le bus. Le processeur était le composant le plus touché par ces temps d'attente. Du fait de l'existence d'un bus unique, les entrées-sorties étaient mappées en mémoire [[File:Computer buses.svg|centre|vignette|upright=2|Bus système]] ===L'apparition du ''chipset''=== Les cartes mères récentes, après les années 1980, ne peuvent plus utiliser un bus unique, car il y a trop de composants à connecter dessus. A la place, elles utilisent une architecture à base de répartiteurs. Pour rappel, ce répartiteur est placé en avant du processeur et sert d'interface entre celui-ci, un bus pour la mémoire, et un bus pour les entrées-sorties. Mais il a aussi d'autres capacités qui dépassent de loin son rôle d'interface. Il a intégré des circuits comme le contrôleur mémoire, un contrôleur DMA, un contrôleur d'interruption, etc. [[File:IO mappées en mémoire avec séparation des bus.png|centre|vignette|upright=2|IO mappées en mémoire avec séparation des bus, usage d'un répartiteur]] Un exemple est le ''chipset'' utilisé avec le processeur Intel 486, sorti en 1989. Il était connecté au processeur, à la mémoire RAM, aux différents bus, mais aussi à la mémoire cache (qui était séparé du processeur et placé sur la carte mère). Pour ce qui est des bus, il était connecté au bus PCI, au bus IDE pour le disque dur et au bus SMM. Il était indirectement connecté au bus ISA, un bus ancien conservé pour des raisons de rétrocompatibilité, mais qui avait été éclipsé par le PCI. ===La séparation du ''chipset'' en deux=== Un autre problème est que la mémoire et la carte graphique sont devenus de plus en plus rapide avec le temps, au point que les périphériques ne pouvaient plus suivre. Les différents composants de la carte mère sont séparés en deux catégories : les "composants lents" et les "composants rapides". Les composants rapides regroupent le processeur, la mémoire RAM et la carte graphique, les autres sont regroupés dans les composants lents. Les besoins entre des deux classes de composants étant différents, utiliser un seul bus pour les faire communiquer n'est pas idéal. Les composants rapides demandent des bus rapides, de forte fréquence, avec un gros débit pour communiquer, alors que les composants lents ont besoin de bus moins rapide, de plus faible fréquence. Entre les années 80 et 2000, la solution retenue par les fabricants de cartes mères utilisait deux répartiteurs séparés : le ''northbridge'' et le ''southbridge''. Le ''northbridge'' sert d'interface entre le processeur, la mémoire et la carte graphique et est connecté à chacun par un bus dédié. Il intègre notamment le controleur mémoire. Le ''southbridge'' est le répartiteur pour les composants lents. Le bus qui relie le processeur au ''northbridge'' est appelé le '''''Front Side Bus''''', abrévié en FSB. Le bus de transmission qui relie le ''northbridge'' au ''southbridge'' est un bus dédié, spécifique au ''chipset'' considéré, sur lequel on ne peut pas dire de généralités. [[File:Chipset schematic.svg|centre|vignette|upright=1.0|Chipset séparé en northbridge et southbridge.]] [[File:Motherboard diagram.svg|vignette|Carte mère avec circuit Super IO.]] Ce qui est mis dans le ''southbridge'' est très variable selon la carte mère. Le ''southbridge'' intègre généralement tout ce qu'il faut pour gérer des périphériques, ce qui inclut des circuits aux noms barbares comme des contrôleurs de périphériques, des contrôleurs d'interruptions, des contrôleurs DMA, etc. Mais les ''chipsets'' modernes ont tellement de transistors qu'on y intègre presque tout et n'importe quoi. Par exemple, les cartes mères des processeurs Intel 5 Series intégraient la ''Real Time Clock''. Il arrive aussi que la CMOS RAM soit intégrée au ''southbridge''. Par contre, sur la plupart des cartes mères, le BIOS est placé en-dehors du ''southbridge''. Il est arrivé que le ''chipset'' incorpore des cartes sons basiques, voire carrément des cartes graphiques (GPU). Les cartes son des ''chipsets'' étaient au départ assez mauvaises, mais ont rapidement augmenté en qualité, au point où plus personne n'utilise de carte son séparée dans son ordinateur. Quand aux GPU intégrés au ''chipset'' suffisaient largement pour une utilisation bureautique de l'ordinateur. Tant que l'utilisateur ne jouait pas à des jeux vidéos peu gourmands, le GPU du ''chipset'' suffisait. De plus, il consommait peu d'énergie et produisait peu de chaleur, le ''chipset'' avait juste à être refroidit par un simple radiateur. De nos jours, ils sont remplacées par les GPU intégrés aux processeurs, qui ont globalement les mêmes défauts et qualités. Sur certaines cartes mères, le ''southbridge'' est complémenté par un circuit de '''''Super IO''''', qui s'occupe des périphériques et bus anciens, comme le bus pour le lecteur de disquette, le port parallèle, le port série, et les ports PS/2 pour le clavier et la souris. De plus, ce circuit peut contenir beaucoup d'autres sous-circuits. Par exemple, il peut contenir des capteurs de température, les circuits qui contrôlent la vitesse des ventilateurs, divers ''timers'', et quelques autres. ===L'intégration du ''northbridge'' au processeur=== [[File:Intel 5 Series architecture.png|vignette|Intel 5 Series architecture]] Sur les cartes mères qui datent au moins des années 2000, depuis la sortie de l'Athlon64, le contrôleur mémoire a été intégré au processeur, ce qui est équivalent à dire que le ''northbridge'' est intégré au processeur. le ''southbridge'' est encore là, il est toujours connecté au processeur et aux périphériques. Concrètement, le processeur a un bus mémoire séparé, non-connecté au répartiteur de type ''southbridge''. Les raisons derrière cette intégration ne sont pas très nombreuses. La raison principale est qu'elle permet diverses optimisations quant aux transferts avec la mémoire RAM. De sombres histoires de ''prefetching'', d'optimisation des commandes, et j'en passe. La seconde est surtout que cela simplifie la conception des cartes mères, sans pour autant rendre vraiment plus complexe la fabrication du processeur. Les industriels y trouvent leur compte. Par la suite, la carte graphique fût aussi connectée directement sur le processeur. Le processeur incorpore pour cela des contrôleurs PCI-Express, et même d'autres circuits contrôleurs de périphériques. Le ''northbridge'' disparu alors complétement. Sur les cartes mères Intel récentes, le ''chipset'' est appelé le ''Platform Controler Hub'', ou PCH. l'organisation des bus sur la carte mère qui résulte de cette connexion du processeur à la carte graphique, est illustrée ci-dessous, avec l'exemple du PCH. ==La gestion thermique : sondes de température et ventilateurs== [[File:AMD heatsink and fan.jpg|vignette|Section de la carte mère avec dissipateur thermique et ventilateur en aluminium au-dessus du processeur AMD. À côté, on peut voir un dissipateur thermique plus petit, sans ventilateur, au-dessus d'un autre circuit intégré de la carte mère.]] Une fonctionnalité importante des cartes mères modernes est la gestion de la température, ainsi que le contrôle des ventilateurs. La carte mère surveille en permanence la température du processeur, éventuellement celle du GPU ou du ''chipset'', et réagit en conséquence. Les réactions ne sont pas très variées, la plus simple est de simplement faire tourner les ventilateurs plus ou moins vite. Mais la carte mère peut aussi réduire la fréquence du processeur en cas de température trop importante, si les ventilateurs ne suivent pas, voire déclencher un arrêt d'urgence si le processeur chauffe trop. Tout cela est regroupé sous le terme de '''gestion thermique'''. La carte mère incorpore un circuit pour la gestion thermique. Concrètement, le circuit varie pas mal selon la carte mère. Il peut faire partie du ''chipset'', précisément dans le ''southbridge''. Mais il se peut aussi qu'il soit séparé des autres, soudé sur la carte mère. Dans ce qui suit, nous partons du principe qu'il s'agit d'un microcontrôleur placé sur la carte mère ou intégré au ''chipset''. Nous l'appellerons le '''microcontrôleur de surveillance hardware'''. Le microcontrôleur de surveillance lit la température et décide comment commander les ventilateurs. La mesure est généralement directe, par l'intermédiaire d'un bus plus ou moins dédié. Par exemple, sur les anciens processeurs Core 2 Duo d'Intel, le bus était appelé le bus PECI. Il peut aussi lire indirectement la température via le ''chipset'' de la carte mère. Mais il existe une voie alternative, où le processeur ordonne directement d'augmenter la vitesse des ventilateurs, sans lecture des températures. Pour cela, il est connecté au microcontrôleur de surveillance, avec un fil dédié. Si le processeur met à 1 ce fil dédié, le microcontrôleur de surveillance réagit immédiatement en faisant tourner les ventilateurs plus vite. [[File:Gestion thermique carte mère.png|centre|vignette|upright=2|Gestion thermique carte mère]] Pour l'anecdote, le microcontrôleur de surveillance des PC était initialement un contrôleur de clavier PS/2, le "Keyboard Controller BIOS". Et ce contrôleur disposait déjà d'un fil connecté à l'entrée RESET du processeur, ce qui fait qu'il est techniquement possible de redémarrer son ordinateur par l'intermédiaire du contrôleur de clavier... Vu qu'il y avait déjà un microcontrôleur présent sur la carte mère, il a été décidé de le réutiliser pour des tâches autres, comme la gestion thermique, de la gestion des tensions d'alimentation, des régulateurs de tension, le démarrage (normal ou via réseau), la mise en veille, etc. De nos jours encore, le microcontrôleur de surveillance gère le touchpad. ===La mesure de la température : les sondes thermiques=== Le microcontrôleur de surveillance contrôle la vitesse du ventilateur en fonction de la température mesurée. Pour cela, le microcontrôleur de surveillance est relié à une ou plusieurs sondes qui mesurent la température. De nos jours, la sonde est intégrée dans le processeur. La sonde thermique du processeur peut être complétée par des sondes sur la carte mère. Il y a aussi des sondes dans le disque dur, le GPU, parfois dans la mémoire RAM, etc. Mais le gros du travail est réalisé par une sonde intra-processeur. Pour mesurer la température, le processeur incorpore un capteur de température, souvent appelé la '''diode thermique'''. Le terme implique qu'il s'agit d'une diode qui est utilisée pour mesurer la température. C'était effectivement le cas auparavant, au tout début de l'informatique. Mais de nos jours, on utilise des senseurs différents, généralement basés sur des transistors configurés de manière à marcher comme une diode. Il faut dire que transistors et diodes sont basés sur des jonctions PN, ce qui fait qu'un transistor peut émuler une diode, mais passons. L'implémentation originale avec une diode est assez simple à comprendre. La tension aux bornes d'une diode est égale à ceci : : <math>\text{Tension aux bornes d'une diode} = \text{Tension de base} - K \times \text{Température}</math> En clair, plus la température est élevée, plus la tension aux bornes de la diode chute. Dit autrement, une diode laisse d'autant mieux passer le courant. Elle chute assez rapidement, au rythme de 2 milli-volts pour chaque degré de plus. Le coefficient K vaut donc <math>- 2 mV</math>. Au final, cela donne une différence d'une centaine de millivolts aux hautes températures. Et cela peut se mesurer assez bien. La tension résultante est ensuite convertie soit en tension, soit en un nombre codé en binaire par un convertisseur analogique-numérique. Le processeur contient au moins une diode thermique, qui est placée à l'endroit le plus susceptible de chauffer. Il y en a généralement une par cœur, afin de gérer individuellement la température de chaque cœur. Généralement, la température mesurée est convertie en digital/numérique et est mémorisée dans un registre, qui est très régulièrement mis à jour. Le registre peut même être consulté par le logiciel, ce qui explique que de nombreux logiciels de surveillance matérielles permettent de connaitre en temps réel les températures du CPU, du GPU, de la mémoire, du SSD, etc. ===Le ''throttling'' du CPU et l'arrêt d'urgence en cas de surchauffe=== Il arrive que le processeur chauffe trop, alors que les ventilateurs tournent à leur vitesse maximale. Dans ce cas, la solution est de réduire la fréquence du processeur et sa tension, afin qu'il consomme moins et donc chauffe moins. On dit que le processeur '''''throttle''''', la technique qui réduit immédiatement la fréquence en cas de surchauffe est souvent appelée le '''''throttling'''''. Le ''throttling'' peut s'implémenter dans le processeur ou dans le microcontrôleur de surveillance, les deux vont souvent de pair. Mais l'implémentation dans le processeur est la plus simple. L'implémenter est assez simple. On rappelle que le processeur contient un multiplieur de fréquence configurable qui lui permet de régler en direct sa fréquence, de même qu'il contient un régulateur de tension interne lui aussi configurable. Il y a la même chose sur la carte mère. Les circuits de ''throttling'' lisent la mesure provenant de la diode thermique, puis configurent les multiplieurs de fréquence/tension. Une température trop forte peut endommager le processeur, définitivement. Il y a un seuil de température au-delà duquel le processeur est en danger et peut fondre, prendre feu, ou tout simplement se dégrader. La température que le processeur ne doit en aucun cas dépasser est appelée la '''température de sureté'''. Au-delà de la température de sureté, la température est tellement élevée que le processeur peut être endommagé et doit immédiatement être mis en pause. Pour éviter cela, le processeur est arrêté de force en cas de température trop forte. Dans ce cas, c'est autant le processeur que le microcontrôleur de surveillance qui sont impliqués. Si la température continue d'augmenter malgré le ''throttling'', ou qu'elle est tout simplement trop forte, le processeur déclenche un arrêt d'urgence et le microcontrôleur de surveillance l'exécute. Le processeur a une sortie PROCHOT qui indique que la température de sureté est dépassée, qui est reliée sur une entrée dédiée du microcontrôleur de surveillance. Lorsque le microcontrôleur de surveillance détecte un 1 sur le fil PROCHOT, il déclenche immédiatement un arrêt d'urgence. [[File:Gestion thermique CPU.png|centre|vignette|upright=2|Gestion thermique CPU]] ===Le contrôle des ventilateurs=== Le ventilateur principal sur une carte mère est le plus souvent du ventilateur du processeur, placé au-dessus du radiateur. Mais il y a parfois des ventilateurs placés dans le boitier ou sur le ''chipset'', qui sont eux aussi commandés par la carte mère. Ils servent à dissiper la chaleur produite par le fonctionnement de l'ordinateur, qui est d'autant plus forte que le processeur travaille. Autrefois, les ventilateurs tournaient en permanence, tant que l'ordinateur était allumé. Je parle là d'un temps datant d'avant les années 90, et encore. Mais depuis, les ventilateurs ne sont pas utilisés au maximum en permanence. A la place, la vitesse des ventilateurs s'adapte aux besoins. Précisément, ils s'adaptent à la consommation du processeur : plus le processeur fait de calcul, plus il émet de chaleur, plus les ventilateurs tournent rapidement. Dans le cas le plus simple, le microcontrôleur de surveillance se contente d'allumer ou d'éteindre le ventilateur. Le résultat est un ventilateur qui tourne à plein pot ou s'arrête totalement. Le ventilateur était allumé au-dessus d'un certain seuil, éteint sous ce seuil. Pour simplifier, nous allons appeler cette technique la '''gestion des ventilateurs à un seuil'''. Elle n'est pas très efficace, mais c'était suffisant sur des processeurs assez anciens, qui pouvaient se contenter du radiateur au repos, mais devaient allumer le ventilateur quand on leur demandait plus de travail. L'inconvénient est que le confort acoustique est perfectible. Les autres techniques qui vont suivre contrôlent plus finement la vitesse du ventilateur. Plus la température est importante, plus le ventilateur tourne vite, jusqu’à un certain point. Dans le détail, le microcontrôleur utilise une '''gestion des ventilateurs à deux seuils'''. Intuitivement, on sait que la vitesse du ventilateur augmente avec la température, jusqu'à atteindre une vitesse maximale. Mais il est aussi important d'imposer une vitesse minimale au ventilateur, même à de très basses températures. Les raisons à cela sont assez nombreuses, l'une d'entre elle est que cela permet un refroidissement minimal si la sonde de température dysfonctionne. Entre les deux seuils de température précédents, la vitesse augmente avec la température d'une manière relativement proportionnelle, linéaire. [[File:Controle des ventilateurs.png|centre|vignette|upright=2|Contrôle des ventilateurs]] [[File:2006 0703molex0002.JPG|vignette|Exemple de connecteur de ventilateur, avec seulement trois pins (VDD, O Volt, Tension de commande).]] Maintenant, on peut se demander comment commander la vitesse des ventilateurs. Les ventilateurs sont connectés à la carte mère via un connecteur, qui contient un fil pour la tension d'alimentation, un autre pour la masse, et un ou deux fils de contrôle. Le premier envoie au ventilateur une '''tension de commande''' qui indique à quelle vitesse il doit tourner. Le second, le '''fil de ''monitoring''''', indique à la carte mère à quel vitesse le ventilateur tourne. Sur le fil de monitoring, le ventilateur envoie un signal à une certaine fréquence, qui correspond à la fréquence de rotation du ventilateur. Il y a plusieurs méthodes concernant la tension de commande. Avec la plus simple, la tension de commande est proportionnelle à la vitesse de rotation. Prenons par exemple un ventilateur pouvant tourner de 0 à 1000 RPM (rotations par minute). Si la tension de commande est de 5 volts, alors une tension de 0 volts donnera 0 RPM, la tension maximale de 5V donnera 1000 RPM, une tension de 2 volts donnera 400 RPM, une tension de 3 volts donnera 600 RPM, etc. Le problème est que contrôler finement une tension est quelque peu compliqué, car cela demande d'utiliser des circuits analogiques, qui sont complexes à fabriquer. Une méthode plus utilisée actuellement est d'utiliser un signal modulé par PWM, un terme barbare dont la signification est pourtant assez simple. Le ventilateur est contrôlé par un signal d'horloge d'une fréquence de 25 KHz. Le moteur du ventilateur est allumé quand le signal d'horloge est à 1, éteint quand il est à 0. Avec l'inertie, le ventilateur continue à tourner quand le signal d'horloge est à 0 et il ralentit assez peu. Le ventilateur accélère quand le signal d'horloge est à 1, mais ralentit quand il est à 0. La vitesse instantanée du ventilateur fluctue donc lors d'une période, mais sa vitesse moyenne est bien définie. Intuitivement, la signal d'horloge est à 1 la moitié du temps, à 0 l'autre moitié. La vitesse moyenne est donc la moitié de la vitesse maximale. Mais ce n'est pas le cas. L'idée est alors de trifouiller le signal d'horloge, en modulant la durée où il est à 1, mais sans changer la fréquence. En clair, on module le '''rapport cyclique''' (''duty cycle''), le pourcentage d'une période où le signal d'horloge est à 1. Plus le rapport cyclique est grand, plus le ventilateur tourne vite. Pour le dire en une phrase : la tension de commande est un signal d'une fréquence de 25 KHz, dont le rapport cyclique contrôle la vitesse du ventilateur. [[File:PWM duty cycle with label.gif|centre|vignette|upright=2|Signaux d'horloge asymétriques]] Typiquement, le rapport cyclique va de 30% à 100%. A 100%, le ventilateur tourne en permanence, le signal d'horloge devient un signal constant, le ventilateur va a sa vitesse maximale. En-dessous de 30%, le comportement dépend fortement de la carte mère et du mécanisme de contrôle du ventilateur. Le ventilateur est généralement éteint, ou alors il ne peut pas tourner à moins de 30% de va vitesse maximale. ==Les circuits de gestion de l'alimentation== Une partie importante de la carte mère est liée à l'alimentation électrique. Le '''sous-système d'alimentation''' reçoit de l'électricité de la part du connecteur d'alimentation, et génère les tensions demandées par le processeur, la mémoire, etc. Le sous-système d'alimentation est très complexe et comprend un mélange de composants analogiques, numériques, et d'autres purement électriques. Mais il est intéressant d'en parler. Ses fonctions sont très diverses : alimenter les composants avec les tensions adéquates, vérifier la stabilité de l'alimentation, détecter les problèmes de tension, gérer l'allumage et la mise en veille, etc. En cas de problème, il peut déclencher un ''reset hardware''. ===La génération des tensions pour chaque composant=== Le processeur, la mémoire, et les différents circuits sur la carte mère, sont alimentés à travers celle-ci. Mais ils ont chacun besoin d'une tension bien précise, qui varie d'un composant à l'autre. Par exemple, la tension d'alimentation du processeur n'est pas celle de la mémoire RAM, qui n'est pas non plus celle du ''chipset''. Il y a donc des composants qui transforment la tension fournie par l’alimentation en tensions adéquates. La carte mère est alimentée par une tension de base, qui provient de la batterie sur un ordinateur portable/smartphone, du bloc d'alimentation pour un PC fixe ou serveur. Les PC fixes suivent le format ATX, qui précise que le bloc d'alimentation doit fournir trois tensions de base : une de 3,3V, une autre de 5V et une autre de 12V. Les tensions de base passe alors à travers un ou plusieurs '''régulateurs de tension''', qui fournissent chacun une tension de sortie à la bonne valeur pour soit le processeur, soit la mémoire, soit un autre circuit. [[File:Voltage Regulator connections-en.svg|centre|vignette|upright=2|Voltage Regulator connections-en]] [[File:Voltage Regulator.png|vignette|Deux régulateurs de tension.]] Un régulateur de tension est un circuit qui a au moins trois broches : une entrée pour la tension de base, une sortie pour la tension voulue, et une troisième entrée qui ne nous intéresse pas ici. Il existe des régulateurs qui fournissent une tension de 3,3V, d'autres qui fournissent du 1V, d'autres du 0.5V, d'autres du 2V, etc. Chaque régulateur est conçu pour sortir une tension bien précise. On ne peut pas, en théorie, configurer un régulateur de tension pour choisir sa tension de sortie. Les ordinateurs modernes utilisent des régulateurs de tension améliorés, appelés des '''modules de régulation de la tension'''. Dans ce qui suit, nous utiliserons l'abréviation VRM, pour ''Voltage Regulator Modules''. Il s'agit de composants très complexes, avec de nombreuses fonctionnalités. Une fonctionnalité importante des VRM est que l'on peut les activer ou les désactiver. Concrètement, cela permet d'allumer ou couper une tension électrique suivant les besoins. C'est utilisé lors de l'allumage de l'ordinateur, pour l'éteindre, le redémarrer, pour mettre certains composants en veille, etc. L'activation/désactivation d'un VRM se fait via une entrée de commande nommée ''Enable''. Mettez un 1 sur cette entrée pour activer le VRM, un 0 pour le désactiver. Il existe des '''''smart VRM''''', qui implémentent de nombreuses fonctionnalités. Par exemple, il est possible de configurer la tension de sortie voulue parmi un choix de quelques tensions prédéterminées. Ce qui peut servir pour modifier la tension d'alimentation d'un composant à la volée, chose utile pour mettre un composant en veille. De plus, le VRM surveille en permanence sa température, la tension de sortie, le courant qui le traverse, et d'autres données importantes. Le microcontrôleur de surveillance peut accéder en temps réel à ces données, afin de détecter tout problème. Il peut ainsi détecter une défaillance de la tension de sortie du VRM, ou détecter qu'un VRM surchauffe. Pour résumer, les ''smart VRM'' peuvent être configurés et/ou surveillés. Pour cela, le ''smart VRM'' communique avec l'extérieur par l'intermédiaire d'un bus dédié. Le bus en question est le bus ''Power Management Bus'', une variante du bus ''System Management Bus'' (SMBus), qui lui-même est une variante du bus i²c. Il s'agit d'un bus très simple, qui demande juste deux fils pour connecter le VRM à l’extérieur. Les ''smart VRM'' sont généralement connectées au microcontroleur de surveillance, parfois aux ''chipset'', parfois les deux. ===La séquence d'allumage des VRM=== Un point important est que chaque composant sur la carte mère utilise souvent plusieurs tensions d'alimentation. Par exemple, le processeur a souvent besoin de plusieurs tensions d'alimentation. Idem pour les cartes graphiques, qui demandent souvent d'avoir à leur disposition d'avoir plusieurs tensions distinctes. Lors du démarrage, le composant requiert d'activer ces tensions dans un ordre bien précis. Expliquer pourquoi est compliqué, mais disons que sans cela, le composant le fonctionne tout simplement pas. Il y a donc un ordre d'allumage des tensions, décrit par une '''séquence d’amorçage des VRM'''. Et la même chose a lieu lors de la mise en veille : il faut désactiver les VRMs dans le bon ordre, souvent l'ordre inverse du démarrage. La sortie de mise en veille demande de faire comme lors de l’allumage, à quelques détails près. L'ordre en question est géré via une fonctionnalité importante des VRM : on peut les activer ou les désactiver à la demande. Pour cela, ils disposent d'une entrée de commande qui active ou désactive le régulateur de tension. Si on envoie un 1 sur cette entrée, le VRM s'active. A l'inverse, un 0 sur cette entrée désactive le VRM. L'activation des tensions est le rôle d'un circuit spécialisé relié à chaque VRM, il a une sortie dédiée à chaque VRM, sur laquelle il envoie un 0 ou un 1 pour l'activer au besoin. Nous l’appellerons le '''''sequencing chip'''''. Il s'agit parfois d'un circuit dédié, mais il est souvent intégré directement dans le microcontrôleur de surveillance hardware. Mais vous vous posez sans doute la question suivante : comment est alimenté le microcontrôleur de surveillance ? La réponse est que le microcontrôleur est relié à une tension de 3,3V qui est toujours active, qui provient du connecteur d'alimentation. Dès que vous branchez votre PC sur secteur, le 3,3 volts va alimenter le microcontrôleur de surveillance. Même si vous laissez votre ordinateur éteint, le microcontrôleur de surveillance est actif tant que le secteur est branché. Par contre, dès que vous appuyez sur le bouton d'alimentation, le microcontrôleur de surveillance démarre la séquence d’amorçage des VRM. D'ailleurs, le microcontrôleur de surveillance est directement connecté au bouton d'alimentation, il lui réserve une entrée dédiée. [[File:Alimentation du microcontroleur de surveillance et liaison aux VRM.png|centre|vignette|upright=2|Alimentation du microcontroleur de surveillance et liaison aux VRM]] Il faut noter que le microcontrôleur de surveillance n'est pas le seul alimenté ainsi. En réalité, une partie du ''chipset'' de la carte mère et quelques circuits annexes le sont aussi. Mais nous verrons cela plus tard. ===La stabilité de l'alimentation au démarrage=== Lors d'un démarrage ou d'un redémarrage, le processeur est allumé par un signal RESET. Il y a une petite différence entre l'allumage et le redémarrage, qui tient dans la manière dont la tension d'alimentation et l'horloge sont gérées. Lors d'un ''reset hardware'', le processeur reste alimenté, il n'est pas coupé. Il réinitialise ses registres, remet à zéro pas mal de circuits, mais l'alimentation reste maintenue. Lors du démarrage, ce n'est pas le cas : l'alimentation est allumée, la tension d'alimentation passe de 0 à 12 ou 5 volts. Au passage, si vous débranchez votre ordinateur avant de le rebrancher, ce n'est pas un ''reset hardware'', car vous éteignez l'ordinateur avant de le relancer. L'alimentation est coupée entre-temps. Lors du démarrage, avant de générer un signal RESET, il faut attendre que la tension d'alimentation se stabilise, de même que le signal d'horloge. Si les tensions d'alimentation ne marchent pas comme prévu, le démarrage n'a pas lieu pour éviter d'endommager le processeur, idem pour le signal d'horloge. Pour cela, la carte mère contient deux circuits séparés. Le '''''Power-on reset''''', temporise en attendant que la tension d'alimentation se stabilise. Le ''Power-on reset'' vérifie les tensions 12 V, 5 V et 3,3 V, et n'autorise le RESET du processeur que si celles-ci sont stables et à la bonne valeur. Pour cela, il est relié au microcontrôleur de surveillance, sur une entrée de ce dernier. Le microcontrôleur de surveillance ne démarre la séquence d'allumage des VRM que s'il reçoit le signal POR. Ainsi que d'autres signaux, comme celui de l'''oscillator startup timer''. ===Les défaillances de l'alimentation=== Une fois l'ordinateur allumé, le processeur fonctionne. On s'attend à ce que la tension et la fréquence soient stables, mais il est parfaitement possible que la tension soit soudainement déstabilisée, par exemple lorsqu'on débranche la prise, une coupure de courant, un problème matériel avec les régulateurs de tension, des condensateurs de la carte mère qui fondent, etc. Un circuit appelé le '''''Low-voltage detect''''' surveille en permanence la tension d'alimentation, pour détecter de telles défaillances et générer un arrêt d'urgence. Il est souvent fusionné avec le ''Power-on reset'' en un seul circuit. Rien d'étonnant à cela : les deux sont reliés à la tension d'alimentation et vérifient sa stabilité. Typiquement, le ''Low-voltage detect'' permet de détecter si la tension d'alimentation descend sous un seuil pendant un certain temps, typiquement sous 2-3 volts pendant quelques centaines de millisecondes. Le ''Low-voltage detect'' est implémenté différemment entre un PC moderne et les cartes mères hors-PC. Sur PC, c'est rarement un circuit à part, il est intégré dans le microcontrôleur de surveillance. Et c'est encore plus vrai si la carte mère utilise des ''smart VRM''. Il suffit alors de connecter des ''smart VRM'' au microcontrôleur de surveillance, via un bus PMBUS, pour que celui-ci puisse vérifier les tensions de chaque VRM en temps réel. Mais sur les cartes mères hors PC, le ''Low-voltage detect'' est souvent un circuit à part. Il faut dire qu'elles n'incorporent pas forcément de microcontrôleur de surveillance, ni de ''smart VRM'', car leur système d'alimentation est beaucoup plus simple. Aussi, un circuit spécialisé est utilisé à la place. La gestion d'une défaillance de l'alimentation est aussi gérée différemment entre un PC et un microcontrôleur. La raison est qu'un PC peut fonctionner durant quelques millisecondes, grâce à la présence de condensateurs sur la carte mère. Ils maintiennent la tension d'alimentation pendant quelques millisecondes, ce qui lui laisse le temps de faire quelques sauvegardes mineures et d'éteindre l'ordinateur proprement. Un arrêt d'urgence avec l'entrée NMI est donc acceptable, si les condensateurs sont dimensionnés pour. Par contre, les microcontrôleurs ne sont pas dans ce cas-là, surtout dans les systèmes alimentés sur batterie. Là, le problème n'est pas tellement une coupure soudaine de l'alimentation, mais une baisse progressive de la tension, au fur et à mesure que la batterie se vide. Typiquement, si la batterie se vide progressivement, il arrive un moment où la tension chute trop bas, et reste basse tant que la batterie n'est pas rechargée. Dans ce cas, le processeur n'est pas éteint, mais maintenu en état de RESET tant que la tension est trop faible. Dès que la tension remonte, le processeur redémarre. On parle alors de '''''brown-out reset'''''. ===Les domaines de puissance et le ''standby domain''=== Le microcontrôleur de surveillance est alimenté par une tension d'alimentation dite de ''standby'', qui est présente dès que l'ordinateur est branché au secteur, même éteint. Et c'est aussi le cas d'une partie du ''chipset'', du contrôleur USB et du contrôleur Ethernet. Ils sont tous partiellement alimentés même ordinateur éteint. C'est grâce à ça qu'un ordinateur peut être allumé via le réseau. L'ensemble des composants alimentés même ordinateur éteint est appelé le '''''Stand By Domain'''''. [[File:Standby domain.png|centre|vignette|upright=2|Standby domain]] Le ''Standby Domain'' s'oppose aux circuits qui ne sont allumés qu'une fois qu'on a démarré l'ordinateur. Il est parfois appelé le '''''Wakeup Domain'''''. Mais ce dernier n'est pas uniforme. En réalité, il est lui-même séparé en plusieurs '''domaines de puissance''', chacun relié à un VRM et alimenté par une tension d'alimentation précise. Par exemple, la mémoire RAM n'est pas alimentée par le même VRM que le processeur. Il est ainsi possible d'éteindre le processeur tout en maintenant la RAM allumée. C'est d'ailleurs ce qui est fait lors de la mise en veille normale de l'ordinateur : le CPU est éteint, mais la RAM continue à être alimentée pour ne pas perdre ses données. [[File:Les différents power domains d'une carte mère.png|centre|vignette|upright=2|Les différents power domains d'une carte mère : CPU, RAM, standby et autres]] Outre le ''chipset'' et le microcontroleur de surveillance, le ''Standby Domain'' contient des tas de bus spécialisés dans la gestion thermique ou la gestion de l'alimentation. Ils sont reliés au microcontroleur de surveillance, à la ''glue logic'' et au ''chipset'', ainsi qu'aux VRM, aux ventilateurs, aux sondes de température, etc. Nous avons mentionné le bus PECI d'Intel qui permet au microcontrôleur de surveillance et au ''chipset'' de lire la température du processeur. Mais ce n'est pas le seul. L'un des tout premier bus utilisé dans cet optique était le bus SMBUS, pour '''''System Management Bus''''', dont l'objectif initial était d'interconnecter un grand nombre de composants peu rapides, soudés à la carte mère. Il est assez spécialisé dans la gestion thermique et de l’alimentation, mais est aussi utilisé pour gérer les LEDs RGB et quelques autres fonctionnalités dans le genre. Le PMBUS est utilisé pour commander les ''smart VRM'' est une version améliorée de ce SMBUS. ===Les ''Power States''=== Pour rappel, un ordinateur peut être dans plusieurs états de fonctionnement : en veille, allumé, éteint. Dans chaque état, certains composants sont allumés, d'autres éteints. Dans le détail, ces états de fonctionnement sont appelés des '''''Power State'''''. Sur les processeurs x86, ils sont normalisés par la norme ACPI. Elle définit plusieurs ''Power State'' distincts. * S0 : ordinateur allumé, en fonctionnement ; * S0 amélioré, facultatif : forme spécifique de veille ; * S1, S2, S3 : veille normale ; * S4 : veille prolongée ; * S5 Standby : secteur branché, ordinateur éteint ; * G3 Mechanical OFF : sécteur débranché. En mode G3, le secteur est débranché, rien n'est alimenté. En mode S5, le ''standby domain'' est alimenté, pas le reste. En mode S0, tout est alimenté, ou presque. Les modes S1, S2 et S3 sont aussi appelés la veille '''''suspend to RAM''''', le nom est assez transparent. La RAM est alimentée, mais pas le processeur. Le ''standby domain'' est alimenté et c'est pour ça qu'un ordinateur en veille se réveille quand on appuie sur une touche du clavier. Les trois ne sont pas équivalents, mais les différences sont mineures, au point que seul le S3 est réellement utilisé de nos jours. Le mode S4 veille prolongée est aussi appelé le mode '''''suspend to disk'''''. Avec lui, l'ordinateur est quasiment éteint, même la RAM est désactivée. La RAM de l'ordinateur est recopiée dans un fichier sur le disque dur, pour être restauré en RAM lors de la sortie de mise en veille. Évidemment, la sauvegarde de la RAM sur le disque dur est assez lente, ce qui fait que la mise en veille n'est pas immédiate. Si les premières implémentations utilisaient le BIOS, ce n'est plus le cas. Il peut en théorie être implémenté en logiciel, mais il est géré en partie par le système d'exploitation et le matériel, que ce soit sur Linux et Windows. Tant que le matériel est intégralement compatible avec la norme ACPI, la mise en hibernation est possible. Les transitions entre ces différents états/''power state'', sont illustrées ci-dessous. Elles sont gérées en coopération par le processeur, le ''chipset'' et le microcontroleur de périphérique. Lors de la mise en veille, le processeur sauvegarde son état de manière à reprendre là où il en était. Puis, il prévient le microcontrôleur de surveillance et le ''chipset'' pour prévenir que l'ordinateur peut être mis en veille. Là, les tensions d'alimentation du CPU sont coupées. Lors de la sortie de veille, les tensions sont rallumées par le microcontrôleur de surveillance, puis un signal RESET est émis. [[File:Power state x86.png|centre|vignette|upright=2|Power state x86]] Il faut noter que chaque périphérique peut aussi avoir des ''power state'' similaires. Par exemple, un SSD peut avoir un mode basse consommation, qui est utilisé si le SSD n'est pas utilisé mais que l'ordinateur est allumé. Typiquement, les composants/périphériques disposent de quatre états : un mode éteint, un mode veille, un mode basse consommation et un mode fonctionnement normal. Le composant peut être mis en veille, où il consomme un petit peu mais est plus rapide à réactiver qu'un SSD éteint. Il peut aussi fonctionner en mode basse consommation, où les performances sont un peu diminuées et certaines fonctionnalités ne sont pas disponibles. ===La gestion logicielle des ''Power States'' et de l'économie d'énergie=== Autrefois, la transition entre ces états était gérée par le microcontrôleur de surveillance, qui répondait aux boutons ON/OFF et celui de mise en veille s'il existait. Mais le logiciel ne pouvait pas éteindre l'ordinateur de lui-même, encore moins le mettre en veille. A vrai dire, la mise en veille normale n'existait pas forcément, seule la mise en veille prolongée existait et était gérée purement en logiciel. Il existait des mises en veille basiques, qui se résumaient à éteindre l'écran et le disque dur, mais le CPU fonctionnait normalement, sa fréquence n'était pas stoppée ni réduite. LA gestion des ''power state'' des périphériques n'était pas gérée du tout. [[File:Win95Build216 Shutdown.png|centre|vignette|upright=2|Windows 95 ne pouvait pas éteindre l’ordinateur, il fallait appuyer sur le bouton ON/OFF.]] L'apparition du standard APM (''Advanced Power Management'') a permis au logiciel de gérer les ''power state'', mais aussi d'autres fonctionnalités d'économie d'énergie. Le BIOS gérait tout ce qui avait trait à la consommation d'énergie, il était au centre du standard. Il pouvait désactiver des périphériques, les mettre en veille de manière sélective, les mettre en état basse consommation, etc. Le logiciel pouvait envoyer des ordres au BIOS pour cela, en passant par l'intermédiaire d'in pilote de périphérique dédié, appelé ''driver APM''. Le standard définissait comment le BIOS et le logiciel devaient communiquer entre eux. [[File:APM-Layers.svg|centre|vignette|upright=2|APM]] De nos jours, le standard APM a été remplacé par le '''standard ACPI''' (''Advanced Configuration and Power Interface''). Ce standard ne gère pas que l'économie d'énergie, mais aussi des fonctionnalités comme la découverte du matériel (détecter le matériel installé dans le PC au démarrage). Il ne se base plus du tout sur le BIOS, contrairement au format APM, mais laisse le système d'exploitation gérer la consommation énergétique du PC. Au passage, les temps de mise en veille sont gérés par des ''timers'' dédiés, appelés '''''timers'' d'inactivité'''. Vous savez sans doute qu'il est possible de gérer combien de temps doit d'écouler avant d'éteindre l'écran, de mettre l'ordinateur en veille. Hé bien ces temps sont gérés par des ''timers'' dédiés, faisant partie de la norme ACPI. Dès que Windows détecte un ordinateur inactif, il initialise le ''timer'' avec la durée configurée et laisse le ''timer'' faire son travail. Le ''timer'' est réinitialisé en cas d'activité. Si le ''timer'' déborde, il génère un signal dit d'interruption à destination du processeur, qui réagit immédiatement et met en veille l'ordinateur. ==La ''glue logic'' et les circuits annexes== Pour résumer, une carte mère intègre de nombreux circuits très différents. Mais avec la loi de Moore, de nombreux circuits distincts ont pu être fusionnés en un seul circuit. Par exemple, le ''chipset'' regroupe de nombreux circuits autrefois distincts, mais nous détaillerons cela dans le chapitre sur les contrôleurs de périphériques. De même, le microcontrôleur de surveillance a beaucoup de fonctions différentes : la gestion de l'alimentation au sens large, la gestion thermique, et bien d'autres que nous n'avons pas encore abordées. Et toutes ces fonctions étaient autrefois le fait de plusieurs circuits séparés. Une carte mère contient donc deux composants principaux : le microcontroleur de surveillance et le ''chipset''. Et à cela il faut ajouter tous les bus électroniques, qui relient le ''chipset'', le microcontroleur de surveillance, les connecteurs, le processeur, la RAM, le disque dur, les ports PCI-Express, et tout ce qui est sur la carte mère. Mais à tout cela, il faut ajouter un dernier composant : la '''''glue logic'''''. La ''glue logic'' regroupe tout le reste, à l'exception de composants analogiques/électriques comme des condensateurs de découplage et autres. Il s'agit d'un ensemble de circuits qui n'a pas de fonction précise et dépend fortement de la carte mère. Formellement, son rôle est de servir à coller ensemble des circuits séparés. La carte mère contient un ''chipset'', le µcontroleur de surveillance, le CPU, la RAM, et d'autres composants qui sont fabriqués séparément, et qui doivent être "collés ensemble" pour obtenir la carte mère finale. La ''glue logic'' s'occupe de ce collage, de cet interfaçage. Elle s'occupe majoritairement de la gestion thermique et des tensions, mais pour des fonctions qui ne sont pas prises en charge par le ''chipset'' ou le µcontroleur. Mais ce n'est pas sa seule fonction. Il est difficile de faire des généralités sur la ''glue logic'', car elle varie énormément d'une carte mère à l'autre. Elle est souvent implémentée avec des FPGA, sur les carte mères actuelles. Mais les anciennes cartes mères utilisaient des composants séparés. La ''glue logic'' prenait donc beaucoup de place, ce qui n'est plus trop le cas maintenant. ==Les chips de sécurité== Depuis la décennie 2010, les cartes mères incorporent des chips spécialisés dans la sécurité informatique. Vous avez peut-être entendu parler des puces TPM, rendues nécessaires pour passer à Windows 11, de l'Intel Management Engine, ou de son équivalent chez AMD. De telles puces ont une utilité mal compris par le grand public, et souvent décriée pour, paradoxalement, des raisons de sécurité. Quelques-uns les ont accusées de contenir des ''backdoors''. ===Le ''Trusted Platform Module''=== Le ''Trusted Platform Module'', ou TPM, est ce qui s'appelle un '''processeur cryptographique sécurisé'''. Concrètement, il s'agit d'un circuit spécialisé dans tout ce qui est chiffrement. Il a deux rôles principaux : générer et stocker des clés de chiffrement. Il peut par exemple générer des nombres aléatoires, des clés RSA, etc. En théorie, un processeur cryptographique peut aussi servir d''''accélérateur cryptographique''', à savoir que le processeur CPU lui délègue les calculs cryptographiques. Il peut alors exécuter des fonctions de hachage cryptographiques comme SHA-1, etc. Disons qu'il peut être utilisé dès qu'il faut crypter ou décrypter des données Il peut aussi mémoriser certaines clés cryptographiques du système, de manière persistante, dans une mémoire EEPROM/FLASH dédiée, intégrée au TPM. Elles ne sont alors accessibles ni par le système d'exploitation, ni par l'utilisateur, ni par qui ou quoi que ce soit d'autres que le TPM. Outre le stockage des clés à l'intérieur du TPM, le TPM peut protéger une portion de la mémoire RAM afin d'y stocker des clés de cryptage/décryptage importantes. La portion de mémoire est appelée une '''enclave mémoire sécurisée'''. Elle est accessible uniquement par le TPM, mais est inaccessible par l'OS ou l'utilisateur, ou alors seulement partiellement accessible. Cela permet de sécuriser certaines clés cryptographiques pendant qu'elles sont utilisées. [[File:TPM 1.2 diagram.svg|centre|vignette|upright=2|TPM 1.2, diagramme.]] Les utilisations principales sont les trois suivantes le chiffrement des disques durs, la sécurité lors du démarrage et les DRMs. Le TPM sert en premier lieu pour '''encrypter les disques durs''' avec Bitlocker sous Windows ou son équivalent sous Linux/mac. Les clés utilisées pour crypter et décrypter un disque dur encrypté sont stockées dans le TPM et sont aussi utilisées à travers une enclave matérielle. Une utilisation plus controversée est celle des techniques de '''''Secure Boot''''', qui vise à protéger l’ordinateur dès le démarrage, pour stopper net les malwares qui infectent le BIOS ou les secteurs de boot. Mais le TPM peut aussi être utilisé pour implémenter le ''trusted computing'', un ensemble de techniques qui visent à identifier un ordinateur. Par identifier, on veut dire que le ''trusted computing'' attribue une identité à chaque ordinateur, afin de l'identifier parmi tous les autres. L'intention est d'implémenter des techniques permettant de ne décrypter des données que sur des ordinateurs bien précis et pas ailleurs. Le ''trusted computing'' fournit aussi des procédés afin d'éviter toute usurpation d'identité entre ordinateurs. Le tout se fait par des procédés matériels auxquels qu'aucun logiciel ne peut altérer, pas même le système d'exploitation, et pas même l'utilisateur lui-même (d'où certaines controverses). Elles servent surtout à gérer les DRM, des protections logicielles qui visent à empêcher le piratage de musique, jeux vidéos, films et autres. Les techniques en question attribuent au matériel une clé de sécurité inconnue de l'OS et de l'utilisateur. A sa création, chaque puce TPM se voit attribuer une clé de sécurité RSA de 2048 bits, qu'il est impossible de changer, et qui est différente d'une puce à l'autre. Avant de poursuivre, rappelons la différence entre clé privée et publique. L'algorithme RSA permet à deux entités de communiquer entre elles en s'échangeant des messages cryptés. Les messages sont encryptés avec une clé publique et décryptés avec une clé privée. La clé dont il est question pour le TPM est une clé privée. Elle permet d'identifier l'ordinateur de manière unique, ce qui sert pour les DRM ou pour authentifier l'ordinateur pour un quelconque login. Parmi les fonctionnalités du ''trusted computing'', voici quelques exemples. La technique de ''Sealed storage'' permet de lire des données encryptées uniquement sur une machine particulière. Les données sont encryptées par le TPM, qui ajoute des informations sur la configuration dans la clé de cryptage, dont sa clé TPM. La technique est utilisée pour les DRM. La technique de ''Remote attestation'' permet à un autre ordinateur d'être au courant des modifications effectuées sur l'ordinateur considéré. Le TPM est parfois une puce placée sur la carte mère, mais ce n'est pas le cas sur les PC commerciaux. A la place, le TPM est soit intégré au ''chipset'', soit intégré au processeur. Il en sera de même pour les circuits de sécurité que nous allons voir par la suite, qui font partie du CPU ou du ''chipset''. ===Le ''Management Engine'' d'Intel et l'''AMD Platform Security Processor''=== L''''''Intel Management Engine''''' (ME) et l''''''AMD Platform Security Processor''''' (PSP) sont des microcontrôleurs intégrés au ''chipset'' de la carte mère. Ils ont accès à tout le matériel de l'ordinateur, d'où sa place dans le ''chipset''. Ils sont actifs en permanence, même si l'ordinateur est éteint, ce qui fait qu'ils sont dans le ''standby domain''. Ils ont des fonctions très diverses, mais ils s'occupent de l'initialisation du ''chipset'' et du démarrage de l'ordinateur, de l'initialisation des périphériques, mais aussi de fonctionnalités de sécurité. En premier lieu, il agit comme un processeur cryptographique sécurisé, à savoir qu'il incorpore des accélérateurs cryptographiques (des circuits de calcul capables de crypter/décrypter des données avec des algorithmes comme AES, RSA, autres). Chez Intel, le tout est appelé l'OCS (''Offload and Cryptography Subsystem''), et est couplé à un système de stockage sécurisé de clés, ainsi qu'un contrôleur DMA (un circuit qui sert pour les échanges entre OCS et mémoire RAM). Le TPM vu précédemment est souvent intégré dans le ME/PSP. Il gère aussi d'autres fonctionnalités, comme des protections lors du démarrage de l’ordinateur, comme le ''secure boot'', ou l'Intel® Boot Guard. Des DRM gérés en hardware sont aussi disponibles. L'Intel ME était initialement basé sur un processeur ARC core et utilisait le système d'exploitation temps réel ThreadX. De nos jours, depuis la version 11 du ME, il utilise un processeur Intel Quark 32 bits et fait tourner le système d'exploitation MINIX 3. Il est possible pour le processeur principal (CPU) de communiquer avec le ME, via la technologie ''Host Embedded Controller Interface'' (HECI). Mais la communication est surtout utilisée pour la gestion thermique et d'alimentation. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Les techniques de réduction de la consommation électrique d'un processeur | prevText=Les techniques de réduction de la consommation électrique d'un processeur | next=Les bus et liaisons point à point (généralités) | nextText=Les bus et liaisons point à point (généralités) }} </noinclude> ozqvw0f9fmtljq6dqxzjzqtguhlunya Jeu de rôle sur table — Jouer, créer 0 67338 744046 741215 2025-06-03T15:21:58Z Cdang 1202 /* Sommaire */ avancement 744046 wikitext text/x-wiki {{Page de garde|image=Dadosvariasfaces.jpg|imagedesc=Différents types de dés utilisés dans les jeux de rôle|description= ''Ce wikilivre se trouve sur l'étagère [[Wikilivres:Étagère jeu|Jeu]].'' Ce wikilivre est consacré au '''jeu de rôle sur table''', ou '''jeu de rôle papier'''. Il concerne la manière de jouer, sans s'attacher à un jeu particulier, ainsi que la création en jeu de rôle, et la création de jeu de rôle : création « émergente » en cours de jeu (improvisation), création de scénario et de manière plus générale préparation de partie, création d'un cadre (univers fictionnel), création de règles (règles maison ou système complet). |avancement=Avancé |cdu= * {{CDU item|7|79}} }} == Sommaire == # [[/Qu'est-ce que le jeu de rôle ?/]] {{100}} # [[/Ma première partie/]] {{100}} # [[/Bienveillance et contrat ludique/]] {{100}} # [[/Préparer une partie/]] {{100}} # [[/Au cœur du jeu de rôle, la partie/]] {{100}} # [[/Créer une nouvelle règle/]] {{100}} # [[/Le hasard dans les jeux de rôle/]] {{100}} # [[/Probabilités des dés en jeu de rôle/]] {{100}} # [[/Créer des éléments du monde/]] {{75}} # [[/Créer un univers/]] {{75}} # [[/Créer un jeu de rôle/]] {{25}} ; Annexe # [[/Abréviations/]] {{100}} == Voir aussi == === Bibliographie === * {{ouvrage | prénom1 = Pierre | nom1 = Rosenthal | responsabilité1 = rédacteur en chef | et al. = oui | titre = Manuel pratique du jeu de rôle | collection = Casus Belli | numéro dans collection = HS25 | mois = mai | année = 1999 | éditeur = Excelsior publications | pages = 98 | format = A4 | lire en ligne = https://docs.google.com/file/d/0B-GYyxhvMf-PaUQ4OUVUMkFFQlk/ | présentation en ligne = http://www.ffjdr.org/manuel-pratique-du-jeu-de-role/ }} * {{ouvrage | langue = fr | prénom1 = Coralie | nom1 = David | directeur1 = oui | prénom2 = Jérôme | nom2 = Larré | directeur2 = oui | et al. = oui | titre = Mener des parties de jeu de rôle | éditeur = Lapin Marteau | collection = Sortit de l'auberge | numéro dans collection = 1 | année = 2016 | isbn = 978-2-9545811-4-9 | pages = 400 | format = 16,5 × 24 cm | présentation en ligne = http://www.lapinmarteau.com/jeux-et-accessoires-sortir-de-lauberge-01-mener-des-parties-de-jeu-de-role/ }} * {{ouvrage | langue = fr | prénom1 = Coralie | nom1 = David | directeur1 = oui | prénom2 = Jérôme | nom2 = Larré | directeur2 = oui | et al. = oui | titre = Jouer des parties de jeu de rôle | éditeur = Lapin Marteau | collection = Sortit de l'auberge | numéro dans collection = 2 | année = 2016 | isbn = 978-2-9545811-6-3 | pages = 368 | format = 16,5 × 24 cm | présentation en ligne = http://www.lapinmarteau.com/jeux-et-accessoires-sortir-de-lauberge-02-jouer-des-parties-de-jeu-de-role/ }} === Autres wikilivres === * [[Guide pour jeux de rôles]] === Liens externes === * Tartofrez, le blog de [[w:Jérôme Larré|Jérôme « Brand » Larré]] : ** {{lien web | url = http://www.tartofrez.com/category/5-trucs/ | titre = Rubrique « Cinq trucs »}} ; ** {{lien web | url = http://www.tartofrez.com/category/game-design/ | titre = Rubrique « Créer son jeu ''(game design)'' »}} ; ** {{lien web | url = http://www.tartofrez.com/category/theorie/ | titre = Rubrique « Théorie et ''game design'' »}}. * {{lien web | url = http://awarestudios.blogspot.co.uk/ | titre = Du bruit derrière le paravent}}, le blog de Grégory « Gregopor » Pogorzelski. * {{lien web | url = http://ptgptb.fr/ | titre = ''Places to go, people to be'' (ptgptb)}}, traduction d'articles sur le jeu de rôle. ** {{lien web | url = https://ptgptb.fr/accueil-ebooks | titre=Ebooks | site=ptgptb |consulté le=2023-03-09}}. * {{lien web | url = http://www.limbicsystemsjdr.com/ | titre = Limbic System}}, le blog de Frédéric Sintes. * {{lien web | url = http://www.legrog.org/ | titre = Le Guide du rôliste galactique (GRoG/roliste.com)}}, la plus grande base de données francophone de jeux de rôle. * {{lien web | url = https://courantsalternatifs.fr/forum/viewtopic.php?f=18&t=1209&p=7979#p7979 | titre = JdR et animation | auteur = Thomas Munier | site = Courants alternatifs | date = 2018-08-21 | consulté le = 2018-08-21}} * Podcasts : ** {{lien web | url = http://www.cendrones.fr/ | titre = Cendrones, la Voix D'altaride}}. ** {{lien web | url = http://www.lacellule.net/ | titre = La Cellule}}. * Forums ** {{lien web | url = http://www.subasylum.com/ | titre = Antonio Bay, village rôliste}} ** {{lien web | url = http://www.pandapirate.net/casus/ | titre = Casus non officiel}} ** {{lien web | url = http://forum.opale-roliste.com/ | titre = Opale rôliste}} ** {{lien web | url = http://www.reves-d-ailleurs.eu/ | titre = Rêves d'ailleurs}} * logiciels et sites d'aide en jeu et tables virtuelles : ** {{lien web | url = https://www.fantasygrounds.com/home/home.php | titre = Fantasy Grounds }} ** {{lien web | url = https://kanka.io/fr | titre = Kanka }} ** {{lien web | url = https://lets-role.com/ | titre = Let's Role }} ** {{lien web | url = https://rolisteam.org/ | titre = Rolisteam }} ** {{lien web | url = https://roll20.net/ | titre = Roll20 }} * jeux en licence libre : ** {{lien web | url = https://ogc.rpglibrary.org/index.php?title=Main_Page | titre = OGC (RPG Library Open Game Content Repository) consulté le=2025-03-20 }} ** {{lien web | url = https://legrumph.org/Terrier/public/jeux-complets | titre = Jeux de rôle complets |site=Le Terrier du Grümph | consulté le=2025-03-20 }} {{DEFAULTSORT:Jeu de role sur table Jouer creer}} [[Catégorie:Jeu de rôle sur table — Jouer, créer (livre)|*]] ak2lqzn75wfdrtp4i3jmb7wj4jf87u6 Les cartes graphiques/Les cartes accélératrices 3D 0 67392 744096 735604 2025-06-04T00:17:00Z Mewtow 31375 /* Les unités de texture sont intégrées aux processeurs de shaders */ 744096 wikitext text/x-wiki Il est intéressant d'étudier le hardware des cartes graphiques en faisant un petit résumé de leur évolution dans le temps. En effet, leur hardware a fortement évolué dans le temps. Et il serait difficile à comprendre le hardware actuel sans parler du hardware d'antan. En effet, une carte graphique moderne est partiellement programmable. Certains circuits sont totalement programmables, d'autres non. Et pour comprendre pourquoi, il faut étudier comment ces circuits ont évolués. Le hardware des cartes graphiques a fortement évolué dans le temps, ce qui n'est pas une surprise. Les évolutions de la technologie, avec la miniaturisation des transistors et l'augmentation de leurs performances a permit aux cartes graphiques d'incorporer de plus en plus de circuits avec les années. Avant l'invention des cartes graphiques, toutes les étapes du pipeline graphique étaient réalisées par le processeur : il calculait l'image à afficher, et l’envoyait à une carte d'affichage 2D. Au fil du temps, de nombreux circuits furent ajoutés, afin de déporter un maximum de calculs vers la carte vidéo. Le rendu 3D moderne est basé sur le placage de texture inverse, avec des coordonnées de texture, une correction de perspective, etc. Mais les anciennes consoles et bornes d'arcade utilisaient le placage de texture direct. Et cela a impacté le hardware des consoles/PCs de l'époque. Avec le placage de texture direct, il était primordial de calculer la géométrie, mais la rasterisation était le fait de VDC améliorés. Aussi, les premières bornes d'arcade 3D et les consoles de 5ème génération disposaient processeurs pour calculer la géométrie et de circuits d'application de textures très particuliers. A l'inverse, les PC utilisaient un rendu inverse, totalement différent. Sur les PC, les premières cartes graphiques avaient un circuit de rastérisation et des unités de textures, mais pas de circuits géométriques. ==Les précurseurs : les cartes graphiques des bornes d'arcade== [[File:Sega ST-V Dynamite Deka PCB 20100324.jpg|vignette|Sega ST-V Dynamite Deka PCB 20100324]] L'accélération du rendu 3D sur les bornes d'arcade était déjà bien avancé dès les années 90. Les bornes d'arcade ont toujours été un segment haut de gamme de l'industrie du jeu vidéo, aussi ce n'est pas étonnant. Le prix d'une borne d'arcade dépassait facilement les 10 000 dollars pour les plus chères et une bonne partie du prix était celui du matériel informatique. Le matériel était donc très puissant et débordait de mémoire RAM comparé aux consoles de jeu et aux PC. La plupart des bornes d'arcade utilisaient du matériel standardisé entre plusieurs bornes. A l'intérieur d'une borne d'arcade se trouve une '''carte de borne d'arcade''' qui est une carte mère avec un ou plusieurs processeurs, de la RAM, une carte graphique, un VDC et pas mal d'autres matériels. La carte est reliée aux périphériques de la borne : joysticks, écran, pédales, le dispositif pour insérer les pièces afin de payer, le système sonore, etc. Le jeu utilisé pour la borne est placé dans une cartouche qui est insérée dans un connecteur spécialisé. Les cartes de bornes d'arcade étaient généralement assez complexes, elles avaient une grande taille et avaient plus de composants que les cartes mères de PC. Chaque carte contenait un grand nombre de chips pour la mémoire RAM et ROM, et il n'était pas rare d'avoir plusieurs processeurs sur une même carte. Et il n'était pas rare d'avoir trois à quatre cartes superposées dans une seule borne. Pour ceux qui veulent en savoir plus, Fabien Sanglard a publié gratuitement un livre sur le fonctionnement des cartes d'arcade CPS System, disponible via ce lien : [https://fabiensanglard.net/b/cpsb.pdf The book of CP System]. Les premières cartes graphiques des bornes d'arcade étaient des cartes graphiques 2D auxquelles on avait ajouté quelques fonctionnalités. Les sprites pouvaient être tournés, agrandit/réduits, ou déformés pour simuler de la perspective et faire de la fausse 3D. Par la suite, le vrai rendu 3D est apparu sur les bornes d'arcade, avec des GPUs totalement programmables. Dès 1988, la carte d'arcade Namco System 21 et Sega Model 1 géraient les calculs géométriques. Les deux cartes n'utilisaient pas de circuit géométrique fixe, mais l'émulaient avec un processeur programmé avec un programme informatique qui implémentait le T&L en logiciel. Elles utilisaient plusieurs DSP pour ce faire. Quelques années plus tard, les cartes graphiques se sont mises à supporter un éclairage de Gouraud et du placage de texture. Le Namco System 22 et la Sega model 2 supportaient des textures 2D et comme le filtrage de texture (bilinéaire et trilinéaire), le mip-mapping, et quelques autres. Par la suite, elles ont réutilisé le hardware des PC et autres consoles de jeux. ==La 3D sur les consoles de quatrième génération== Les consoles avant la quatrième génération de console étaient des consoles purement 2D, sans circuits d'accélération 3D. Leur carte graphique était un simple VDC 2D, plus ou moins performant selon la console. Pourtant, les consoles de quatrième génération ont connus quelques jeux en 3D. Par exemple, les jeux Star Fox sur SNES. Fait important, il s'agissait de vrais jeux en 3D qui tournaient sur des consoles qui ne géraient pas la 3D. La raison à cela est que la 3D était calculée par un GPU placé dans les cartouches du jeu ! Par exemple, les cartouches de Starfox et de Super Mario 2 contenait un coprocesseur Super FX, qui gérait des calculs de rendu 2D/3D. Un autre exemple est celui du co-processeur Cx4, cousin du Super FX, qui était spécialisé dans les calculs trigonométriques et diverses opérations utiles pour le rendu 2D/3D. En tout, il y a environ 16 coprocesseurs pour la SNES et on en trouve facilement la liste sur le net. La console était conçue pour, des pins sur les ports cartouches étaient prévues pour des fonctionnalités de cartouche annexes, dont ces coprocesseurs. Ces pins connectaient le coprocesseur au bus des entrées-sorties. Les coprocesseurs des cartouches de NES avaient souvent de la mémoire rien que pour eux, qui était intégrée dans la cartouche. ==L'arrivée des consoles de cinquième génération== Par la suite, les consoles de jeu se sont mises à intégrer des cartes graphiques 3D. Les premières consoles de jeu capables de rendu 3D sont les consoles dites de 5ème génération. Il y a diverses manières de classer les consoles en générations, la plus commune place la 3D à la 5ème génération, mais détailler ces controverses quant à ce classement nous amènerait trop loin. Les cartes graphiques des consoles de jeu utilisaient le rendu inverse, avec quelques exceptions qui utilisaient le rendu inverse. ===La Nintendo 64 : un GPU avancé=== La Nintendo 64 avait le GPU le plus complexe comparé aux autres consoles, et dépassait même les cartes graphiques des PC. Son GPU était très novateur pour une console sortie en 1996. Il incorporait une unité pour les calculs géométriques, un circuit pour la rasterisation, une unité pour les textures et un ROP final pour les calculs de transparence/brouillard/anti-aliasing, ainsi qu'un circuit pour gérer la profondeur des pixels. En somme, tout le pipeline graphique était implémenté dans le GPU de la Nintendo 64, chose très en avance sur son temps, même comparé au PC ! Le GPU est construit autour d'un processeur dédié aux calculs géométriques, le ''Reality Signal Processor'' (RSP), autour duquel on a ajouté des circuits pour le reste du pipeline graphique. L'unité de calcul géométrique est un processeur MIPS R4000, un processeur assez courant à l'époque, mais auquel on avait retiré quelques fonctionnalités inutiles pour le rendu 3D. Il était couplé à 4 KB de mémoire vidéo, ainsi qu'à 4 KB de mémoire ROM. Le reste du GPU était réalisé avec des circuits fixes. La Nintendo 64 utilisait déjà un mélange de circuits programmables et fixes. Un point intéressant est que le programme exécuté par le RSP pouvait être programmé ! Le RSP gérait déjà des espèces de proto-shaders, qui étaient appelés des ''[https://ultra64.ca/files/documentation/online-manuals/functions_reference_manual_2.0i/ucode/microcode.html micro-codes]'' dans la documentation de l'époque. La ROM associée au RSP mémorise cinq à sept programmes différents, des microcodes de base, aux fonctionnalités différentes. Ils géraient le rendu 3D de manière différente et avec une gestion des ressources différentes. Très peu de studios de jeu vidéo ont développé leur propre microcodes N64, car la documentation était mal faite, que Nintendo ne fournissait pas de support officiel pour cela, que les outils de développement ne permettaient pas de faire cela proprement et efficacement. ===La Playstation 1=== Sur la Playstation 1 le calcul de la géométrie était réalisé par le processeur, la carte graphique gérait tout le reste. Et la carte graphique était un circuit fixe spécialisé dans la rasterisation et le placage de textures. Elle utilisait, comme la Nintendo 64, le placage de texture inverse, qui est apparu ensuite sur les cartes graphiques. ===La 3DO et la Sega Saturn=== La Sega Saturn et la 3DO étaient les deux seules consoles à utiliser le rendu direct. La géométrie était calculée sur le processeur, même si les consoles utilisaient parfois un CPU dédié au calcul de la géométrie. Le reste du pipeline était géré par un VDC 2D qui implémentait le placage de textures. La Sega Saturn incorpore trois processeurs et deux GPU. Les deux GPUs sont nommés le VDP1 et le VDP2. Le VDP1 s'occupe des textures et des sprites, le VDP2 s'occupe uniquement de l'arrière-plan et incorpore un VDC tout ce qu'il y a de plus simple. Ils ne gèrent pas du tout la géométrie, qui est calculée par les trois processeurs. Le troisième processeur, la Saturn Control Unit, est un processeur de type DSP, à savoir un processeur spécialisé dans le traitement de signal. Il est utilisé presque exclusivement pour accélérer les calculs géométriques. Il avait sa propre mémoire RAM dédiée, 32 KB de SRAM, soit une mémoire locale très rapide. Les transferts entre cette RAM et le reste de l'ordinateur était géré par un contrôleur DMA intégré dans le DSP. En somme, il s'agit d'une sorte de processeur spécialisé dans la géométrie, une sorte d'unité géométrique programmable. Mais la géométrie n'était pas forcément calculée que sur ce DSP, mais pouvait être prise en charge par les 3 CPU. ==L'historique des cartes graphiques des PC, avant l'arrivée de Direct X et Open Gl== Sur PC, l'évolution des cartes graphiques a eu du retard par rapport aux consoles. Les PC sont en effet des machines multi-usage, pour lesquelles le jeu vidéo était un cas d'utilisation parmi tant d'autres. Et les consoles étaient la plateforme principale pour jouer à des jeux vidéo, le jeu vidéo PC étant plus marginal. Mais cela ne veut pas dire que le jeu PC n'existait pas, loin de là ! Un problème pour les jeux PC était que l'écosystème des PC était aussi fragmenté en plusieurs machines différentes : machines Apple 1 et 2, ordinateurs Commdore et Amiga, IBM PC et dérivés, etc. Aussi, programmer des jeux PC n'était pas mince affaire, car les problèmes de compatibilité étaient légion. C'est seulement quand la plateforme x86 des IBM PC s'est démocratisée que l'informatique grand public s'est standardisée, réduisant fortement les problèmes de compatibilité. Mais cela n'a pas suffit, il a aussi fallu que les API 3D naissent. Les API 3D comme Direct X et Open GL sont absolument cruciales pour garantir la compatibilité entre plusieurs ordinateurs aux cartes graphiques différentes. Aussi, l'évolution des cartes graphiques pour PC s'est faite main dans la main avec l'évolution des API 3D. Il a fallu que Direct X et Open GL progressent suffisamment pour que les problèmes de compatibilité soient partiellement résolus. Les fonctionnalités des cartes graphiques ont évolué dans le temps, en suivant les évolutions des API 3D. Du moins dans les grandes lignes, car il est arrivé plusieurs fois que des fonctionnalités naissent sur les cartes graphiques, pour que les fabricants forcent la main de Microsoft ou d'Open GL pour les intégrer de force dans les API 3D. Passons. ===L'introduction des premiers jeux 3D : Quake et les drivers miniGL=== L'histoire de la 3D sur PC commence avec la sortie du jeu Quake, d'IdSoftware. Celui-ci pouvait fonctionner en rendu logiciel, mais le programmeur responsable du moteur 3D (le fameux John Carmack) ajouta une version OpenGL du jeu. Le fait que le jeu était programmé sur une station de travail compatible avec OpenGL faisait que ce choix n'était si stupide, même si aucune carte accélératrice de l'époque ne supportait OpenGL. C'était là un choix qui se révéla visionnaire. En théorie, le rendu par OpenGL aurait dû se faire intégralement en logiciel, sauf sur quelques rares stations de travail adaptées. Mais les premières cartes graphiques étaient déjà dans les starting blocks. La toute première carte 3D pour PC est la Rendition Vérité V1000, sortie en Septembre 1995, soit quelques mois avant l'arrivée de la Nintendo 64. La Rendition Vérité V1000 était purement programmable, contrairement aux autres cartes graphiques de l'époque. Elle contenait un processeur MIPS cadencé à 25 MHz, 4 mébioctets de RAM, une ROM pour le BIOS, et un RAMDAC, rien de plus. C'était un vrai ordinateur complètement programmable de bout en bout. Les programmeurs ne pouvaient cependant pas utiliser cette programmabilité avec des ''shaders'', mais elle permettait à Rendition d'implémenter n'importe quelle API 3D, que ce soit OpenGL, DirectX ou même sa son API propriétaire. La Rendition Vérité avait de bonnes performances pour ce qui est de la géométrie, mais pas pour le reste. Autant les calculs géométriques sont assez rapides quand on les exécute sur un CPU, autant réaliser la rastérisation et le placage de texture en logiciel n'est pas efficace, pareil pour les opérations de fin de pipeline comme l'antialiasing. Le manque d'unités fixes très rapides pour la rastérisation, le placage de texture ou les opérations de fin de pipeline était clairement un gros défaut. Les autres cartes graphiques avaient implémenté l'exact inverse : de bonnes performances pour le placage de textures et la rastérization, mais les calculs géométriques étaient réalisés par le CPU. Au final, la carte graphique qui s'en sortait le mieux était la Nintendo 64 qui avait un CPU dédié pour les calculs géométriques et des circuits fixes pour le reste... Les autres cartes graphiques étaient totalement non-programmables et ne contenant que des circuits fixes, regroupe les Voodoo de 3dfx, les Riva TNT de NVIDIA, les Rage/3D d'ATI, la Virge/3D de S3, et la Matrox Mystique. Elles contenaient des circuits pour gérer les textures, mais aussi une étape d'enregistrement des pixels en mémoire. Elle était gérait le ''z-buffer'' en mémoire vidéo, mais aussi quelques effets graphiques comme les effets de brouillard. L'unité d'enregistrement des pixels en mémoire s'appelle le ROP pour ''Raster Operation Pipeline''. [[File:Architecture de base d'une carte 3D - 2.png|centre|vignette|upright=1.5|Carte 3D sans rasterization matérielle.]] Les cartes suivantes ajoutèrent une gestion des étapes de ''rasterization'' directement en matériel. Les cartes ATI rage 2, les Invention de chez Rendition, et d'autres cartes graphiques supportaient la rasterisation en hardware. [[File:Architecture de base d'une carte 3D - 3.png|centre|vignette|upright=1.5|Carte 3D avec gestion de la géométrie.]] Pour exploiter les unités de texture et le circuit de rastérisation, OpenGL et Direct 3D étaient partiellement implémentées en logiciel, car les cartes graphiques ne supportaient pas toutes les fonctionnalités de l'API. C'était l'époque du miniGL, des implémentations partielles d'OpenGL, fournies par les fabricants de cartes 3D, implémentées dans les pilotes de périphériques de ces dernières. Les fonctionnalités d'OpenGL implémentées dans ces pilotes étaient presque toutes exécutées en matériel, par la carte graphique. Avec l'évolution du matériel, les pilotes de périphériques devinrent de plus en plus complets, au point de devenir des implémentations totales d'OpenGL. Mais au-delà d'OpenGL, chaque fabricant de carte graphique avait sa propre API propriétaire, qui était gérée par leurs pilotes de périphériques (''drivers''). Par exemple, les premières cartes graphiques de 3dfx interactive, les fameuses voodoo, disposaient de leur propre API graphique, l'API Glide. Elle facilitait la gestion de la géométrie et des textures, ce qui collait bien avec l'architecture de ces cartes 3D. Mais ces API propriétaires tombèrent rapidement en désuétude avec l'évolution de DirectX et d'OpenGL. Direct X était une API dans l'ombre d'Open GL. La première version de Direct X qui supportait la 3D était DirectX 2.0 (juin 2, 1996), suivie rapidement par DirectX 3.0 (septembre 1996). Elles dataient d'avant le jeu Quake, et elles étaient très éloignées du hardware des premières cartes graphiques. Elles utilisaient un système d'''execute buffer'' pour communiquer avec la carte graphique, Microsoft espérait que le matériel 3D implémenterait ce genre de système. Ce qui ne fu pas le cas. Direct X 4.0 a été abandonné en cours de développement pour laisser à une version 5.0 assez semblable à la 2.0/3.0. Le mode de rendu laissait de côté les ''execute buffer'' pour coller un peu plus au hardware de l'époque. Mais rien de vraiment probant comparé à Open GL. Même Windows utilisait Open GL au lieu de Direct X maison... C'est avec Direct X 6.0 que Direct X est entré dans la cours des grands. Il gérait la plupart des technologies supportées par les cartes graphiques de l'époque. ===Le ''multi-texturing'' de l'époque Direct X 6.0 : combiner plusieurs textures=== Une technologie très importante standardisée par Dirext X 6 est la technique du '''''multi-texturing'''''. Avec ce qu'on a dit dans le chapitre précédent, vous pensez sans doute qu'il n'y a qu'une seule texture par objet, qui est plaquée sur sa surface. Mais divers effet graphiques demandent d'ajouter des textures par dessus d'autres textures. En général, elles servent pour ajouter des détails, du relief, sur une surface pré-existante. Un exemple intéressant vient des jeux de tir : ajouter des impacts de balles sur les murs. Pour cela, on plaque une texture d'impact de balle sur le mur, à la position du tir. Il s'agit là d'un exemple de '''''decals''''', des petites textures ajoutées sur les murs ou le sol, afin de simuler de la poussière, des impacts de balle, des craquelures, des fissures, des trous, etc. Les textures en question sont de petite taille et se superposent à une texture existante, plus grande. Rendre des ''decals'' demande de pouvoir superposer deux textures. Direct X 6.0 supportait l'application de plusieurs textures directement dans le matériel. La carte graphique devait être capable d'accéder à deux textures en même temps, ou du moins faire semblant que. Pour cela, elle doublaient les unités de texture et adaptaient les connexions entre unités de texture et mémoire vidéo. La mémoire vidéo devait être capable de gérer plusieurs accès mémoire en même temps et devait alors avoir un débit binaire élevé. [[File:Multitexturing.png|centre|vignette|upright=2|Multitexturing]] La carte graphique devait aussi gérer de quoi combiner deux textures entre elles. Par exemple, pour revenir sur l'exemple d'une texture d'impact de balle, il faut que la texture d'impact recouvre totalement la texture du mur. Dans ce cas, la combinaison est simple : la première texture remplace l'ancienne, là où elle est appliquée. Mais les cartes graphiques ont ajouté d'autres combinaisons possibles, par exemple additionner les deux textures entre elle, faire une moyenne des texels, etc. Les opérations pour combiner les textures était le fait de circuits appelés des '''''combiners'''''. Concrètement, les ''combiners'' sont de simples unités de calcul. Les ''conbiners'' ont beaucoup évolués dans le temps, mais les premières implémentation se limitaient à quelques opérations simples : addition, multiplication, superposition, interpolation. L'opération effectuer était envoyée au ''conbiner'' sur une entrée dédiée. [[File:Multitexturing avec combiners.png|centre|vignette|upright=2|Multitexturing avec combiners]] S'il y avait eu un seul ''conbiner'', le circuit de ''multitexturing'' aurait été simplement configurable. Mais dans la réalité, les premières cartes utilisant du ''multi-texturing'' utilisaient plusieurs ''combiners'' placés les uns à la suite des autres. L'implémentation des ''combiners'' retenue par Open Gl, et par le hardware des cartes graphiques, était la suivante. Les ''combiners'' étaient placés en série, l'un à la suite de l'autre, chacun combinant le résultat de l'étage précédent avec une texture. Le premier ''combiner'' gérait l'éclairage par sommet, afin de conserver un minimum de rétrocompatibilité. [[File:Texture combiners Open GL.png|centre|vignette|upright=2|Texture combiners Open GL]] Voici les opérations supportées par les ''combiners'' d'Open GL. Ils prennent en entrée le résultat de l'étage précédent et le combinent avec une texture lue depuis l'unité de texture. {|class="wikitable" |+ Opérations supportées par les ''combiners'' d'Open GL |- ! Replace | colspan="2" | Pixel provenant de l'unité de texture |- ! Addition | colspan="2" | Additionne l'entrée au texel lu. |- ! Modulate | colspan="2" | Multiplie l'entrée avec le texel lu |- ! Mélange (''blending'') | Moyenne pondérée des deux entrées, pondérée par la composante de transparence || La couleur de transparence du texel lu et de l'entrée sont multipliées. |- ! Decals | Moyenne pondérée des deux entrées, pondérée par la composante de transparence. || La transparence du résultat est celle de l'entrée. |} Il faut noter qu'un dernier étage de ''combiners'' s'occupait d'ajouter la couleur spéculaire et les effets de brouillards. Il était à part des autres et n'était pas configurable, c'était un étage fixe, qui était toujours présent, peu importe le nombre de textures utilisé. Il était parfois appelé le '''''combiner'' final''', terme que nous réutiliserons par la suite. Mine de rien, cela a rendu les cartes graphiques partiellement programmables. Le fait qu'il y ait des opérations enchainées à la suite, opérations qu'on peut choisir librement, suffit à créer une sorte de mini-programme qui décide comment mélanger plusieurs textures. Mais il y avait une limitation de taille : le fait que les données soient transmises d'un étage à l'autre, sans détours possibles. Par exemple, le troisième étage ne pouvait avoir comme seule opérande le résultat du second étage, mais ne pouvait pas utiliser celui du premier étage. Il n'y avait pas de registres pour stocker ce qui sortait de la rastérisation, ni pour mémoriser temporairement les texels lus. ===Le ''Transform & Lighting'' matériel de Direct X 7.0=== [[File:Architecture de base d'une carte 3D - 4.png|vignette|upright=1.5|Carte 3D avec gestion de la géométrie.]] La première carte graphique pour PC capable de gérer la géométrie en hardware fût la Geforce 256, la toute première Geforce. Son unité de gestion de la géométrie n'est autre que la bien connue '''unité T&L''' (''Transform And Lighting''). Elle implémentait des algorithmes d'éclairage de la scène 3D assez simples, comme un éclairage de Gouraud, qui étaient directement câblés dans ses circuits. Mais contrairement à la Nintendo 64 et aux bornes d'arcade, elle implémentait le tout, non pas avec un processeur classique, mais avec des circuits fixes. Avec Direct X 7.0 et Open GL 1.0, l'éclairage était en théorie limité à de l'éclairage par sommet, l'éclairage par pixel n'était pas implémentable en hardware. Les cartes graphiques ont tenté d'implémenter l'éclairage par pixel, mais cela n'est pas allé au-delà du support de quelques techniques de ''bump-mapping'' très limitées. Par exemple, Direct X 6.0 implémentait une forme limitée de ''bump-mapping'', guère plus. Un autre problème est que l'éclairage peut s'implémenter de plusieurs manières différentes, aux résultats visuels différents. Les unités de T&L étaient souvent en retard sur les algorithmes logiciels. Les programmeurs avaient le choix entre programmer les algorithmes d’éclairage qu'ils voulaient et les exécuter en logiciel ou utiliser ceux de l'unité de T&L, et choisissaient souvent la première option. Par exemple, Quake 3 Arena et Unreal Tournament n'utilisaient pas les capacités d'éclairage géométrique et préféraient utiliser leurs calculs d'éclairage logiciel fait maison. Cependant, le hardware dépassait les capacités des API et avait déjà commencé à ajouter des capacités de programmation liées au ''multi-texturing''. Les cartes graphiques de l'époque, surtout chez NVIDIA, implémentaient un système de '''''register combiners''''', une forme améliorée de ''texture combiners'', qui permettait de faire une forme limitée d'éclairage par pixel, notamment du vrai ''bump-mampping'', voire du ''normal-mapping''. Mais ce n'était pas totalement supporté par les API 3D de l'époque. Les ''registers combiners'' sont des ''texture combiners'' mais dans lesquels ont aurait retiré la stricte organisation en série. Il y a toujours plusieurs étages à la suite, qui peuvent exécuter chacun une opération, mais tous les étages ont maintenant accès à toutes les textures lues et à tout ce qui sort de la rastérisation, pas seulement au résultat de l'étape précédente. Pour cela, on ajoute des registres pour mémoriser ce qui sort des unités de texture, et pour ce qui sort de la rastérisation. De plus, on ajoute des registres temporaires pour mémoriser les résultats de chaque ''combiner'', de chaque étage. Il faut cependant signaler qu'il existe un ''combiner'' final, séparé des étages qui effectuent des opérations proprement dits. Il s'agit de l'étage qui applique la couleur spéculaire et les effets de brouillards. Il ne peut être utilisé qu'à la toute fin du traitement, en tant que dernier étage, on ne peut pas mettre d'opérations après lui. Sa sortie est directement connectée aux ROPs, pas à des registres. Il faut donc faire la distinction entre les '''''combiners'' généraux''' qui effectuent une opération et mémorisent le résultat dans des registres, et le ''combiner'' final qui envoie le résultat aux ROPs. L'implémentation des ''register combiners'' utilisait un processeur spécialisés dans les traitements sur des pixels, une sorte de proto-processeur de ''shader''. Le processeur supportait des opérations assez complexes : multiplication, produit scalaire, additions. Il s'agissait d'un processeur de type VLIW, qui sera décrit dans quelques chapitres. Mais ce processeur avait des programmes très courts. Les premières cartes NVIDIA, comme les cartes TNT pouvaient exécuter deux opérations à la suite, suivie par l'application de la couleurs spéculaire et du brouillard. En somme, elles étaient limitées à un ''shader'' à deux/trois opérations, mais c'était un début. Le nombre d'opérations consécutives est rapidement passé à 8 sur la Geforce 3. ===L'arrivée des ''shaders'' avec Direct X 8.0=== [[File:Architecture de la Geforce 3.png|vignette|upright=1.5|Architecture de la Geforce 3]] Les ''register combiners'' était un premier pas vers un éclairage programmable. Paradoxalement, l'évolution suivante s'est faite non pas dans l'unité de rastérisation/texture, mais dans l'unité de traitement de la géométrie. La Geforce 3 a remplacé l'unité de T&L par un processeur capable d'exécuter des programmes. Les programmes en question complétaient l'unité de T&L, afin de pouvoir rajouter des techniques d'éclairage plus complexes. Le tout a permis aussi d'ajouter des animations, des effets de fourrures, des ombres par ''shadow volume'', des systèmes de particule évolués, et bien d'autres. À partir de la Geforce 3 de Nvidia, les cartes graphiques sont devenues capables d'exécuter des programmes appelés '''''shaders'''''. Le terme ''shader'' vient de ''shading'' : ombrage en anglais. Grace aux ''shaders'', l'éclairage est devenu programmable, il n'est plus géré par des unités d'éclairage fixes mais été laissé à la créativité des programmeurs. Les programmeurs ne sont plus vraiment limités par les algorithmes d'éclairage implémentés dans les cartes graphiques, mais peuvent implémenter les algorithmes d'éclairage qu'ils veulent et peuvent le faire exécuter directement sur la carte graphique. Les ''shaders'' sont classifiés suivant les données qu'ils manipulent : '''''pixel shader''''' pour ceux qui manipulent des pixels, '''''vertex shaders''''' pour ceux qui manipulent des sommets. Les premiers sont utilisés pour implémenter l'éclairage par pixel, les autres pour gérer tout ce qui a trait à la géométrie, pas seulement l'éclairage par sommets. Direct X 8.0 avait un standard pour les shaders, appelé ''shaders 1.0'', qui correspondait parfaitement à ce dont était capable la Geforce 3. Il standardisait les ''vertex shaders'' de la Geforce 3, mais il a aussi renommé les ''register combiners'' comme étant des ''pixel shaders'' version 1.0. Les ''register combiners'' n'ont pas évolués depuis la Geforce 256, si ce n'est que les programmes sont passés de deux opérations successives à 8, et qu'il y avait possibilité de lire 4 textures en ''multitexturing''. A l'opposé, le processeur de ''vertex shader'' de la Geforce 3 était capable d'exécuter des programmes de 128 opérations consécutives et avait 258 registres différents ! Des ''pixels shaders'' plus évolués sont arrivés avec l'ATI Radeon 8500 et ses dérivés. Elle incorporait la technologie ''SMARTSHADER'' qui remplacait les ''registers combiners'' par un processeur de ''shader'' un peu limité. Un point est que le processeur acceptait de calculer des adresses de texture dans le ''pixel shader''. Avant, les adresses des texels à lire étaient fournis par l'unité de rastérisation et basta. L'avantage est que certains effets graphiques étaient devenus possibles : du ''bump-mapping'' avancé, des textures procédurales, de l'éclairage par pixel anisotrope, du éclairage de Phong réel, etc. Avec la Radeon 8500, le ''pixel shader'' pouvait calculer des adresses, et lire les texels associés à ces adresses calculées. Les ''pixel shaders'' pouvaient lire 6 textures, faire 8 opérations sur les texels lus, puis lire 6 textures avec les adresses calculées à l'étape précédente, et refaire 8 opérations. Quelque chose de limité, donc, mais déjà plus pratique. Les ''pixel shaders'' de ce type ont été standardisé dans Direct X 8.1, sous le nom de ''pixel shaders 1.4''. Encore une fois, le hardware a forcé l'intégration dans une API 3D. ===Les ''shaders'' de Direct X 9.0 : de vrais ''pixel shaders''=== Avec Direct X 9.0, les ''shaders'' sont devenus de vrais programmes, sans les limitations des ''shaders'' précédents. Les ''pixels shaders'' sont passés à la version 2.0, idem pour les ''vertex shaders''. Concrètement, ils sont maintenant exécutés par un processeur de ''shader'' dédié, aux fonctionnalités bien supérieures à celles des ''registers combiners''. Les ''shaders'' pouvaient exécuter une suite d'opérations arbitraire, dans le sens où elle n'était pas structurée avec tel type d'opération au début, suivie par un accès aux textures, etc. On pouvait mettre n'importe quelle opération dans n'importe quel ordre. De plus, les ''shaders'' ne sont plus écrit en assembleur comme c'était le cas avant. Ils sont dorénavant écrits dans un langage de haut-niveau, le HLSL pour les shaders Direct X et le GLSL pour les shaders Open Gl. Les ''shaders'' sont ensuite traduit (compilés) en instructions machines compréhensibles par la carte graphique. Au début, ces langages et la carte graphique supportaient uniquement des opérations simples. Mais au fil du temps, les spécifications de ces langages sont devenues de plus en plus riches à chaque version de Direct X ou d'Open Gl, et le matériel en a fait autant. [[File:Architecture de base d'une carte 3D - 5.png|centre|vignette|upright=1.5|Carte 3D avec pixels et vertex shaders non-unifiés.]] ===L'après Direct X 9.0=== Avant Direct X 10, les processeurs de ''shaders'' ne géraient pas exactement les mêmes opérations pour les processeurs de ''vertex shader'' et de ''pixel shader''. Les processeurs de ''vertex shader'' et de ''pixel shader''étaient séparés. Depuis DirectX 10, ce n'est plus le cas : le jeu d'instructions a été unifié entre les vertex shaders et les pixels shaders, ce qui fait qu'il n'y a plus de distinction entre processeurs de vertex shaders et de pixels shaders, chaque processeur pouvant traiter indifféremment l'un ou l'autre. [[File:Architecture de base d'une carte 3D - 6.png|centre|vignette|upright=1.5|Architecture de la GeForce 6800.]] Avec Direct X 10, de nombreux autres ''shaders'' sont apparus. Les plus liés au rendu 3D sont les '''''geometry shader''''' pour ceux qui manipulent des triangles, de ''hull shaders'' et de ''domain shaders'' pour la tesselation. De plus, les cartes graphiques modernes sont capables d’exécuter des programmes informatiques qui n'ont aucun lien avec le rendu 3D, mais sont exécutés par la carte graphique comme le ferait un processeur d'ordinateur normal. De tels ''shaders'' sans lien avec le rendu 3D sont appelés des ''compute shader''. ==Les cartes graphiques d'aujourd'hui== Avec l'arrivée des shaders, les circuits d'une carte graphique sont divisés en deux catégories : d'un côté les circuits non-programmables et de l'autre les circuits programmables. Pour exécuter les ''shaders'', la carte graphique incorpore des '''processeurs de ''shaders''''', des processeurs similaires aux processeurs des ordinateurs, aux CPU, mais avec quelques petites différences qu'on expliquera dans le prochain chapitre. A côté des processeurs de ''shaders'', il reste quelques circuits non(programmables appelés des circuits fixes. De nos jours, la gestion de la géométrie et des pixels est programmable, mais la rastérisation, le placage de texture, le ''culling'' et l'enregistrement du ''framebuffer'' ne l'est pas. Il n'en a pas toujours été ainsi. [[File:3D-Pipeline.svg|centre|vignette|upright=3.0|Pipeline 3D : ce qui est programmable et ce qui ne l'est pas dans une carte graphique moderne.]] ===Les GPU modernes sont un mélange de processeurs et de circuits fixes=== Une carte graphique contient donc un mélange de circuits fixes et de processeurs de ''shaders'', qui peut sembler contradictoire. Pourquoi ne pas tout rendre programmable ? Ou au contraire, utiliser seulement des circuits fixes ? La réponse rapide est qu'il s'agit d'un compromis entre flexibilité et performance qui permet d'avoir le meilleur des deux mondes. Mais ce compromis a fortement évolué dans le temps, comme on va le voir plus bas. Rendre la gestion de la géométrie ou des pixels programmable permet d'implémenter facilement un grand nombre d'effets graphiques sans avoir à les implémenter en hardware. Avant les ''shaders'', seul le hardware récent gérait les dernières fonctionnalités. Les effets graphiques derniers cri n'étaient disponibles que sur les derniers modèles de carte graphique. Avec des ''vertex/pixel shaders'', ce genre de défaut est passé à la trappe. Si un nouvel algorithme de rendu graphique est inventé, il peut être utilisé dès le lendemain sur toutes les cartes graphiques modernes. De plus, implémenter beaucoup d'algorithmes d'éclairage différents est difficile. Le cout en termes de transistors et de complexité était assez important, utiliser des circuits programmable a un cout en hardware plus limité. Tout cela est à l'exact opposé de ce qu'on a avec les autres circuits, comme les circuits pour la rastérisation ou le placage de texture. Il n'y a pas 36 façons de rastériser une scène 3D et la flexibilité n'est pas un besoin important pour cette opération, alors que les performances sont cruciales. Même chose pour le placage/filtrage de textures. En conséquences, les unités de transformation, de rastérisation et de placage de texture sont toutes implémentées en matériel. Faire ainsi permet de gagner en performance sans que cela ait le moindre impact pour le programmeur. ===Les unités de texture sont intégrées aux processeurs de shaders=== Les unités de textures sont à part des autres circuits fixes, dans le sens où ce sont les seuls à être implémentés dans les processeurs de shaders. Sur les anciennes cartes 3D, les unités de textures étaient des circuits séparés des autres. Mais avec l'arrivée des processeurs de shaders, elles ont été intégrée dans les processeurs de shaders eux-mêmes. Pour comprendre pourquoi, il faut faire un rappel sur ce qu'il y a dans un processeur. Un processeur contient globalement quatre circuits : * une unité de calcul qui fait des calculs ; * des registres pour stocker les opérandes et résultats des calculs ; * une unité de communication avec la mémoire ; * et un séquenceur, un circuit de contrôle qui commande les autres. L'unité de communication avec la mémoire sert à lire ou écrire des données, à les transférer de la RAM vers les registres, ou l'inverse. Lire une donnée demande d'envoyer son adresse à la RAM, qui répond en envoyant la donnée lue. Elle est donc toute indiquée pour lire une texture : lire une texture n'est qu'un cas particulier de lecture de données. Les texels à lire sont à une adresse précise, la RAM répond à la lecture avec le texel demandé. Il est donc possible d'utiliser l'unité de communication avec la mémoire comme si c'était une unité de texture. Cependant, les textures ne sont pas utilisées comme telles de nos jours. Le rendu 3D moderne utilise des techniques dites de filtrage de texture, qui permettent d'améliorer la qualité du rendu des textures. Sans ce filtrage de texture, les textures appliquées naïvement donnent un résultat assez pixelisé et assez moche, pour des raisons assez techniques. Le filtrage élimine ces artefacts, en utilisant une forme d'''antialiasing'' interne aux textures, le fameux filtrage de texture. Le filtrage de texture peut être réalisé en logiciel ou en matériel. Techniquement, il est possible de le faire dans un ''shader'' : le ''shader'' calcule les adresses des texels à lire, lit plusieurs texels, et effectue ensuite le filtrage. En soi, rien d'impossible. Mais le filtrage de texture est toujours effectué directement en matériel. Les processeurs de shaders incorporent des circuits de filtrage de texture, dans l'unité de communication avec la mémoire. La raison est que le filtrage de texture est une opération très simple à implémenter en hardware, qui demande assez peu de circuits. Le filtrage bilinéaire ou trilinéaire demande juste des circuits d'interpolation et quelques registres, ce qui est trivial. Et la seconde raison est qu'il n'y a pas 36 façons de filtrer des textures : une carte graphique peut implémenter les algorithmes principaux existants en assez peu de circuits. : Il faut noter que les ROPs peuvent aussi être intégré dans les processeurs de ''shader'', mais c'est assez rare. Les cartes graphiques pour PC ont des ROPs séparés des processeurs de ''shaders''. Par contre, quelques cartes graphiques destinées les smartphones et autres appareils mobiles font exception. Sur celles-ci, les unités de textures et les ROPs sont intégrés dans les processeurs de ''shaders'', aux côtés de l'unité d'accès mémoire LOAD/STORE. Il s'agit de cartes graphiques en rendu à tuiles. {{NavChapitre | book=Les cartes graphiques | prev=Les cartes graphiques : architecture de base | prevText=Les cartes graphiques : architecture de base | next=Les processeurs de shaders | nextText=Les processeurs de shaders }} {{autocat}} 07oxg8ezjycqq82slljm95jxhtkq71t 744097 744096 2025-06-04T00:20:10Z Mewtow 31375 /* Les unités de texture sont intégrées aux processeurs de shaders */ 744097 wikitext text/x-wiki Il est intéressant d'étudier le hardware des cartes graphiques en faisant un petit résumé de leur évolution dans le temps. En effet, leur hardware a fortement évolué dans le temps. Et il serait difficile à comprendre le hardware actuel sans parler du hardware d'antan. En effet, une carte graphique moderne est partiellement programmable. Certains circuits sont totalement programmables, d'autres non. Et pour comprendre pourquoi, il faut étudier comment ces circuits ont évolués. Le hardware des cartes graphiques a fortement évolué dans le temps, ce qui n'est pas une surprise. Les évolutions de la technologie, avec la miniaturisation des transistors et l'augmentation de leurs performances a permit aux cartes graphiques d'incorporer de plus en plus de circuits avec les années. Avant l'invention des cartes graphiques, toutes les étapes du pipeline graphique étaient réalisées par le processeur : il calculait l'image à afficher, et l’envoyait à une carte d'affichage 2D. Au fil du temps, de nombreux circuits furent ajoutés, afin de déporter un maximum de calculs vers la carte vidéo. Le rendu 3D moderne est basé sur le placage de texture inverse, avec des coordonnées de texture, une correction de perspective, etc. Mais les anciennes consoles et bornes d'arcade utilisaient le placage de texture direct. Et cela a impacté le hardware des consoles/PCs de l'époque. Avec le placage de texture direct, il était primordial de calculer la géométrie, mais la rasterisation était le fait de VDC améliorés. Aussi, les premières bornes d'arcade 3D et les consoles de 5ème génération disposaient processeurs pour calculer la géométrie et de circuits d'application de textures très particuliers. A l'inverse, les PC utilisaient un rendu inverse, totalement différent. Sur les PC, les premières cartes graphiques avaient un circuit de rastérisation et des unités de textures, mais pas de circuits géométriques. ==Les précurseurs : les cartes graphiques des bornes d'arcade== [[File:Sega ST-V Dynamite Deka PCB 20100324.jpg|vignette|Sega ST-V Dynamite Deka PCB 20100324]] L'accélération du rendu 3D sur les bornes d'arcade était déjà bien avancé dès les années 90. Les bornes d'arcade ont toujours été un segment haut de gamme de l'industrie du jeu vidéo, aussi ce n'est pas étonnant. Le prix d'une borne d'arcade dépassait facilement les 10 000 dollars pour les plus chères et une bonne partie du prix était celui du matériel informatique. Le matériel était donc très puissant et débordait de mémoire RAM comparé aux consoles de jeu et aux PC. La plupart des bornes d'arcade utilisaient du matériel standardisé entre plusieurs bornes. A l'intérieur d'une borne d'arcade se trouve une '''carte de borne d'arcade''' qui est une carte mère avec un ou plusieurs processeurs, de la RAM, une carte graphique, un VDC et pas mal d'autres matériels. La carte est reliée aux périphériques de la borne : joysticks, écran, pédales, le dispositif pour insérer les pièces afin de payer, le système sonore, etc. Le jeu utilisé pour la borne est placé dans une cartouche qui est insérée dans un connecteur spécialisé. Les cartes de bornes d'arcade étaient généralement assez complexes, elles avaient une grande taille et avaient plus de composants que les cartes mères de PC. Chaque carte contenait un grand nombre de chips pour la mémoire RAM et ROM, et il n'était pas rare d'avoir plusieurs processeurs sur une même carte. Et il n'était pas rare d'avoir trois à quatre cartes superposées dans une seule borne. Pour ceux qui veulent en savoir plus, Fabien Sanglard a publié gratuitement un livre sur le fonctionnement des cartes d'arcade CPS System, disponible via ce lien : [https://fabiensanglard.net/b/cpsb.pdf The book of CP System]. Les premières cartes graphiques des bornes d'arcade étaient des cartes graphiques 2D auxquelles on avait ajouté quelques fonctionnalités. Les sprites pouvaient être tournés, agrandit/réduits, ou déformés pour simuler de la perspective et faire de la fausse 3D. Par la suite, le vrai rendu 3D est apparu sur les bornes d'arcade, avec des GPUs totalement programmables. Dès 1988, la carte d'arcade Namco System 21 et Sega Model 1 géraient les calculs géométriques. Les deux cartes n'utilisaient pas de circuit géométrique fixe, mais l'émulaient avec un processeur programmé avec un programme informatique qui implémentait le T&L en logiciel. Elles utilisaient plusieurs DSP pour ce faire. Quelques années plus tard, les cartes graphiques se sont mises à supporter un éclairage de Gouraud et du placage de texture. Le Namco System 22 et la Sega model 2 supportaient des textures 2D et comme le filtrage de texture (bilinéaire et trilinéaire), le mip-mapping, et quelques autres. Par la suite, elles ont réutilisé le hardware des PC et autres consoles de jeux. ==La 3D sur les consoles de quatrième génération== Les consoles avant la quatrième génération de console étaient des consoles purement 2D, sans circuits d'accélération 3D. Leur carte graphique était un simple VDC 2D, plus ou moins performant selon la console. Pourtant, les consoles de quatrième génération ont connus quelques jeux en 3D. Par exemple, les jeux Star Fox sur SNES. Fait important, il s'agissait de vrais jeux en 3D qui tournaient sur des consoles qui ne géraient pas la 3D. La raison à cela est que la 3D était calculée par un GPU placé dans les cartouches du jeu ! Par exemple, les cartouches de Starfox et de Super Mario 2 contenait un coprocesseur Super FX, qui gérait des calculs de rendu 2D/3D. Un autre exemple est celui du co-processeur Cx4, cousin du Super FX, qui était spécialisé dans les calculs trigonométriques et diverses opérations utiles pour le rendu 2D/3D. En tout, il y a environ 16 coprocesseurs pour la SNES et on en trouve facilement la liste sur le net. La console était conçue pour, des pins sur les ports cartouches étaient prévues pour des fonctionnalités de cartouche annexes, dont ces coprocesseurs. Ces pins connectaient le coprocesseur au bus des entrées-sorties. Les coprocesseurs des cartouches de NES avaient souvent de la mémoire rien que pour eux, qui était intégrée dans la cartouche. ==L'arrivée des consoles de cinquième génération== Par la suite, les consoles de jeu se sont mises à intégrer des cartes graphiques 3D. Les premières consoles de jeu capables de rendu 3D sont les consoles dites de 5ème génération. Il y a diverses manières de classer les consoles en générations, la plus commune place la 3D à la 5ème génération, mais détailler ces controverses quant à ce classement nous amènerait trop loin. Les cartes graphiques des consoles de jeu utilisaient le rendu inverse, avec quelques exceptions qui utilisaient le rendu inverse. ===La Nintendo 64 : un GPU avancé=== La Nintendo 64 avait le GPU le plus complexe comparé aux autres consoles, et dépassait même les cartes graphiques des PC. Son GPU était très novateur pour une console sortie en 1996. Il incorporait une unité pour les calculs géométriques, un circuit pour la rasterisation, une unité pour les textures et un ROP final pour les calculs de transparence/brouillard/anti-aliasing, ainsi qu'un circuit pour gérer la profondeur des pixels. En somme, tout le pipeline graphique était implémenté dans le GPU de la Nintendo 64, chose très en avance sur son temps, même comparé au PC ! Le GPU est construit autour d'un processeur dédié aux calculs géométriques, le ''Reality Signal Processor'' (RSP), autour duquel on a ajouté des circuits pour le reste du pipeline graphique. L'unité de calcul géométrique est un processeur MIPS R4000, un processeur assez courant à l'époque, mais auquel on avait retiré quelques fonctionnalités inutiles pour le rendu 3D. Il était couplé à 4 KB de mémoire vidéo, ainsi qu'à 4 KB de mémoire ROM. Le reste du GPU était réalisé avec des circuits fixes. La Nintendo 64 utilisait déjà un mélange de circuits programmables et fixes. Un point intéressant est que le programme exécuté par le RSP pouvait être programmé ! Le RSP gérait déjà des espèces de proto-shaders, qui étaient appelés des ''[https://ultra64.ca/files/documentation/online-manuals/functions_reference_manual_2.0i/ucode/microcode.html micro-codes]'' dans la documentation de l'époque. La ROM associée au RSP mémorise cinq à sept programmes différents, des microcodes de base, aux fonctionnalités différentes. Ils géraient le rendu 3D de manière différente et avec une gestion des ressources différentes. Très peu de studios de jeu vidéo ont développé leur propre microcodes N64, car la documentation était mal faite, que Nintendo ne fournissait pas de support officiel pour cela, que les outils de développement ne permettaient pas de faire cela proprement et efficacement. ===La Playstation 1=== Sur la Playstation 1 le calcul de la géométrie était réalisé par le processeur, la carte graphique gérait tout le reste. Et la carte graphique était un circuit fixe spécialisé dans la rasterisation et le placage de textures. Elle utilisait, comme la Nintendo 64, le placage de texture inverse, qui est apparu ensuite sur les cartes graphiques. ===La 3DO et la Sega Saturn=== La Sega Saturn et la 3DO étaient les deux seules consoles à utiliser le rendu direct. La géométrie était calculée sur le processeur, même si les consoles utilisaient parfois un CPU dédié au calcul de la géométrie. Le reste du pipeline était géré par un VDC 2D qui implémentait le placage de textures. La Sega Saturn incorpore trois processeurs et deux GPU. Les deux GPUs sont nommés le VDP1 et le VDP2. Le VDP1 s'occupe des textures et des sprites, le VDP2 s'occupe uniquement de l'arrière-plan et incorpore un VDC tout ce qu'il y a de plus simple. Ils ne gèrent pas du tout la géométrie, qui est calculée par les trois processeurs. Le troisième processeur, la Saturn Control Unit, est un processeur de type DSP, à savoir un processeur spécialisé dans le traitement de signal. Il est utilisé presque exclusivement pour accélérer les calculs géométriques. Il avait sa propre mémoire RAM dédiée, 32 KB de SRAM, soit une mémoire locale très rapide. Les transferts entre cette RAM et le reste de l'ordinateur était géré par un contrôleur DMA intégré dans le DSP. En somme, il s'agit d'une sorte de processeur spécialisé dans la géométrie, une sorte d'unité géométrique programmable. Mais la géométrie n'était pas forcément calculée que sur ce DSP, mais pouvait être prise en charge par les 3 CPU. ==L'historique des cartes graphiques des PC, avant l'arrivée de Direct X et Open Gl== Sur PC, l'évolution des cartes graphiques a eu du retard par rapport aux consoles. Les PC sont en effet des machines multi-usage, pour lesquelles le jeu vidéo était un cas d'utilisation parmi tant d'autres. Et les consoles étaient la plateforme principale pour jouer à des jeux vidéo, le jeu vidéo PC étant plus marginal. Mais cela ne veut pas dire que le jeu PC n'existait pas, loin de là ! Un problème pour les jeux PC était que l'écosystème des PC était aussi fragmenté en plusieurs machines différentes : machines Apple 1 et 2, ordinateurs Commdore et Amiga, IBM PC et dérivés, etc. Aussi, programmer des jeux PC n'était pas mince affaire, car les problèmes de compatibilité étaient légion. C'est seulement quand la plateforme x86 des IBM PC s'est démocratisée que l'informatique grand public s'est standardisée, réduisant fortement les problèmes de compatibilité. Mais cela n'a pas suffit, il a aussi fallu que les API 3D naissent. Les API 3D comme Direct X et Open GL sont absolument cruciales pour garantir la compatibilité entre plusieurs ordinateurs aux cartes graphiques différentes. Aussi, l'évolution des cartes graphiques pour PC s'est faite main dans la main avec l'évolution des API 3D. Il a fallu que Direct X et Open GL progressent suffisamment pour que les problèmes de compatibilité soient partiellement résolus. Les fonctionnalités des cartes graphiques ont évolué dans le temps, en suivant les évolutions des API 3D. Du moins dans les grandes lignes, car il est arrivé plusieurs fois que des fonctionnalités naissent sur les cartes graphiques, pour que les fabricants forcent la main de Microsoft ou d'Open GL pour les intégrer de force dans les API 3D. Passons. ===L'introduction des premiers jeux 3D : Quake et les drivers miniGL=== L'histoire de la 3D sur PC commence avec la sortie du jeu Quake, d'IdSoftware. Celui-ci pouvait fonctionner en rendu logiciel, mais le programmeur responsable du moteur 3D (le fameux John Carmack) ajouta une version OpenGL du jeu. Le fait que le jeu était programmé sur une station de travail compatible avec OpenGL faisait que ce choix n'était si stupide, même si aucune carte accélératrice de l'époque ne supportait OpenGL. C'était là un choix qui se révéla visionnaire. En théorie, le rendu par OpenGL aurait dû se faire intégralement en logiciel, sauf sur quelques rares stations de travail adaptées. Mais les premières cartes graphiques étaient déjà dans les starting blocks. La toute première carte 3D pour PC est la Rendition Vérité V1000, sortie en Septembre 1995, soit quelques mois avant l'arrivée de la Nintendo 64. La Rendition Vérité V1000 était purement programmable, contrairement aux autres cartes graphiques de l'époque. Elle contenait un processeur MIPS cadencé à 25 MHz, 4 mébioctets de RAM, une ROM pour le BIOS, et un RAMDAC, rien de plus. C'était un vrai ordinateur complètement programmable de bout en bout. Les programmeurs ne pouvaient cependant pas utiliser cette programmabilité avec des ''shaders'', mais elle permettait à Rendition d'implémenter n'importe quelle API 3D, que ce soit OpenGL, DirectX ou même sa son API propriétaire. La Rendition Vérité avait de bonnes performances pour ce qui est de la géométrie, mais pas pour le reste. Autant les calculs géométriques sont assez rapides quand on les exécute sur un CPU, autant réaliser la rastérisation et le placage de texture en logiciel n'est pas efficace, pareil pour les opérations de fin de pipeline comme l'antialiasing. Le manque d'unités fixes très rapides pour la rastérisation, le placage de texture ou les opérations de fin de pipeline était clairement un gros défaut. Les autres cartes graphiques avaient implémenté l'exact inverse : de bonnes performances pour le placage de textures et la rastérization, mais les calculs géométriques étaient réalisés par le CPU. Au final, la carte graphique qui s'en sortait le mieux était la Nintendo 64 qui avait un CPU dédié pour les calculs géométriques et des circuits fixes pour le reste... Les autres cartes graphiques étaient totalement non-programmables et ne contenant que des circuits fixes, regroupe les Voodoo de 3dfx, les Riva TNT de NVIDIA, les Rage/3D d'ATI, la Virge/3D de S3, et la Matrox Mystique. Elles contenaient des circuits pour gérer les textures, mais aussi une étape d'enregistrement des pixels en mémoire. Elle était gérait le ''z-buffer'' en mémoire vidéo, mais aussi quelques effets graphiques comme les effets de brouillard. L'unité d'enregistrement des pixels en mémoire s'appelle le ROP pour ''Raster Operation Pipeline''. [[File:Architecture de base d'une carte 3D - 2.png|centre|vignette|upright=1.5|Carte 3D sans rasterization matérielle.]] Les cartes suivantes ajoutèrent une gestion des étapes de ''rasterization'' directement en matériel. Les cartes ATI rage 2, les Invention de chez Rendition, et d'autres cartes graphiques supportaient la rasterisation en hardware. [[File:Architecture de base d'une carte 3D - 3.png|centre|vignette|upright=1.5|Carte 3D avec gestion de la géométrie.]] Pour exploiter les unités de texture et le circuit de rastérisation, OpenGL et Direct 3D étaient partiellement implémentées en logiciel, car les cartes graphiques ne supportaient pas toutes les fonctionnalités de l'API. C'était l'époque du miniGL, des implémentations partielles d'OpenGL, fournies par les fabricants de cartes 3D, implémentées dans les pilotes de périphériques de ces dernières. Les fonctionnalités d'OpenGL implémentées dans ces pilotes étaient presque toutes exécutées en matériel, par la carte graphique. Avec l'évolution du matériel, les pilotes de périphériques devinrent de plus en plus complets, au point de devenir des implémentations totales d'OpenGL. Mais au-delà d'OpenGL, chaque fabricant de carte graphique avait sa propre API propriétaire, qui était gérée par leurs pilotes de périphériques (''drivers''). Par exemple, les premières cartes graphiques de 3dfx interactive, les fameuses voodoo, disposaient de leur propre API graphique, l'API Glide. Elle facilitait la gestion de la géométrie et des textures, ce qui collait bien avec l'architecture de ces cartes 3D. Mais ces API propriétaires tombèrent rapidement en désuétude avec l'évolution de DirectX et d'OpenGL. Direct X était une API dans l'ombre d'Open GL. La première version de Direct X qui supportait la 3D était DirectX 2.0 (juin 2, 1996), suivie rapidement par DirectX 3.0 (septembre 1996). Elles dataient d'avant le jeu Quake, et elles étaient très éloignées du hardware des premières cartes graphiques. Elles utilisaient un système d'''execute buffer'' pour communiquer avec la carte graphique, Microsoft espérait que le matériel 3D implémenterait ce genre de système. Ce qui ne fu pas le cas. Direct X 4.0 a été abandonné en cours de développement pour laisser à une version 5.0 assez semblable à la 2.0/3.0. Le mode de rendu laissait de côté les ''execute buffer'' pour coller un peu plus au hardware de l'époque. Mais rien de vraiment probant comparé à Open GL. Même Windows utilisait Open GL au lieu de Direct X maison... C'est avec Direct X 6.0 que Direct X est entré dans la cours des grands. Il gérait la plupart des technologies supportées par les cartes graphiques de l'époque. ===Le ''multi-texturing'' de l'époque Direct X 6.0 : combiner plusieurs textures=== Une technologie très importante standardisée par Dirext X 6 est la technique du '''''multi-texturing'''''. Avec ce qu'on a dit dans le chapitre précédent, vous pensez sans doute qu'il n'y a qu'une seule texture par objet, qui est plaquée sur sa surface. Mais divers effet graphiques demandent d'ajouter des textures par dessus d'autres textures. En général, elles servent pour ajouter des détails, du relief, sur une surface pré-existante. Un exemple intéressant vient des jeux de tir : ajouter des impacts de balles sur les murs. Pour cela, on plaque une texture d'impact de balle sur le mur, à la position du tir. Il s'agit là d'un exemple de '''''decals''''', des petites textures ajoutées sur les murs ou le sol, afin de simuler de la poussière, des impacts de balle, des craquelures, des fissures, des trous, etc. Les textures en question sont de petite taille et se superposent à une texture existante, plus grande. Rendre des ''decals'' demande de pouvoir superposer deux textures. Direct X 6.0 supportait l'application de plusieurs textures directement dans le matériel. La carte graphique devait être capable d'accéder à deux textures en même temps, ou du moins faire semblant que. Pour cela, elle doublaient les unités de texture et adaptaient les connexions entre unités de texture et mémoire vidéo. La mémoire vidéo devait être capable de gérer plusieurs accès mémoire en même temps et devait alors avoir un débit binaire élevé. [[File:Multitexturing.png|centre|vignette|upright=2|Multitexturing]] La carte graphique devait aussi gérer de quoi combiner deux textures entre elles. Par exemple, pour revenir sur l'exemple d'une texture d'impact de balle, il faut que la texture d'impact recouvre totalement la texture du mur. Dans ce cas, la combinaison est simple : la première texture remplace l'ancienne, là où elle est appliquée. Mais les cartes graphiques ont ajouté d'autres combinaisons possibles, par exemple additionner les deux textures entre elle, faire une moyenne des texels, etc. Les opérations pour combiner les textures était le fait de circuits appelés des '''''combiners'''''. Concrètement, les ''combiners'' sont de simples unités de calcul. Les ''conbiners'' ont beaucoup évolués dans le temps, mais les premières implémentation se limitaient à quelques opérations simples : addition, multiplication, superposition, interpolation. L'opération effectuer était envoyée au ''conbiner'' sur une entrée dédiée. [[File:Multitexturing avec combiners.png|centre|vignette|upright=2|Multitexturing avec combiners]] S'il y avait eu un seul ''conbiner'', le circuit de ''multitexturing'' aurait été simplement configurable. Mais dans la réalité, les premières cartes utilisant du ''multi-texturing'' utilisaient plusieurs ''combiners'' placés les uns à la suite des autres. L'implémentation des ''combiners'' retenue par Open Gl, et par le hardware des cartes graphiques, était la suivante. Les ''combiners'' étaient placés en série, l'un à la suite de l'autre, chacun combinant le résultat de l'étage précédent avec une texture. Le premier ''combiner'' gérait l'éclairage par sommet, afin de conserver un minimum de rétrocompatibilité. [[File:Texture combiners Open GL.png|centre|vignette|upright=2|Texture combiners Open GL]] Voici les opérations supportées par les ''combiners'' d'Open GL. Ils prennent en entrée le résultat de l'étage précédent et le combinent avec une texture lue depuis l'unité de texture. {|class="wikitable" |+ Opérations supportées par les ''combiners'' d'Open GL |- ! Replace | colspan="2" | Pixel provenant de l'unité de texture |- ! Addition | colspan="2" | Additionne l'entrée au texel lu. |- ! Modulate | colspan="2" | Multiplie l'entrée avec le texel lu |- ! Mélange (''blending'') | Moyenne pondérée des deux entrées, pondérée par la composante de transparence || La couleur de transparence du texel lu et de l'entrée sont multipliées. |- ! Decals | Moyenne pondérée des deux entrées, pondérée par la composante de transparence. || La transparence du résultat est celle de l'entrée. |} Il faut noter qu'un dernier étage de ''combiners'' s'occupait d'ajouter la couleur spéculaire et les effets de brouillards. Il était à part des autres et n'était pas configurable, c'était un étage fixe, qui était toujours présent, peu importe le nombre de textures utilisé. Il était parfois appelé le '''''combiner'' final''', terme que nous réutiliserons par la suite. Mine de rien, cela a rendu les cartes graphiques partiellement programmables. Le fait qu'il y ait des opérations enchainées à la suite, opérations qu'on peut choisir librement, suffit à créer une sorte de mini-programme qui décide comment mélanger plusieurs textures. Mais il y avait une limitation de taille : le fait que les données soient transmises d'un étage à l'autre, sans détours possibles. Par exemple, le troisième étage ne pouvait avoir comme seule opérande le résultat du second étage, mais ne pouvait pas utiliser celui du premier étage. Il n'y avait pas de registres pour stocker ce qui sortait de la rastérisation, ni pour mémoriser temporairement les texels lus. ===Le ''Transform & Lighting'' matériel de Direct X 7.0=== [[File:Architecture de base d'une carte 3D - 4.png|vignette|upright=1.5|Carte 3D avec gestion de la géométrie.]] La première carte graphique pour PC capable de gérer la géométrie en hardware fût la Geforce 256, la toute première Geforce. Son unité de gestion de la géométrie n'est autre que la bien connue '''unité T&L''' (''Transform And Lighting''). Elle implémentait des algorithmes d'éclairage de la scène 3D assez simples, comme un éclairage de Gouraud, qui étaient directement câblés dans ses circuits. Mais contrairement à la Nintendo 64 et aux bornes d'arcade, elle implémentait le tout, non pas avec un processeur classique, mais avec des circuits fixes. Avec Direct X 7.0 et Open GL 1.0, l'éclairage était en théorie limité à de l'éclairage par sommet, l'éclairage par pixel n'était pas implémentable en hardware. Les cartes graphiques ont tenté d'implémenter l'éclairage par pixel, mais cela n'est pas allé au-delà du support de quelques techniques de ''bump-mapping'' très limitées. Par exemple, Direct X 6.0 implémentait une forme limitée de ''bump-mapping'', guère plus. Un autre problème est que l'éclairage peut s'implémenter de plusieurs manières différentes, aux résultats visuels différents. Les unités de T&L étaient souvent en retard sur les algorithmes logiciels. Les programmeurs avaient le choix entre programmer les algorithmes d’éclairage qu'ils voulaient et les exécuter en logiciel ou utiliser ceux de l'unité de T&L, et choisissaient souvent la première option. Par exemple, Quake 3 Arena et Unreal Tournament n'utilisaient pas les capacités d'éclairage géométrique et préféraient utiliser leurs calculs d'éclairage logiciel fait maison. Cependant, le hardware dépassait les capacités des API et avait déjà commencé à ajouter des capacités de programmation liées au ''multi-texturing''. Les cartes graphiques de l'époque, surtout chez NVIDIA, implémentaient un système de '''''register combiners''''', une forme améliorée de ''texture combiners'', qui permettait de faire une forme limitée d'éclairage par pixel, notamment du vrai ''bump-mampping'', voire du ''normal-mapping''. Mais ce n'était pas totalement supporté par les API 3D de l'époque. Les ''registers combiners'' sont des ''texture combiners'' mais dans lesquels ont aurait retiré la stricte organisation en série. Il y a toujours plusieurs étages à la suite, qui peuvent exécuter chacun une opération, mais tous les étages ont maintenant accès à toutes les textures lues et à tout ce qui sort de la rastérisation, pas seulement au résultat de l'étape précédente. Pour cela, on ajoute des registres pour mémoriser ce qui sort des unités de texture, et pour ce qui sort de la rastérisation. De plus, on ajoute des registres temporaires pour mémoriser les résultats de chaque ''combiner'', de chaque étage. Il faut cependant signaler qu'il existe un ''combiner'' final, séparé des étages qui effectuent des opérations proprement dits. Il s'agit de l'étage qui applique la couleur spéculaire et les effets de brouillards. Il ne peut être utilisé qu'à la toute fin du traitement, en tant que dernier étage, on ne peut pas mettre d'opérations après lui. Sa sortie est directement connectée aux ROPs, pas à des registres. Il faut donc faire la distinction entre les '''''combiners'' généraux''' qui effectuent une opération et mémorisent le résultat dans des registres, et le ''combiner'' final qui envoie le résultat aux ROPs. L'implémentation des ''register combiners'' utilisait un processeur spécialisés dans les traitements sur des pixels, une sorte de proto-processeur de ''shader''. Le processeur supportait des opérations assez complexes : multiplication, produit scalaire, additions. Il s'agissait d'un processeur de type VLIW, qui sera décrit dans quelques chapitres. Mais ce processeur avait des programmes très courts. Les premières cartes NVIDIA, comme les cartes TNT pouvaient exécuter deux opérations à la suite, suivie par l'application de la couleurs spéculaire et du brouillard. En somme, elles étaient limitées à un ''shader'' à deux/trois opérations, mais c'était un début. Le nombre d'opérations consécutives est rapidement passé à 8 sur la Geforce 3. ===L'arrivée des ''shaders'' avec Direct X 8.0=== [[File:Architecture de la Geforce 3.png|vignette|upright=1.5|Architecture de la Geforce 3]] Les ''register combiners'' était un premier pas vers un éclairage programmable. Paradoxalement, l'évolution suivante s'est faite non pas dans l'unité de rastérisation/texture, mais dans l'unité de traitement de la géométrie. La Geforce 3 a remplacé l'unité de T&L par un processeur capable d'exécuter des programmes. Les programmes en question complétaient l'unité de T&L, afin de pouvoir rajouter des techniques d'éclairage plus complexes. Le tout a permis aussi d'ajouter des animations, des effets de fourrures, des ombres par ''shadow volume'', des systèmes de particule évolués, et bien d'autres. À partir de la Geforce 3 de Nvidia, les cartes graphiques sont devenues capables d'exécuter des programmes appelés '''''shaders'''''. Le terme ''shader'' vient de ''shading'' : ombrage en anglais. Grace aux ''shaders'', l'éclairage est devenu programmable, il n'est plus géré par des unités d'éclairage fixes mais été laissé à la créativité des programmeurs. Les programmeurs ne sont plus vraiment limités par les algorithmes d'éclairage implémentés dans les cartes graphiques, mais peuvent implémenter les algorithmes d'éclairage qu'ils veulent et peuvent le faire exécuter directement sur la carte graphique. Les ''shaders'' sont classifiés suivant les données qu'ils manipulent : '''''pixel shader''''' pour ceux qui manipulent des pixels, '''''vertex shaders''''' pour ceux qui manipulent des sommets. Les premiers sont utilisés pour implémenter l'éclairage par pixel, les autres pour gérer tout ce qui a trait à la géométrie, pas seulement l'éclairage par sommets. Direct X 8.0 avait un standard pour les shaders, appelé ''shaders 1.0'', qui correspondait parfaitement à ce dont était capable la Geforce 3. Il standardisait les ''vertex shaders'' de la Geforce 3, mais il a aussi renommé les ''register combiners'' comme étant des ''pixel shaders'' version 1.0. Les ''register combiners'' n'ont pas évolués depuis la Geforce 256, si ce n'est que les programmes sont passés de deux opérations successives à 8, et qu'il y avait possibilité de lire 4 textures en ''multitexturing''. A l'opposé, le processeur de ''vertex shader'' de la Geforce 3 était capable d'exécuter des programmes de 128 opérations consécutives et avait 258 registres différents ! Des ''pixels shaders'' plus évolués sont arrivés avec l'ATI Radeon 8500 et ses dérivés. Elle incorporait la technologie ''SMARTSHADER'' qui remplacait les ''registers combiners'' par un processeur de ''shader'' un peu limité. Un point est que le processeur acceptait de calculer des adresses de texture dans le ''pixel shader''. Avant, les adresses des texels à lire étaient fournis par l'unité de rastérisation et basta. L'avantage est que certains effets graphiques étaient devenus possibles : du ''bump-mapping'' avancé, des textures procédurales, de l'éclairage par pixel anisotrope, du éclairage de Phong réel, etc. Avec la Radeon 8500, le ''pixel shader'' pouvait calculer des adresses, et lire les texels associés à ces adresses calculées. Les ''pixel shaders'' pouvaient lire 6 textures, faire 8 opérations sur les texels lus, puis lire 6 textures avec les adresses calculées à l'étape précédente, et refaire 8 opérations. Quelque chose de limité, donc, mais déjà plus pratique. Les ''pixel shaders'' de ce type ont été standardisé dans Direct X 8.1, sous le nom de ''pixel shaders 1.4''. Encore une fois, le hardware a forcé l'intégration dans une API 3D. ===Les ''shaders'' de Direct X 9.0 : de vrais ''pixel shaders''=== Avec Direct X 9.0, les ''shaders'' sont devenus de vrais programmes, sans les limitations des ''shaders'' précédents. Les ''pixels shaders'' sont passés à la version 2.0, idem pour les ''vertex shaders''. Concrètement, ils sont maintenant exécutés par un processeur de ''shader'' dédié, aux fonctionnalités bien supérieures à celles des ''registers combiners''. Les ''shaders'' pouvaient exécuter une suite d'opérations arbitraire, dans le sens où elle n'était pas structurée avec tel type d'opération au début, suivie par un accès aux textures, etc. On pouvait mettre n'importe quelle opération dans n'importe quel ordre. De plus, les ''shaders'' ne sont plus écrit en assembleur comme c'était le cas avant. Ils sont dorénavant écrits dans un langage de haut-niveau, le HLSL pour les shaders Direct X et le GLSL pour les shaders Open Gl. Les ''shaders'' sont ensuite traduit (compilés) en instructions machines compréhensibles par la carte graphique. Au début, ces langages et la carte graphique supportaient uniquement des opérations simples. Mais au fil du temps, les spécifications de ces langages sont devenues de plus en plus riches à chaque version de Direct X ou d'Open Gl, et le matériel en a fait autant. [[File:Architecture de base d'une carte 3D - 5.png|centre|vignette|upright=1.5|Carte 3D avec pixels et vertex shaders non-unifiés.]] ===L'après Direct X 9.0=== Avant Direct X 10, les processeurs de ''shaders'' ne géraient pas exactement les mêmes opérations pour les processeurs de ''vertex shader'' et de ''pixel shader''. Les processeurs de ''vertex shader'' et de ''pixel shader''étaient séparés. Depuis DirectX 10, ce n'est plus le cas : le jeu d'instructions a été unifié entre les vertex shaders et les pixels shaders, ce qui fait qu'il n'y a plus de distinction entre processeurs de vertex shaders et de pixels shaders, chaque processeur pouvant traiter indifféremment l'un ou l'autre. [[File:Architecture de base d'une carte 3D - 6.png|centre|vignette|upright=1.5|Architecture de la GeForce 6800.]] Avec Direct X 10, de nombreux autres ''shaders'' sont apparus. Les plus liés au rendu 3D sont les '''''geometry shader''''' pour ceux qui manipulent des triangles, de ''hull shaders'' et de ''domain shaders'' pour la tesselation. De plus, les cartes graphiques modernes sont capables d’exécuter des programmes informatiques qui n'ont aucun lien avec le rendu 3D, mais sont exécutés par la carte graphique comme le ferait un processeur d'ordinateur normal. De tels ''shaders'' sans lien avec le rendu 3D sont appelés des ''compute shader''. ==Les cartes graphiques d'aujourd'hui== Avec l'arrivée des shaders, les circuits d'une carte graphique sont divisés en deux catégories : d'un côté les circuits non-programmables et de l'autre les circuits programmables. Pour exécuter les ''shaders'', la carte graphique incorpore des '''processeurs de ''shaders''''', des processeurs similaires aux processeurs des ordinateurs, aux CPU, mais avec quelques petites différences qu'on expliquera dans le prochain chapitre. A côté des processeurs de ''shaders'', il reste quelques circuits non(programmables appelés des circuits fixes. De nos jours, la gestion de la géométrie et des pixels est programmable, mais la rastérisation, le placage de texture, le ''culling'' et l'enregistrement du ''framebuffer'' ne l'est pas. Il n'en a pas toujours été ainsi. [[File:3D-Pipeline.svg|centre|vignette|upright=3.0|Pipeline 3D : ce qui est programmable et ce qui ne l'est pas dans une carte graphique moderne.]] ===Les GPU modernes sont un mélange de processeurs et de circuits fixes=== Une carte graphique contient donc un mélange de circuits fixes et de processeurs de ''shaders'', qui peut sembler contradictoire. Pourquoi ne pas tout rendre programmable ? Ou au contraire, utiliser seulement des circuits fixes ? La réponse rapide est qu'il s'agit d'un compromis entre flexibilité et performance qui permet d'avoir le meilleur des deux mondes. Mais ce compromis a fortement évolué dans le temps, comme on va le voir plus bas. Rendre la gestion de la géométrie ou des pixels programmable permet d'implémenter facilement un grand nombre d'effets graphiques sans avoir à les implémenter en hardware. Avant les ''shaders'', seul le hardware récent gérait les dernières fonctionnalités. Les effets graphiques derniers cri n'étaient disponibles que sur les derniers modèles de carte graphique. Avec des ''vertex/pixel shaders'', ce genre de défaut est passé à la trappe. Si un nouvel algorithme de rendu graphique est inventé, il peut être utilisé dès le lendemain sur toutes les cartes graphiques modernes. De plus, implémenter beaucoup d'algorithmes d'éclairage différents est difficile. Le cout en termes de transistors et de complexité était assez important, utiliser des circuits programmable a un cout en hardware plus limité. Tout cela est à l'exact opposé de ce qu'on a avec les autres circuits, comme les circuits pour la rastérisation ou le placage de texture. Il n'y a pas 36 façons de rastériser une scène 3D et la flexibilité n'est pas un besoin important pour cette opération, alors que les performances sont cruciales. Même chose pour le placage/filtrage de textures. En conséquences, les unités de transformation, de rastérisation et de placage de texture sont toutes implémentées en matériel. Faire ainsi permet de gagner en performance sans que cela ait le moindre impact pour le programmeur. ===Les unités de texture sont intégrées aux processeurs de shaders=== Les unités de textures sont à part des autres circuits fixes, dans le sens où ce sont les seuls à être implémentés dans les processeurs de shaders. Sur les anciennes cartes 3D, les unités de textures étaient des circuits séparés des autres. Mais avec l'arrivée des processeurs de shaders, elles ont été intégrée dans les processeurs de shaders eux-mêmes. Pour comprendre pourquoi, il faut faire un rappel sur ce qu'il y a dans un processeur. Un processeur contient globalement quatre circuits : * une unité de calcul qui fait des calculs ; * des registres pour stocker les opérandes et résultats des calculs ; * une unité de communication avec la mémoire ; * et un séquenceur, un circuit de contrôle qui commande les autres. L'unité de communication avec la mémoire sert à lire ou écrire des données, à les transférer de la RAM vers les registres, ou l'inverse. Lire une donnée demande d'envoyer son adresse à la RAM, qui répond en envoyant la donnée lue. Elle est donc toute indiquée pour lire une texture : lire une texture n'est qu'un cas particulier de lecture de données. Les texels à lire sont à une adresse précise, la RAM répond à la lecture avec le texel demandé. Il est donc possible d'utiliser l'unité de communication avec la mémoire comme si c'était une unité de texture. Cependant, les textures ne sont pas utilisées comme telles de nos jours. Le rendu 3D moderne utilise des techniques dites de filtrage de texture, qui permettent d'améliorer la qualité du rendu des textures. Sans ce filtrage de texture, les textures appliquées naïvement donnent un résultat assez pixelisé et assez moche, pour des raisons assez techniques. Le filtrage élimine ces artefacts, en utilisant une forme d'''antialiasing'' interne aux textures, le fameux filtrage de texture. Le filtrage de texture peut être réalisé en logiciel ou en matériel. Techniquement, il est possible de le faire dans un ''shader'' : le ''shader'' calcule les adresses des texels à lire, lit plusieurs texels, et effectue ensuite le filtrage. En soi, rien d'impossible. Mais le filtrage de texture est toujours effectué directement en matériel. Les processeurs de shaders incorporent des circuits de filtrage de texture, dans l'unité de texture. Pour simplifier l'implémentation, les processeurs de ''shader'' modernes disposent d'une unité d'accès mémoire séparée de l'unité de texture. L'unité d'accès mémoire normale s'occupe des accès mémoire hors-textures, alors que l'unité mémoire s'occupe de lire les textures. L'unité de texture contient de quoi faire du filtrage de texture, mais aussi faire des calculs d'adresse spécialisées, intrinsèquement liés au format des textures, qu'on détaillera dans le chapitre sur les textures. En comparaison, les unités d'accès mémoire effectuent des calculs d'adresse plus basiques. Un dernier avantage est que l'unité de texture est reliée au cache de texture, alors que l'unité d'accès mémoire est relié au cache L1/L2. La raison est que le filtrage de texture est une opération très simple à implémenter en hardware, qui demande assez peu de circuits. Le filtrage bilinéaire ou trilinéaire demande juste des circuits d'interpolation et quelques registres, ce qui est trivial. Et la seconde raison est qu'il n'y a pas 36 façons de filtrer des textures : une carte graphique peut implémenter les algorithmes principaux existants en assez peu de circuits. : Il faut noter que les ROPs peuvent aussi être intégré dans les processeurs de ''shader'', mais c'est assez rare. Les cartes graphiques pour PC ont des ROPs séparés des processeurs de ''shaders''. Par contre, quelques cartes graphiques destinées les smartphones et autres appareils mobiles font exception. Sur celles-ci, les unités de textures et les ROPs sont intégrés dans les processeurs de ''shaders'', aux côtés de l'unité d'accès mémoire LOAD/STORE. Il s'agit de cartes graphiques en rendu à tuiles. {{NavChapitre | book=Les cartes graphiques | prev=Les cartes graphiques : architecture de base | prevText=Les cartes graphiques : architecture de base | next=Les processeurs de shaders | nextText=Les processeurs de shaders }} {{autocat}} a17i0s6rz2k3npkd97f0i32coxa71yv Fonctionnement d'un ordinateur/Les mémoires historiques 0 69063 744178 729386 2025-06-05T17:40:44Z Mewtow 31375 /* Les tambours magnétiques */ 744178 wikitext text/x-wiki Au tout début de l'informatique, les mémoires étaient totalement différentes d'aujourd'hui. Il n'y avait pas de mémoire ROM, de mémoire RAM, ou quoique ce soit d'autres. Les premières mémoires n'étaient pas électroniques, la technologie n'étant pas assez avancée pour cela. On parle d'un temps où les transistors n'existaient pas et où l'informatique était en pleine gestation. Pourtant, les mémoires existaient déjà. L'électronique analogique avait déjà des supports de stockage : les lecteurs audio utilisaient des cassettes audio à bande magnétiques, les lecteurs vidéo utilisaient des cassettes VHS elles aussi basées sur des bandes magnétiques, et j'en passe. Une partie de ces supports de stockage ont été réutilisés, puis adaptés pour les ordinateurs de l'époque. En conséquence, les premières mémoires informatiques étaient des mémoires magnétiques, bien plus rudimentaires que les disques durs et les disquettes : mémoires à tores de ferrite, bandes magnétiques, et bien d'autres (cassettes audio, notamment). D'autres mémoires historiques étaient des mémoires mécaniques, qui stockaient leurs informations sous la forme de trous dans une carte en plastique, d'ondes sonores, etc. Ces mémoires, aujourd'hui totalement obsolètes, ont pourtant eu leur heure de gloire, certaines étant plus utilisées que les mémoires magnétiques ou électroniques de leur époque. Ce chapitre se propose de rendre hommage à ces mémoires historiques. Toutes les mémoires que nous allons aborder sont aujourd'hui obsolètes et la plupart ne sont même plus produites du tout. On peut encore en trouver dans des musées, mais leur utilisation réelle est réduite à peau de chagrin. ==Les cartes et rubans perforés== Les toutes premières mémoires informatiques étaient des mémoires mécaniques. Les mémoires mécaniques les plus connues étaient basées sur du papier : je veux parler des '''cartes et rubans perforés'''. Il s'agit de cartes ou de rubans de papier, parfois de carton ou de plastiques. Les données sont stockées sous la forme de trous dans le ruban ou la carte : un trou code un 1, tandis que l'absence d'un trou code un 0. [[File:2punchCards.jpg|centre|vignette|Carte perforée.]] ==Les bandes magnétiques== [[File:Digital pdp8-e.jpg|vignette|Ordinateur Digital PDP-8, avec ses bandes magnétiques visibles.]] De vieux ordinateurs utilisaient des cassettes à bande magnétique, les mêmes qui étaient utilisées comme cassettes audio il y a de cela quelques décennies. C'était le cas de vieux ordinateurs personnels, comme les Amstrad CPC, les ZX Spectrum, ou les ordinateurs Commodore. [[File:Amstrad CPC 464 computer at Play Expo 2013.JPG|centre|vignette|Ordinateur personnel Amstrad CPC 464.]] D'autres ordinateurs de la même époque utilisaient des supports de stockage similaires aux cassettes audio, mais sans le plastique extérieur. Des bandes magnétiques étaient enroulées dans un cylindre plastique, et étaient déroulées par un système de déroulement. ==Les tambours magnétiques== [[File:ERA Magnetic Drum, US, c. 1951 - Computer History Museum - Mountain View, California.jpg|vignette|ERA Magnetic Drum, US, c. 1951 - Computer History Museum - Mountain View, California]] Les '''tambours magnétiques''' sont les ancêtres du disque durs, les deux ayant un fonctionnement assez similaire. La différence principale est que les plateaux sont remplacés par un tube cylindrique, dont la surface est couverte d'un matériau magnétique. L'organisation en pistes est toujours présente, chaque piste étant une ligne horizontale sur le tube central. Par contre, il n'y a pas de tête de lecture/écriture qui se déplace de piste en piste. Les têtes de lecture/écriture sont immobiles, mais il y en a une par piste pour compenser. Le temps de latence d'un tel disque dépend donc uniquement de la vitesse de rotation et de la densité surfacique. Fait surprenant, les tambours magnétiques étaient utilisés comme mémoire primaire, c'est à dire qu'elles avaient la même fonction que la mémoire RAM des PC actuels, malgré leur caractère non-volatile ! De nombreux ordinateurs de l'époque exécutaient des programmes directement depuis le tambour magnétique. Les instructions étaient mémorisées sur le tambour magnétique, étaient copiées dans un registre d'instruction, puis exécutées. Pour garder des performances correctes, la répartition des instructions dans les secteurs devait être optimisée. Les programmeurs ayant travaillé, par exemple sur l'IBM 650, devaient prendre en compte la manière dont les instructions étaient placées dans et entre les secteurs pour éviter des pertes de performance. Les tambours magnétiques étaient aussi utilisées comme mémoire de masse, mais c'était une utilisation moins fréquente. Les tambours magnétiques avaient cependant une méthode d'adressage différente selon qu'ils étaient utilisées comme mémoire de masse ou primaire. Les tambours utilisées comme mémoire primaire avaient une adresse par mot mémoire, alors que celles utilisées comme mémoire de masse avaient une adresse par secteur ou par piste. La méthode d'adressage variait suivant le tambour. * Sur certains tambours, chaque piste avait sa propre adresse mémoire. Les pistes étaient de taille variable suivant la marque du tambour magnétique utilisé, mais chacune avait sa propre adresse. * Sur d'autres, chaque piste était découpée en secteurs de taille fixe, comme sur les disques durs, et chaque secteur était adressé en précisant le numéro de piste et un numéro de secteur (similaire à l'adressage CHS des disques durs, en enlevant les plateaux). * Sur d'autres, les secteurs avaient une taille variable, l'adressage se faisait en indiquant le numéro de la piste et la position du secteur dans la piste. * D'autres mémoires utilisaient des systèmes d'adressages différents. ==Les mémoires à tore de ferrite== Les premières mémoires de masse sont sans conteste les '''mémoires à tores de ferrites'''. Ce sont des mémoires magnétiques, un peu comme les disques durs, même si les différences sont nombreuses. Elles sont donc naturellement non-volatiles. Elles sont formées d'une matrice de tores fabriqués dans un matériau magnétique (ferromagnétique pour être précis), le plus souvent de la ferrite. Ces tores peuvent être magnétisés dans deux sens différents, ce qui leur permet de coder un bit. [[File:KL CoreMemory Macro.jpg|centre|vignette|Mémoire à tores de ferrite réelle (avec les fils).]] ===Le fonctionnement d'une mémoire à tore de ferrite=== L'ensemble formait une sorte de tableau où chaque tore a deux positions : une position X et une autre position Y. Deux fils servent pour l'adressage : le fil Y traverse tous les tores d'une ligne, alors que le fil X traverse tous les tores placés sur la même colonne. Quand une tension est envoyée sur un fil Y et un fil X, le tore à l'intersection des deux fils est activé : il peut alors être lu ou écrit. Plus précisément, chaque fil est parcouru par une tension légèrement supérieure à la moitié de la tension nécessaire pour aimanter le tore : ainsi, la somme des deux tensions est supérieure à la tension d'aimantation, mais seulement à l'intersection des deux fils, sur le tore à aimanter. Selon la tension envoyée (plus précisément, son signe), le tore sera mis à 0 ou à 1. [[File:Coincident-current magnetic core.svg|centre|vignette|Schéma de la matrice de tores (avec les fils).]] Pour lire ou écrire un bit dans un tore (en changer l'aimantation), il faut que celui-ci soit soumis à un champ magnétique supérieur à une valeur déterminée. pour cela, chaque tore est parcouru par quatre fils : le fil X et Y servent pour l'adressage, comme dit plus haut, un fil S (''Sense'') pour les lectures, et un fil Z pour les écritures. En faisant passer un courant ou une tension dans ces fils, un champ magnétique se forme autour d'eux, ce qui agit sur les tores de ferrites ce qui permet de les aimanter (écriture) ou de lire leur contenu. [[File:Single coincident-current magnetic core.svg|centre|vignette|Un tore de ferrite.]] La lecture s'effectue via le fil nommé ''Sense''. Toute lecture est destructrice : le bit stocké dans le tore est effacé après chaque lecture. En effet, chaque lecture commence par mettre à zéro le bit à lire. Cette mise à zéro va ou non, faire changer le champ magnétique dans le fil ''Sense'', entrainant l'apparition d'un courant et d'une tension. Suite à cette mise à zéro, la mémoire regarde ce qui se passe sur ce fil. Si le bit était déjà à zéro avant la lecture, aucun champ magnétique ne sera créé : il ne se passe rien sur le fil ''Sense''. Mais si ce bit était à 1, le tore va changer de polarité, entrainant l'apparition d'une tension sur ce fil, durant un temps très bref (le temps de changement de polarité du tore). La lecture s'effectue donc via le fil ''Sense'', suivant ce qui s'y passe lors d'une mise à zéro d'un bit. L'écriture s'effectue d'une manière différente, quoique similaire, en utilisant le fil ''Z''. Lors d'une écriture d'un tore, les fils X et Y qui correspondent sont alimentés en tension, de telle manière qu'un 1 soit écrit dans le tore. Pour écrire un 1, cela suffit largement. Mais pour écrire un zéro, il faut que quelque chose annule cette écriture, en compensant le champ magnétique créé par ces deux fils. Pour cela, on fait passer un courant dans le fil ''Inhibit'', afin de créer un champ magnétique contraire dans le tore. Cela annule l'écriture du 1 en inhibant le champ crée par les fils X et Y. La plupart des mémoires de ce type utilisaient deux fils ''Sense'' et ''Inhibit'' séparés. Mais vu que le fil ''Inhibit'' et ''Sense'' ne sont jamais utilisés en même temps, certaines mémoires à tore ont fusionné ces deux fils en un seul. ===Une mémoire très fiable=== Les mémoires à tore de ferrite sont des mémoires non-volatiles très fiables. Elles ne s'effacent pas dans le temps et peuvent supporter des conditions très dures sans perdre de données. Par exemple, elles peuvent résister à des radiations extrêmes , voire à une EMP, sans perdre de données. C'est pour cette raison qu'elles ont beaucoup été utilisées dans des applications aérospatiales, dans l'industrie, voire dans les applications militaires. Elles étaient encore utilisées dans ces applications bien après l'apparition des premières mémoires à semi-conducteurs. Par contre, ces mémoires étaient très sensibles à la température. Les tensions à envoyer aux tores devaient avoir une valeur bien précise, qui dépend énormément de la température ambiante. Sur les premières mémoires à tore de ferrite, les circuits de contrôle de la mémoire contenaient un senseur de température et ajustaient les tensions appliquées en fonction des mesures. Une autre solution consistait à placer la mémoire dans une petite boite dont la température était maintenue stable. Généralement, la boite était chauffée au-dessus de la température ambiante, car maintenir une température constante est facile quand celle-ci est plus élevée que la normale. Chauffer une petite chambre est plus simple que de la refroidir, surtout pour une petite boite. Autant une simple résistance permet de chauffer la boite, autant utiliser un réfrigérateur pour une mémoire de ce type était clairement une mauvaise solution. Le défaut principal de ces mémoires est que leur processus de fabrication est difficile à industrialiser. La fabrication de ces mémoires s'est surtout fait de main d'homme, sans machines ou du moins avec peu d'outils. Le fait que ces mémoires ne puisse pas facilement être fabriquées par des machines fait que ces mémoires sont difficiles à miniaturiser : la miniaturisation ne va pas aussi loin que pour les mémoires à semi-conducteurs et on peut tout au plus stocker quelques centaines de bits sur une puce, voire quelques milliers. La capacité de telles mémoire est généralement assez faible. Par contre, leurs performances étaient assez honorables. On estime que les premières mémoires de ce type avaient un temps d'accès mémoire d'environ 6 µs, ce qui fait une fréquence d'environ 166.7 kilohertz. Le temps d'accès est ensuite descendu à 0.6 µs durant les années 70, ce qui faisait une fréquence proche du mégahertz. [[File:Ferrite core memory.jpg|centre|vignette|upright=1.5|Mémoire à tore Ferrite miniaturisée. La puce fait 10 centimètres de coté et contient 64 mots de 64 bits, soit 4 kikioctets.]] ==Les mémoires à ligne de délai== Les '''mémoires à ligne de délai''' sont des mémoires volatiles mécaniques, basées sur des ondes sonores ! Celles-ci ont été inventées suite à des technologies liées aux radars, dans les laboratoires militaires. Ces mémoires sont des mémoires séquentielles, qui ont une capacité extrêmement faible (quelques centaines de bits). Il en existe diverses versions, la première étant basée sur des tubes de mercure, les suivantes étant basées sur des tubes de cuivre ou d'autre matériaux magnétiques. ===L'intérieur d'une mémoire à ligne de délai=== Ces mémoires sont basées sur un tube de matière, dans lequel se propage une onde sonore : celui-ci sert de support de mémorisation. Un bit est codé par l'absence ou la présence d'une onde sonore dans le tube de matière. Au bout de ce tube, on trouve un microphone et un haut-parleur. Le haut-parleur génère une onde sonore d'un côté du tube, onde qui est reçue de l'autre côté du tube par le microphone. De plus, le haut-parleur et le microphone sont reliés entre eux : le signal capté sur le microphone est envoyé sur le haut-parleur d'entrée. Ce faisant, l'onde sonore circule en boucle dans le circuit : elle est rafraichie sans cesse, à chaque passage. [[File:Delay line memory fr.svg|centre|vignette|upright=2.0|Mémoire à ligne de délai.]] Divers circuits sont présents entre le microphone et le haut-parleur. On trouve notamment des amplificateurs, histoire que les ondes sonores captées ne s'amenuisent pas à force de reparcourir le tube. [[File:SEACComputer 010.jpg|centre|vignette|upright=2.0|Mémoire à tube de mercure.]] ===La capacité des mémoires à ligne de délai=== Il existe naturellement un petit délai de transmission entre le microphone et le haut-parleur, ainsi qu'un autre délai de propagation dans le tube. Ces délais limitent la capacité de la mémoire, qui dépend du nombre d'ondes sonores qui peuvent parcourir le tube. Chaque bit est codée exactement par une impulsion sonore, qui a une forme et une durée très précise, qui dépend de la qualité du circuit (microphone, haut-parleur, et autres) : notons ce temps <math>\Tau</math>. La capacité totale est, par définition, égale au nombre d'impulsions qui se trouvent en même temps dans le tube de matière (les unes à la suite des autres). Pour la calculer, on peut diviser le temps que met une impulsion à se propager dans le tube, par la durée d'une impulsion. ===Les différents types de mémoires à lignes de délai=== Les premières mémoires de ce type étaient fabriquées avec des tubes de mercure : ce sont des '''lignes à délai de mercure'''. [[File:Mercury memory.jpg|centre|vignette|SEAC Computer, avec une mémoire à ligne de Mercure.]] Mais les inconvénients du mercure (toxicité, notamment) ont mené au remplacement du mercure par des tubes de matériaux conducteurs (des fils électriques, dit autrement) : ce sont des '''lignes de délai à torsion de fil'''. [[File:Torsion wire delay line.jpg|centre|vignette|Exemple de ligne de délai à torsion de fil.]] ==Les tubes Williams et Selectron== Les '''tubes ''Williams''''' et '''Selectron''' sont basés sur un écran CRT modifié. Il s'agissait de mémoires de type mémoires vives volatiles qui devaient être rafraichies régulièrement. En clair, ce sont l'ancêtre des mémoires DRAM ! Les ''tubes Williams'' étaient utilisés sur les tout premiers ordinateurs, au tout début de l'histoire de l'informatique, dans les années 50, à une époque où les ordinateurs étaient des monstres qui occupaient une pièce entière et étaient plus proches de petites usines à calcul qu'autre chose. Une technologie alternative basée sur un principe simialire est le ''Tube Selectron''. D'une capacité de 256 bits, il n'a été utilisé que sur un seul ordinateur : le JOHNNIAC de la RAND Corporation. Ils ont tous deux était rapidement remplacé par les mémoires à ligne de délai, plus simples et moins chères. [[File:Williams-tube.jpg|centre|vignette|upright=2|Williams-tube]] ===Les écrans CRT (''Cathode Ray Tube'')=== Tubes Williams et Selectron se basent sur la même technologie : celle des écrans CRT. Un écran CRT est composé de plusieurs composants, qui marchent de concert : un canon à électron, des bobines de contrôle et la surface de l'écran proprement dite. Le canon à électron émet un faisceau d'électron concentré, qui touche la surface de l'écran. Cette dernière, du moins derrière la vitre transparente, est d'une composition chimique particulière et est notamment riche en phosphore. Elle est souvent appelée ''surface phosphorescente''. Quand elle est touchée par le faisceau d’électron, le phosphore s'illumine pendant quelques millisecondes. Les bobines visent à détourner le faisceau d'électron de manière à ce qu'il balaye tout l'écran de gauche à droite et de haut en bas. [[File:Cathode ray tube fr.svg|centre|vignette|upright=2|Cathode ray tube.]] La surface de l'écran est découpée en pixels, et l'intensité du canon varie pour chaque pixel lorsque le faisceau passe sur ce pixelde l'écran. En commandant l'intensité du canon d'électron, on arrive à afficher des images en noir et blanc ainsi. Un canon intense pendant x millisecondes donnera un point blanc sur l'écran, là où tombe de faisceau. un canon éteint donnera un point noir à l'écran. Il est possible de gérer la couleurs avec des écrans CRT plus complexes, mais ce n'est pas le sujet et nous n'en avons pas besoin pour les explications qui vont suivre. ====La physique de la surface phosphorescente : émission secondaire et puits de potentiels==== Un point important est que la physique de la surface phosphorescente n'est pas intuitive et peu donner lieu à des phénomènes assez importants pour ce qui va suivre. Deux d'entre eu vont nous intéresser. Le premier est que les électrons émis par le canaux à électrons frappent la surface phosphorescente, l'illuminent, mais qu'il arrive que des électrons soient piégés dans la surface, à l'endroit de l'impact. En conséquence, une petite charge électrique s'accumule progressivement à chaque passage du faisceau, dans chaque pixel. Les électrons ne restent pas en place de manière permanente, ils finissent par s'échapper après un certain temps, ce qui fait que la charge finit par s'atténuer, mais elle peut durer quelques secondes sur les CRT conçus pour exploiter cet effet au mieux. Le second phénomène est l''''émission secondaire'''. Quand l'énergie du faisceau à électron est trop forte, les électrons naturellement présents dans les atomes du matériau phosphorescent sont dégagés. Les électrons éjectés deviennent alors des électrons libres qui vont allumer les zones alentours, ce qui perturbe l'affichage. Et cela arrive lors que la zone frappée par le faisceau a perdu des électrons et ne s'allume plus. Le résultat est que si une image était affichée sur l'écran auparavant, utiliser un faisceau trop fort l'efface totalement via émission secondaire. Il s'agit là d'un défaut à éviter sur les écrans d'affichage, mais c'est ce phénomène qui est utilisé sur les mémoires à tubes de stockage. ====Les CRT rémanents==== Il existe des écrans CRT conçus pour afficher des images sur une longue durée de temps, et pas seulement pour un 50ème ou 60ème de seconde. Ils sont appelés des '''écrans rémanents''' ou encore '''''storage tubes''''', ou tubes de stockage. Avec eux, l'image affichée s'efface progressivement et lentement, mais reste visible durant quelques secondes. Pour cela, les écran de stockage sont fabriqués en utilisant un matériau phosphorescent spécial, différent de celui des autres CRT, mais le reste du CRT fonctionne de la même manière. La rémanence est liée au premier phénomène mentionné plus haut, à savoir la capture d'électrons par la surface, mais ce phénoméne est maximisé par l'usage du matériau adéquat. Cette rémanence de quelques secondes fait que l'image a besoin d'être rafraichie moins souvent, comparée à un écran CRT normal. Et les mémoires Selectron et de Williams sont basées sur de tels tubes de stockage. La rémanence de l'image a de nombreuses applications et est utile quand on n'a pas besoin d'une réactivité importante. Elle était utile dans les radars, dans certains oscilloscopes qui demandent de capturer des évènements très brefs, etc. Quelques écrans d'ordinateur ont tenté d'utiliser ce système, notamment les écrans de la marque Textronix. Ils portent le nom de '''''Direct-view bistable storage tube'''''. L'idée est d'utiliser un écran CRT rémanent pour afficher une image pour éviter de rafraichir l'écran souvent. Mais pour quel l'écran soit réactif et éviter des artefacts graphiques liés à la rémanence, on est obligé d'effacer l'écran avant d'afficher une nouvelle image. Et l'effacement se fait grâce à l'émission secondaire. Pour cela, de tels écrans contenaient deu faisceaux : un faisceau normal pour afficher une image, un autre faisceau très puissant qui déclenche une émission secondaire pour effacer l'écran. ===Les tubes Williams=== [[File:SWAC 003.jpg|vignette|Image affichée par un tube Williams en fonctionnement, sur l'ordinateur SWAC.]] L'idée derrière les tubes tubes Williams et Selectron est de mémoriser les données sous la forme d'images à l'écran. Un bit à 1 correspond à un pixel allumé/lumineux, un bit à 0 à un pixel éteint/noir. Les écrans de l'époque ne géraient pas la couleur, aussi seul le noir et blanc était disponible (avec les niveaux de gris), ce qui est parfait pour un stockage en binaire. L'image affichée par un écran CRT est affichée ligne par ligne, avec un petit temps de pause entre l'affichage de deux lignes pour repositionner le canon à électron sur le début de la ligne suivante. Par simplicité, sur les tubes Williams, chaque ligne correspond à un mot mémoire, une case mémoire. La taille d'un mot mémoire et le nombre d'adresse dépend donc de la résolution utilisée. Un tube Williams est composé d'un tube CRT rémanent et d'une plaque de métal placée devant l'écran, et de circuits électroniques annexes. La plaque de métal est collée à l'écran, ce qui fait qu'on ne peut pas voir l'écran proprement dit. Elle sert uniquement lors des lectures et pas pour les écritures. Lors d'une lecture, on mesure la tension sur la plaque, qui dépendra du bit stocké au moment de la lecture. La lecture se fait bit par bit, un par un. Elle est reliée à un circuit amplificateur de tension, qui amplifie la tension mesurée par la plaque. On trouve aussi des circuits pour le contrôle de l'écran CRT, à savoir des registres X et Y pour commander les bobines de défléction, de quoi générer un signal d'horloge, et des circuits électroniques pour gérer les lectures/écritures. [[File:WilliamsTubeFigure1.tiff|centre|vignette|upright=2|WilliamsTubeFigure1]] L'écriture et l’effacement de l'image est ce qu'il y a de plus facile : écrire une image utilise un faisceau d’électrons normal qu'on allume ou éteint convenablement lors du balayage de l'écran, l'effacer demande de faire la même chose en utilisant un faisceau très puissant. Un faisceau normal allume le phosphore et le charge pendant un certain temps, alors que l'émission secondaire efface ce qui a été enregistré sur le phosphore. Pour lire un bit, on envoie un faisceau d'électron sur sa position sur l'écran, dont l'intensité est situé juste en-dessous du seuil pour l'émission secondaire. Si le bit stocké est à 0, l'intensité ne sera pas suffisante pour générer une émission secondaire. Mais si cil stocke un 1, la charge électrique stockée sur la surface phosphorescente va s'additionner à l’intensité du faisceau et déclencher une émission secondaire. L’émission secondaire a déclencher une augmentation local de la tension électrique, que la plaque de métal va capter. Un amplifieur amplifie la tension mesurée sur la plaque, pour en faire une tension capable de coder un 0 ou un 1. Vous remarquerez que la lecture est destructrice, ce qui fait que toute lecture de l'écran est suivie par une écriture pour compenser, comme sur les DRAM. [[File:Williams tube timing.jpg|centre|vignette|upright=2|Williams tube timing]] Passons maintenant au rafraichissement mémoire. Il faut rafraichir l'écran pour une raison simple : l'image affichée par l'écran s'efface au bout de quelques millisecondes, quelques secondes, tout dépend du type d'écran utilisé. Le rafraichissement se fait en effectuant une lecture suivie d'une écriture : on récupère le contenu de la mémoire/tube, avant de le réécrire. Autour de la plaque de métal et du tube CRT, on trouve divers circuits qui gèrent les lectures et écritures. Les lectures et écritures se font bit par bit, on peut masquer certains bits lors des écritures, autoriser ou interdire les lectures/écritures durant un temps, etc. [[File:SEACComputer 004.jpg|centre|vignette|upright=2|Fonctionnement d'un tube Williams, avec les circuits associés]] <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> m7qs12zz8hj8fna3phbjd6z6z7vw8di 744180 744178 2025-06-05T17:52:53Z Mewtow 31375 /* Les tambours magnétiques */ 744180 wikitext text/x-wiki Au tout début de l'informatique, les mémoires étaient totalement différentes d'aujourd'hui. Il n'y avait pas de mémoire ROM, de mémoire RAM, ou quoique ce soit d'autres. Les premières mémoires n'étaient pas électroniques, la technologie n'étant pas assez avancée pour cela. On parle d'un temps où les transistors n'existaient pas et où l'informatique était en pleine gestation. Pourtant, les mémoires existaient déjà. L'électronique analogique avait déjà des supports de stockage : les lecteurs audio utilisaient des cassettes audio à bande magnétiques, les lecteurs vidéo utilisaient des cassettes VHS elles aussi basées sur des bandes magnétiques, et j'en passe. Une partie de ces supports de stockage ont été réutilisés, puis adaptés pour les ordinateurs de l'époque. En conséquence, les premières mémoires informatiques étaient des mémoires magnétiques, bien plus rudimentaires que les disques durs et les disquettes : mémoires à tores de ferrite, bandes magnétiques, et bien d'autres (cassettes audio, notamment). D'autres mémoires historiques étaient des mémoires mécaniques, qui stockaient leurs informations sous la forme de trous dans une carte en plastique, d'ondes sonores, etc. Ces mémoires, aujourd'hui totalement obsolètes, ont pourtant eu leur heure de gloire, certaines étant plus utilisées que les mémoires magnétiques ou électroniques de leur époque. Ce chapitre se propose de rendre hommage à ces mémoires historiques. Toutes les mémoires que nous allons aborder sont aujourd'hui obsolètes et la plupart ne sont même plus produites du tout. On peut encore en trouver dans des musées, mais leur utilisation réelle est réduite à peau de chagrin. ==Les cartes et rubans perforés== Les toutes premières mémoires informatiques étaient des mémoires mécaniques. Les mémoires mécaniques les plus connues étaient basées sur du papier : je veux parler des '''cartes et rubans perforés'''. Il s'agit de cartes ou de rubans de papier, parfois de carton ou de plastiques. Les données sont stockées sous la forme de trous dans le ruban ou la carte : un trou code un 1, tandis que l'absence d'un trou code un 0. [[File:2punchCards.jpg|centre|vignette|Carte perforée.]] ==Les bandes magnétiques== [[File:Digital pdp8-e.jpg|vignette|Ordinateur Digital PDP-8, avec ses bandes magnétiques visibles.]] De vieux ordinateurs utilisaient des cassettes à bande magnétique, les mêmes qui étaient utilisées comme cassettes audio il y a de cela quelques décennies. C'était le cas de vieux ordinateurs personnels, comme les Amstrad CPC, les ZX Spectrum, ou les ordinateurs Commodore. [[File:Amstrad CPC 464 computer at Play Expo 2013.JPG|centre|vignette|Ordinateur personnel Amstrad CPC 464.]] D'autres ordinateurs de la même époque utilisaient des supports de stockage similaires aux cassettes audio, mais sans le plastique extérieur. Des bandes magnétiques étaient enroulées dans un cylindre plastique, et étaient déroulées par un système de déroulement. ==Les tambours magnétiques== [[File:ERA Magnetic Drum, US, c. 1951 - Computer History Museum - Mountain View, California.jpg|vignette|ERA Magnetic Drum, US, c. 1951 - Computer History Museum - Mountain View, California]] Les '''tambours magnétiques''' sont les ancêtres du disque durs, les deux ayant un fonctionnement assez similaire. La différence principale est que les plateaux sont remplacés par un tube cylindrique, dont la surface est couverte d'un matériau magnétique. L'organisation en pistes est toujours présente, chaque piste étant une ligne horizontale sur le tube central. Par contre, il n'y a pas de tête de lecture/écriture qui se déplace de piste en piste. Les têtes de lecture/écriture sont immobiles, mais il y en a une par piste pour compenser. Le temps de latence d'un tel disque dépend donc uniquement de la vitesse de rotation et de la densité surfacique. ===Les tambours magnétiques étaient des mémoires primaires=== Fait surprenant, les tambours magnétiques étaient utilisés comme mémoire primaire, c'est à dire qu'elles avaient la même fonction que la mémoire RAM des PC actuels, malgré leur caractère non-volatile ! Les tambours magnétiques étaient aussi utilisées comme mémoire de masse, mais c'était une utilisation moins fréquente. De nombreux ordinateurs de l'époque exécutaient des programmes directement depuis le tambour magnétique. Les instructions étaient mémorisées sur le tambour magnétique, étaient copiées dans un registre d'instruction, puis exécutées. Pour garder des performances correctes, la répartition des instructions dans les secteurs devait être optimisée. Les programmeurs ayant travaillé, par exemple sur l'IBM 650, devaient prendre en compte la manière dont les instructions étaient placées dans et entre les secteurs pour éviter des pertes de performance. L'ordinateur Bull Gamma 3 intégrait une sorte de cache d'instruction pour accélérer l'exécution des programmes depuis le tambour magnétique. Les instructions étaient stockées sur le tambour par groupes de 48 instructions, appelés des séries. Le processeur est relié à mémoires intermédiaires, appelées des ''Circulating Memories'', chacune contenant une série complète. Pour exécuter une instruction, la série complète était recopiée dans une ''Circulating Memories'', si ce n'est pas déjà fait, puis l'instruction était copiée dans le registre d'instruction. Les ''Circulating Memories'' étaient implémentées avec des mémoires magnéto-résistives à ligne de mercure, qu'on détaillera dans la suite de ce chapitre. ===L'adressage sur un tambour magnétique=== Les tambours magnétiques avaient une méthode d'adressage différente selon qu'ils étaient utilisées comme mémoire de masse ou primaire. Les tambours utilisées comme mémoire primaire avaient une adresse par mot mémoire, alors que celles utilisées comme mémoire de masse avaient une adresse par secteur ou par piste. La méthode d'adressage variait suivant le tambour. * Sur certains tambours, chaque piste avait sa propre adresse mémoire. Les pistes étaient de taille variable suivant la marque du tambour magnétique utilisé, mais chacune avait sa propre adresse. * Sur d'autres, chaque piste était découpée en secteurs de taille fixe, comme sur les disques durs, et chaque secteur était adressé en précisant le numéro de piste et un numéro de secteur (similaire à l'adressage CHS des disques durs, en enlevant les plateaux). * Sur d'autres, les secteurs avaient une taille variable, l'adressage se faisait en indiquant le numéro de la piste et la position du secteur dans la piste. * D'autres mémoires utilisaient des systèmes d'adressages différents. ==Les mémoires à tore de ferrite== Les premières mémoires de masse sont sans conteste les '''mémoires à tores de ferrites'''. Ce sont des mémoires magnétiques, un peu comme les disques durs, même si les différences sont nombreuses. Elles sont donc naturellement non-volatiles. Elles sont formées d'une matrice de tores fabriqués dans un matériau magnétique (ferromagnétique pour être précis), le plus souvent de la ferrite. Ces tores peuvent être magnétisés dans deux sens différents, ce qui leur permet de coder un bit. [[File:KL CoreMemory Macro.jpg|centre|vignette|Mémoire à tores de ferrite réelle (avec les fils).]] ===Le fonctionnement d'une mémoire à tore de ferrite=== L'ensemble formait une sorte de tableau où chaque tore a deux positions : une position X et une autre position Y. Deux fils servent pour l'adressage : le fil Y traverse tous les tores d'une ligne, alors que le fil X traverse tous les tores placés sur la même colonne. Quand une tension est envoyée sur un fil Y et un fil X, le tore à l'intersection des deux fils est activé : il peut alors être lu ou écrit. Plus précisément, chaque fil est parcouru par une tension légèrement supérieure à la moitié de la tension nécessaire pour aimanter le tore : ainsi, la somme des deux tensions est supérieure à la tension d'aimantation, mais seulement à l'intersection des deux fils, sur le tore à aimanter. Selon la tension envoyée (plus précisément, son signe), le tore sera mis à 0 ou à 1. [[File:Coincident-current magnetic core.svg|centre|vignette|Schéma de la matrice de tores (avec les fils).]] Pour lire ou écrire un bit dans un tore (en changer l'aimantation), il faut que celui-ci soit soumis à un champ magnétique supérieur à une valeur déterminée. pour cela, chaque tore est parcouru par quatre fils : le fil X et Y servent pour l'adressage, comme dit plus haut, un fil S (''Sense'') pour les lectures, et un fil Z pour les écritures. En faisant passer un courant ou une tension dans ces fils, un champ magnétique se forme autour d'eux, ce qui agit sur les tores de ferrites ce qui permet de les aimanter (écriture) ou de lire leur contenu. [[File:Single coincident-current magnetic core.svg|centre|vignette|Un tore de ferrite.]] La lecture s'effectue via le fil nommé ''Sense''. Toute lecture est destructrice : le bit stocké dans le tore est effacé après chaque lecture. En effet, chaque lecture commence par mettre à zéro le bit à lire. Cette mise à zéro va ou non, faire changer le champ magnétique dans le fil ''Sense'', entrainant l'apparition d'un courant et d'une tension. Suite à cette mise à zéro, la mémoire regarde ce qui se passe sur ce fil. Si le bit était déjà à zéro avant la lecture, aucun champ magnétique ne sera créé : il ne se passe rien sur le fil ''Sense''. Mais si ce bit était à 1, le tore va changer de polarité, entrainant l'apparition d'une tension sur ce fil, durant un temps très bref (le temps de changement de polarité du tore). La lecture s'effectue donc via le fil ''Sense'', suivant ce qui s'y passe lors d'une mise à zéro d'un bit. L'écriture s'effectue d'une manière différente, quoique similaire, en utilisant le fil ''Z''. Lors d'une écriture d'un tore, les fils X et Y qui correspondent sont alimentés en tension, de telle manière qu'un 1 soit écrit dans le tore. Pour écrire un 1, cela suffit largement. Mais pour écrire un zéro, il faut que quelque chose annule cette écriture, en compensant le champ magnétique créé par ces deux fils. Pour cela, on fait passer un courant dans le fil ''Inhibit'', afin de créer un champ magnétique contraire dans le tore. Cela annule l'écriture du 1 en inhibant le champ crée par les fils X et Y. La plupart des mémoires de ce type utilisaient deux fils ''Sense'' et ''Inhibit'' séparés. Mais vu que le fil ''Inhibit'' et ''Sense'' ne sont jamais utilisés en même temps, certaines mémoires à tore ont fusionné ces deux fils en un seul. ===Une mémoire très fiable=== Les mémoires à tore de ferrite sont des mémoires non-volatiles très fiables. Elles ne s'effacent pas dans le temps et peuvent supporter des conditions très dures sans perdre de données. Par exemple, elles peuvent résister à des radiations extrêmes , voire à une EMP, sans perdre de données. C'est pour cette raison qu'elles ont beaucoup été utilisées dans des applications aérospatiales, dans l'industrie, voire dans les applications militaires. Elles étaient encore utilisées dans ces applications bien après l'apparition des premières mémoires à semi-conducteurs. Par contre, ces mémoires étaient très sensibles à la température. Les tensions à envoyer aux tores devaient avoir une valeur bien précise, qui dépend énormément de la température ambiante. Sur les premières mémoires à tore de ferrite, les circuits de contrôle de la mémoire contenaient un senseur de température et ajustaient les tensions appliquées en fonction des mesures. Une autre solution consistait à placer la mémoire dans une petite boite dont la température était maintenue stable. Généralement, la boite était chauffée au-dessus de la température ambiante, car maintenir une température constante est facile quand celle-ci est plus élevée que la normale. Chauffer une petite chambre est plus simple que de la refroidir, surtout pour une petite boite. Autant une simple résistance permet de chauffer la boite, autant utiliser un réfrigérateur pour une mémoire de ce type était clairement une mauvaise solution. Le défaut principal de ces mémoires est que leur processus de fabrication est difficile à industrialiser. La fabrication de ces mémoires s'est surtout fait de main d'homme, sans machines ou du moins avec peu d'outils. Le fait que ces mémoires ne puisse pas facilement être fabriquées par des machines fait que ces mémoires sont difficiles à miniaturiser : la miniaturisation ne va pas aussi loin que pour les mémoires à semi-conducteurs et on peut tout au plus stocker quelques centaines de bits sur une puce, voire quelques milliers. La capacité de telles mémoire est généralement assez faible. Par contre, leurs performances étaient assez honorables. On estime que les premières mémoires de ce type avaient un temps d'accès mémoire d'environ 6 µs, ce qui fait une fréquence d'environ 166.7 kilohertz. Le temps d'accès est ensuite descendu à 0.6 µs durant les années 70, ce qui faisait une fréquence proche du mégahertz. [[File:Ferrite core memory.jpg|centre|vignette|upright=1.5|Mémoire à tore Ferrite miniaturisée. La puce fait 10 centimètres de coté et contient 64 mots de 64 bits, soit 4 kikioctets.]] ==Les mémoires à ligne de délai== Les '''mémoires à ligne de délai''' sont des mémoires volatiles mécaniques, basées sur des ondes sonores ! Celles-ci ont été inventées suite à des technologies liées aux radars, dans les laboratoires militaires. Ces mémoires sont des mémoires séquentielles, qui ont une capacité extrêmement faible (quelques centaines de bits). Il en existe diverses versions, la première étant basée sur des tubes de mercure, les suivantes étant basées sur des tubes de cuivre ou d'autre matériaux magnétiques. ===L'intérieur d'une mémoire à ligne de délai=== Ces mémoires sont basées sur un tube de matière, dans lequel se propage une onde sonore : celui-ci sert de support de mémorisation. Un bit est codé par l'absence ou la présence d'une onde sonore dans le tube de matière. Au bout de ce tube, on trouve un microphone et un haut-parleur. Le haut-parleur génère une onde sonore d'un côté du tube, onde qui est reçue de l'autre côté du tube par le microphone. De plus, le haut-parleur et le microphone sont reliés entre eux : le signal capté sur le microphone est envoyé sur le haut-parleur d'entrée. Ce faisant, l'onde sonore circule en boucle dans le circuit : elle est rafraichie sans cesse, à chaque passage. [[File:Delay line memory fr.svg|centre|vignette|upright=2.0|Mémoire à ligne de délai.]] Divers circuits sont présents entre le microphone et le haut-parleur. On trouve notamment des amplificateurs, histoire que les ondes sonores captées ne s'amenuisent pas à force de reparcourir le tube. [[File:SEACComputer 010.jpg|centre|vignette|upright=2.0|Mémoire à tube de mercure.]] ===La capacité des mémoires à ligne de délai=== Il existe naturellement un petit délai de transmission entre le microphone et le haut-parleur, ainsi qu'un autre délai de propagation dans le tube. Ces délais limitent la capacité de la mémoire, qui dépend du nombre d'ondes sonores qui peuvent parcourir le tube. Chaque bit est codée exactement par une impulsion sonore, qui a une forme et une durée très précise, qui dépend de la qualité du circuit (microphone, haut-parleur, et autres) : notons ce temps <math>\Tau</math>. La capacité totale est, par définition, égale au nombre d'impulsions qui se trouvent en même temps dans le tube de matière (les unes à la suite des autres). Pour la calculer, on peut diviser le temps que met une impulsion à se propager dans le tube, par la durée d'une impulsion. ===Les différents types de mémoires à lignes de délai=== Les premières mémoires de ce type étaient fabriquées avec des tubes de mercure : ce sont des '''lignes à délai de mercure'''. [[File:Mercury memory.jpg|centre|vignette|SEAC Computer, avec une mémoire à ligne de Mercure.]] Mais les inconvénients du mercure (toxicité, notamment) ont mené au remplacement du mercure par des tubes de matériaux conducteurs (des fils électriques, dit autrement) : ce sont des '''lignes de délai à torsion de fil'''. [[File:Torsion wire delay line.jpg|centre|vignette|Exemple de ligne de délai à torsion de fil.]] ==Les tubes Williams et Selectron== Les '''tubes ''Williams''''' et '''Selectron''' sont basés sur un écran CRT modifié. Il s'agissait de mémoires de type mémoires vives volatiles qui devaient être rafraichies régulièrement. En clair, ce sont l'ancêtre des mémoires DRAM ! Les ''tubes Williams'' étaient utilisés sur les tout premiers ordinateurs, au tout début de l'histoire de l'informatique, dans les années 50, à une époque où les ordinateurs étaient des monstres qui occupaient une pièce entière et étaient plus proches de petites usines à calcul qu'autre chose. Une technologie alternative basée sur un principe simialire est le ''Tube Selectron''. D'une capacité de 256 bits, il n'a été utilisé que sur un seul ordinateur : le JOHNNIAC de la RAND Corporation. Ils ont tous deux était rapidement remplacé par les mémoires à ligne de délai, plus simples et moins chères. [[File:Williams-tube.jpg|centre|vignette|upright=2|Williams-tube]] ===Les écrans CRT (''Cathode Ray Tube'')=== Tubes Williams et Selectron se basent sur la même technologie : celle des écrans CRT. Un écran CRT est composé de plusieurs composants, qui marchent de concert : un canon à électron, des bobines de contrôle et la surface de l'écran proprement dite. Le canon à électron émet un faisceau d'électron concentré, qui touche la surface de l'écran. Cette dernière, du moins derrière la vitre transparente, est d'une composition chimique particulière et est notamment riche en phosphore. Elle est souvent appelée ''surface phosphorescente''. Quand elle est touchée par le faisceau d’électron, le phosphore s'illumine pendant quelques millisecondes. Les bobines visent à détourner le faisceau d'électron de manière à ce qu'il balaye tout l'écran de gauche à droite et de haut en bas. [[File:Cathode ray tube fr.svg|centre|vignette|upright=2|Cathode ray tube.]] La surface de l'écran est découpée en pixels, et l'intensité du canon varie pour chaque pixel lorsque le faisceau passe sur ce pixelde l'écran. En commandant l'intensité du canon d'électron, on arrive à afficher des images en noir et blanc ainsi. Un canon intense pendant x millisecondes donnera un point blanc sur l'écran, là où tombe de faisceau. un canon éteint donnera un point noir à l'écran. Il est possible de gérer la couleurs avec des écrans CRT plus complexes, mais ce n'est pas le sujet et nous n'en avons pas besoin pour les explications qui vont suivre. ====La physique de la surface phosphorescente : émission secondaire et puits de potentiels==== Un point important est que la physique de la surface phosphorescente n'est pas intuitive et peu donner lieu à des phénomènes assez importants pour ce qui va suivre. Deux d'entre eu vont nous intéresser. Le premier est que les électrons émis par le canaux à électrons frappent la surface phosphorescente, l'illuminent, mais qu'il arrive que des électrons soient piégés dans la surface, à l'endroit de l'impact. En conséquence, une petite charge électrique s'accumule progressivement à chaque passage du faisceau, dans chaque pixel. Les électrons ne restent pas en place de manière permanente, ils finissent par s'échapper après un certain temps, ce qui fait que la charge finit par s'atténuer, mais elle peut durer quelques secondes sur les CRT conçus pour exploiter cet effet au mieux. Le second phénomène est l''''émission secondaire'''. Quand l'énergie du faisceau à électron est trop forte, les électrons naturellement présents dans les atomes du matériau phosphorescent sont dégagés. Les électrons éjectés deviennent alors des électrons libres qui vont allumer les zones alentours, ce qui perturbe l'affichage. Et cela arrive lors que la zone frappée par le faisceau a perdu des électrons et ne s'allume plus. Le résultat est que si une image était affichée sur l'écran auparavant, utiliser un faisceau trop fort l'efface totalement via émission secondaire. Il s'agit là d'un défaut à éviter sur les écrans d'affichage, mais c'est ce phénomène qui est utilisé sur les mémoires à tubes de stockage. ====Les CRT rémanents==== Il existe des écrans CRT conçus pour afficher des images sur une longue durée de temps, et pas seulement pour un 50ème ou 60ème de seconde. Ils sont appelés des '''écrans rémanents''' ou encore '''''storage tubes''''', ou tubes de stockage. Avec eux, l'image affichée s'efface progressivement et lentement, mais reste visible durant quelques secondes. Pour cela, les écran de stockage sont fabriqués en utilisant un matériau phosphorescent spécial, différent de celui des autres CRT, mais le reste du CRT fonctionne de la même manière. La rémanence est liée au premier phénomène mentionné plus haut, à savoir la capture d'électrons par la surface, mais ce phénoméne est maximisé par l'usage du matériau adéquat. Cette rémanence de quelques secondes fait que l'image a besoin d'être rafraichie moins souvent, comparée à un écran CRT normal. Et les mémoires Selectron et de Williams sont basées sur de tels tubes de stockage. La rémanence de l'image a de nombreuses applications et est utile quand on n'a pas besoin d'une réactivité importante. Elle était utile dans les radars, dans certains oscilloscopes qui demandent de capturer des évènements très brefs, etc. Quelques écrans d'ordinateur ont tenté d'utiliser ce système, notamment les écrans de la marque Textronix. Ils portent le nom de '''''Direct-view bistable storage tube'''''. L'idée est d'utiliser un écran CRT rémanent pour afficher une image pour éviter de rafraichir l'écran souvent. Mais pour quel l'écran soit réactif et éviter des artefacts graphiques liés à la rémanence, on est obligé d'effacer l'écran avant d'afficher une nouvelle image. Et l'effacement se fait grâce à l'émission secondaire. Pour cela, de tels écrans contenaient deu faisceaux : un faisceau normal pour afficher une image, un autre faisceau très puissant qui déclenche une émission secondaire pour effacer l'écran. ===Les tubes Williams=== [[File:SWAC 003.jpg|vignette|Image affichée par un tube Williams en fonctionnement, sur l'ordinateur SWAC.]] L'idée derrière les tubes tubes Williams et Selectron est de mémoriser les données sous la forme d'images à l'écran. Un bit à 1 correspond à un pixel allumé/lumineux, un bit à 0 à un pixel éteint/noir. Les écrans de l'époque ne géraient pas la couleur, aussi seul le noir et blanc était disponible (avec les niveaux de gris), ce qui est parfait pour un stockage en binaire. L'image affichée par un écran CRT est affichée ligne par ligne, avec un petit temps de pause entre l'affichage de deux lignes pour repositionner le canon à électron sur le début de la ligne suivante. Par simplicité, sur les tubes Williams, chaque ligne correspond à un mot mémoire, une case mémoire. La taille d'un mot mémoire et le nombre d'adresse dépend donc de la résolution utilisée. Un tube Williams est composé d'un tube CRT rémanent et d'une plaque de métal placée devant l'écran, et de circuits électroniques annexes. La plaque de métal est collée à l'écran, ce qui fait qu'on ne peut pas voir l'écran proprement dit. Elle sert uniquement lors des lectures et pas pour les écritures. Lors d'une lecture, on mesure la tension sur la plaque, qui dépendra du bit stocké au moment de la lecture. La lecture se fait bit par bit, un par un. Elle est reliée à un circuit amplificateur de tension, qui amplifie la tension mesurée par la plaque. On trouve aussi des circuits pour le contrôle de l'écran CRT, à savoir des registres X et Y pour commander les bobines de défléction, de quoi générer un signal d'horloge, et des circuits électroniques pour gérer les lectures/écritures. [[File:WilliamsTubeFigure1.tiff|centre|vignette|upright=2|WilliamsTubeFigure1]] L'écriture et l’effacement de l'image est ce qu'il y a de plus facile : écrire une image utilise un faisceau d’électrons normal qu'on allume ou éteint convenablement lors du balayage de l'écran, l'effacer demande de faire la même chose en utilisant un faisceau très puissant. Un faisceau normal allume le phosphore et le charge pendant un certain temps, alors que l'émission secondaire efface ce qui a été enregistré sur le phosphore. Pour lire un bit, on envoie un faisceau d'électron sur sa position sur l'écran, dont l'intensité est situé juste en-dessous du seuil pour l'émission secondaire. Si le bit stocké est à 0, l'intensité ne sera pas suffisante pour générer une émission secondaire. Mais si cil stocke un 1, la charge électrique stockée sur la surface phosphorescente va s'additionner à l’intensité du faisceau et déclencher une émission secondaire. L’émission secondaire a déclencher une augmentation local de la tension électrique, que la plaque de métal va capter. Un amplifieur amplifie la tension mesurée sur la plaque, pour en faire une tension capable de coder un 0 ou un 1. Vous remarquerez que la lecture est destructrice, ce qui fait que toute lecture de l'écran est suivie par une écriture pour compenser, comme sur les DRAM. [[File:Williams tube timing.jpg|centre|vignette|upright=2|Williams tube timing]] Passons maintenant au rafraichissement mémoire. Il faut rafraichir l'écran pour une raison simple : l'image affichée par l'écran s'efface au bout de quelques millisecondes, quelques secondes, tout dépend du type d'écran utilisé. Le rafraichissement se fait en effectuant une lecture suivie d'une écriture : on récupère le contenu de la mémoire/tube, avant de le réécrire. Autour de la plaque de métal et du tube CRT, on trouve divers circuits qui gèrent les lectures et écritures. Les lectures et écritures se font bit par bit, on peut masquer certains bits lors des écritures, autoriser ou interdire les lectures/écritures durant un temps, etc. [[File:SEACComputer 004.jpg|centre|vignette|upright=2|Fonctionnement d'un tube Williams, avec les circuits associés]] <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> m4cmxboi5vcbwxi5ll0ji9nxw45ejau 744181 744180 2025-06-05T17:57:53Z Mewtow 31375 /* Les tambours magnétiques étaient des mémoires primaires */ 744181 wikitext text/x-wiki Au tout début de l'informatique, les mémoires étaient totalement différentes d'aujourd'hui. Il n'y avait pas de mémoire ROM, de mémoire RAM, ou quoique ce soit d'autres. Les premières mémoires n'étaient pas électroniques, la technologie n'étant pas assez avancée pour cela. On parle d'un temps où les transistors n'existaient pas et où l'informatique était en pleine gestation. Pourtant, les mémoires existaient déjà. L'électronique analogique avait déjà des supports de stockage : les lecteurs audio utilisaient des cassettes audio à bande magnétiques, les lecteurs vidéo utilisaient des cassettes VHS elles aussi basées sur des bandes magnétiques, et j'en passe. Une partie de ces supports de stockage ont été réutilisés, puis adaptés pour les ordinateurs de l'époque. En conséquence, les premières mémoires informatiques étaient des mémoires magnétiques, bien plus rudimentaires que les disques durs et les disquettes : mémoires à tores de ferrite, bandes magnétiques, et bien d'autres (cassettes audio, notamment). D'autres mémoires historiques étaient des mémoires mécaniques, qui stockaient leurs informations sous la forme de trous dans une carte en plastique, d'ondes sonores, etc. Ces mémoires, aujourd'hui totalement obsolètes, ont pourtant eu leur heure de gloire, certaines étant plus utilisées que les mémoires magnétiques ou électroniques de leur époque. Ce chapitre se propose de rendre hommage à ces mémoires historiques. Toutes les mémoires que nous allons aborder sont aujourd'hui obsolètes et la plupart ne sont même plus produites du tout. On peut encore en trouver dans des musées, mais leur utilisation réelle est réduite à peau de chagrin. ==Les cartes et rubans perforés== Les toutes premières mémoires informatiques étaient des mémoires mécaniques. Les mémoires mécaniques les plus connues étaient basées sur du papier : je veux parler des '''cartes et rubans perforés'''. Il s'agit de cartes ou de rubans de papier, parfois de carton ou de plastiques. Les données sont stockées sous la forme de trous dans le ruban ou la carte : un trou code un 1, tandis que l'absence d'un trou code un 0. [[File:2punchCards.jpg|centre|vignette|Carte perforée.]] ==Les bandes magnétiques== [[File:Digital pdp8-e.jpg|vignette|Ordinateur Digital PDP-8, avec ses bandes magnétiques visibles.]] De vieux ordinateurs utilisaient des cassettes à bande magnétique, les mêmes qui étaient utilisées comme cassettes audio il y a de cela quelques décennies. C'était le cas de vieux ordinateurs personnels, comme les Amstrad CPC, les ZX Spectrum, ou les ordinateurs Commodore. [[File:Amstrad CPC 464 computer at Play Expo 2013.JPG|centre|vignette|Ordinateur personnel Amstrad CPC 464.]] D'autres ordinateurs de la même époque utilisaient des supports de stockage similaires aux cassettes audio, mais sans le plastique extérieur. Des bandes magnétiques étaient enroulées dans un cylindre plastique, et étaient déroulées par un système de déroulement. ==Les tambours magnétiques== [[File:ERA Magnetic Drum, US, c. 1951 - Computer History Museum - Mountain View, California.jpg|vignette|ERA Magnetic Drum, US, c. 1951 - Computer History Museum - Mountain View, California]] Les '''tambours magnétiques''' sont les ancêtres du disque durs, les deux ayant un fonctionnement assez similaire. La différence principale est que les plateaux sont remplacés par un tube cylindrique, dont la surface est couverte d'un matériau magnétique. L'organisation en pistes est toujours présente, chaque piste étant une ligne horizontale sur le tube central. Par contre, il n'y a pas de tête de lecture/écriture qui se déplace de piste en piste. Les têtes de lecture/écriture sont immobiles, mais il y en a une par piste pour compenser. Le temps de latence d'un tel disque dépend donc uniquement de la vitesse de rotation et de la densité surfacique. ===Les tambours magnétiques étaient des mémoires primaires=== Fait surprenant, les tambours magnétiques étaient utilisés comme mémoire primaire, c'est à dire qu'elles avaient la même fonction que la mémoire RAM des PC actuels, malgré leur caractère non-volatile ! Les tambours magnétiques étaient aussi utilisées comme mémoire de masse, mais c'était une utilisation moins fréquente. De nombreux ordinateurs de l'époque exécutaient des programmes directement depuis le tambour magnétique. Les instructions étaient mémorisées sur le tambour magnétique, étaient copiées dans un registre d'instruction, puis exécutées. Pour garder des performances correctes, la répartition des instructions dans les secteurs devait être optimisée. Les programmeurs ayant travaillé, par exemple sur l'IBM 650, devaient prendre en compte la manière dont les instructions étaient placées dans et entre les secteurs pour éviter des pertes de performance. L'ordinateur Bull Gamma 3 intégrait une sorte de cache d'instruction pour accélérer l'exécution des programmes depuis le tambour magnétique. Pour l'expliquer avec des termes modernes, le processeur intégrait un ''local store'' dédié aux instructions. Les instructions étaient exécutées depuis ce ''local store'', pas depuis le tambour magnétique. Les échanges entre le ''local store'' et le tambour magnétique se faisaient par groupes de 48 instructions. Le ''local store'' était composé de 8 banques, chacune contenant un groupe de 48 instructions complet. Dans le détail, le Bull Gamma 3 intégrait en réalité 8 ''local store'', appelés des ''Circulating Memories'', chacun pouvant mémoriser un groupe de 48 instructions. Pour exécuter une instruction, le groupe de 48 instructions complet était copié dans une ''Circulating Memory'', puis l'instruction voulue était copiée dans le registre d'instruction. Les ''Circulating Memories'' étaient implémentées avec des mémoires magnéto-résistives à ligne de mercure, qu'on détaillera dans la suite de ce chapitre. ===L'adressage sur un tambour magnétique=== Les tambours magnétiques avaient une méthode d'adressage différente selon qu'ils étaient utilisées comme mémoire de masse ou primaire. Les tambours utilisées comme mémoire primaire avaient une adresse par mot mémoire, alors que celles utilisées comme mémoire de masse avaient une adresse par secteur ou par piste. La méthode d'adressage variait suivant le tambour. * Sur certains tambours, chaque piste avait sa propre adresse mémoire. Les pistes étaient de taille variable suivant la marque du tambour magnétique utilisé, mais chacune avait sa propre adresse. * Sur d'autres, chaque piste était découpée en secteurs de taille fixe, comme sur les disques durs, et chaque secteur était adressé en précisant le numéro de piste et un numéro de secteur (similaire à l'adressage CHS des disques durs, en enlevant les plateaux). * Sur d'autres, les secteurs avaient une taille variable, l'adressage se faisait en indiquant le numéro de la piste et la position du secteur dans la piste. * D'autres mémoires utilisaient des systèmes d'adressages différents. ==Les mémoires à tore de ferrite== Les premières mémoires de masse sont sans conteste les '''mémoires à tores de ferrites'''. Ce sont des mémoires magnétiques, un peu comme les disques durs, même si les différences sont nombreuses. Elles sont donc naturellement non-volatiles. Elles sont formées d'une matrice de tores fabriqués dans un matériau magnétique (ferromagnétique pour être précis), le plus souvent de la ferrite. Ces tores peuvent être magnétisés dans deux sens différents, ce qui leur permet de coder un bit. [[File:KL CoreMemory Macro.jpg|centre|vignette|Mémoire à tores de ferrite réelle (avec les fils).]] ===Le fonctionnement d'une mémoire à tore de ferrite=== L'ensemble formait une sorte de tableau où chaque tore a deux positions : une position X et une autre position Y. Deux fils servent pour l'adressage : le fil Y traverse tous les tores d'une ligne, alors que le fil X traverse tous les tores placés sur la même colonne. Quand une tension est envoyée sur un fil Y et un fil X, le tore à l'intersection des deux fils est activé : il peut alors être lu ou écrit. Plus précisément, chaque fil est parcouru par une tension légèrement supérieure à la moitié de la tension nécessaire pour aimanter le tore : ainsi, la somme des deux tensions est supérieure à la tension d'aimantation, mais seulement à l'intersection des deux fils, sur le tore à aimanter. Selon la tension envoyée (plus précisément, son signe), le tore sera mis à 0 ou à 1. [[File:Coincident-current magnetic core.svg|centre|vignette|Schéma de la matrice de tores (avec les fils).]] Pour lire ou écrire un bit dans un tore (en changer l'aimantation), il faut que celui-ci soit soumis à un champ magnétique supérieur à une valeur déterminée. pour cela, chaque tore est parcouru par quatre fils : le fil X et Y servent pour l'adressage, comme dit plus haut, un fil S (''Sense'') pour les lectures, et un fil Z pour les écritures. En faisant passer un courant ou une tension dans ces fils, un champ magnétique se forme autour d'eux, ce qui agit sur les tores de ferrites ce qui permet de les aimanter (écriture) ou de lire leur contenu. [[File:Single coincident-current magnetic core.svg|centre|vignette|Un tore de ferrite.]] La lecture s'effectue via le fil nommé ''Sense''. Toute lecture est destructrice : le bit stocké dans le tore est effacé après chaque lecture. En effet, chaque lecture commence par mettre à zéro le bit à lire. Cette mise à zéro va ou non, faire changer le champ magnétique dans le fil ''Sense'', entrainant l'apparition d'un courant et d'une tension. Suite à cette mise à zéro, la mémoire regarde ce qui se passe sur ce fil. Si le bit était déjà à zéro avant la lecture, aucun champ magnétique ne sera créé : il ne se passe rien sur le fil ''Sense''. Mais si ce bit était à 1, le tore va changer de polarité, entrainant l'apparition d'une tension sur ce fil, durant un temps très bref (le temps de changement de polarité du tore). La lecture s'effectue donc via le fil ''Sense'', suivant ce qui s'y passe lors d'une mise à zéro d'un bit. L'écriture s'effectue d'une manière différente, quoique similaire, en utilisant le fil ''Z''. Lors d'une écriture d'un tore, les fils X et Y qui correspondent sont alimentés en tension, de telle manière qu'un 1 soit écrit dans le tore. Pour écrire un 1, cela suffit largement. Mais pour écrire un zéro, il faut que quelque chose annule cette écriture, en compensant le champ magnétique créé par ces deux fils. Pour cela, on fait passer un courant dans le fil ''Inhibit'', afin de créer un champ magnétique contraire dans le tore. Cela annule l'écriture du 1 en inhibant le champ crée par les fils X et Y. La plupart des mémoires de ce type utilisaient deux fils ''Sense'' et ''Inhibit'' séparés. Mais vu que le fil ''Inhibit'' et ''Sense'' ne sont jamais utilisés en même temps, certaines mémoires à tore ont fusionné ces deux fils en un seul. ===Une mémoire très fiable=== Les mémoires à tore de ferrite sont des mémoires non-volatiles très fiables. Elles ne s'effacent pas dans le temps et peuvent supporter des conditions très dures sans perdre de données. Par exemple, elles peuvent résister à des radiations extrêmes , voire à une EMP, sans perdre de données. C'est pour cette raison qu'elles ont beaucoup été utilisées dans des applications aérospatiales, dans l'industrie, voire dans les applications militaires. Elles étaient encore utilisées dans ces applications bien après l'apparition des premières mémoires à semi-conducteurs. Par contre, ces mémoires étaient très sensibles à la température. Les tensions à envoyer aux tores devaient avoir une valeur bien précise, qui dépend énormément de la température ambiante. Sur les premières mémoires à tore de ferrite, les circuits de contrôle de la mémoire contenaient un senseur de température et ajustaient les tensions appliquées en fonction des mesures. Une autre solution consistait à placer la mémoire dans une petite boite dont la température était maintenue stable. Généralement, la boite était chauffée au-dessus de la température ambiante, car maintenir une température constante est facile quand celle-ci est plus élevée que la normale. Chauffer une petite chambre est plus simple que de la refroidir, surtout pour une petite boite. Autant une simple résistance permet de chauffer la boite, autant utiliser un réfrigérateur pour une mémoire de ce type était clairement une mauvaise solution. Le défaut principal de ces mémoires est que leur processus de fabrication est difficile à industrialiser. La fabrication de ces mémoires s'est surtout fait de main d'homme, sans machines ou du moins avec peu d'outils. Le fait que ces mémoires ne puisse pas facilement être fabriquées par des machines fait que ces mémoires sont difficiles à miniaturiser : la miniaturisation ne va pas aussi loin que pour les mémoires à semi-conducteurs et on peut tout au plus stocker quelques centaines de bits sur une puce, voire quelques milliers. La capacité de telles mémoire est généralement assez faible. Par contre, leurs performances étaient assez honorables. On estime que les premières mémoires de ce type avaient un temps d'accès mémoire d'environ 6 µs, ce qui fait une fréquence d'environ 166.7 kilohertz. Le temps d'accès est ensuite descendu à 0.6 µs durant les années 70, ce qui faisait une fréquence proche du mégahertz. [[File:Ferrite core memory.jpg|centre|vignette|upright=1.5|Mémoire à tore Ferrite miniaturisée. La puce fait 10 centimètres de coté et contient 64 mots de 64 bits, soit 4 kikioctets.]] ==Les mémoires à ligne de délai== Les '''mémoires à ligne de délai''' sont des mémoires volatiles mécaniques, basées sur des ondes sonores ! Celles-ci ont été inventées suite à des technologies liées aux radars, dans les laboratoires militaires. Ces mémoires sont des mémoires séquentielles, qui ont une capacité extrêmement faible (quelques centaines de bits). Il en existe diverses versions, la première étant basée sur des tubes de mercure, les suivantes étant basées sur des tubes de cuivre ou d'autre matériaux magnétiques. ===L'intérieur d'une mémoire à ligne de délai=== Ces mémoires sont basées sur un tube de matière, dans lequel se propage une onde sonore : celui-ci sert de support de mémorisation. Un bit est codé par l'absence ou la présence d'une onde sonore dans le tube de matière. Au bout de ce tube, on trouve un microphone et un haut-parleur. Le haut-parleur génère une onde sonore d'un côté du tube, onde qui est reçue de l'autre côté du tube par le microphone. De plus, le haut-parleur et le microphone sont reliés entre eux : le signal capté sur le microphone est envoyé sur le haut-parleur d'entrée. Ce faisant, l'onde sonore circule en boucle dans le circuit : elle est rafraichie sans cesse, à chaque passage. [[File:Delay line memory fr.svg|centre|vignette|upright=2.0|Mémoire à ligne de délai.]] Divers circuits sont présents entre le microphone et le haut-parleur. On trouve notamment des amplificateurs, histoire que les ondes sonores captées ne s'amenuisent pas à force de reparcourir le tube. [[File:SEACComputer 010.jpg|centre|vignette|upright=2.0|Mémoire à tube de mercure.]] ===La capacité des mémoires à ligne de délai=== Il existe naturellement un petit délai de transmission entre le microphone et le haut-parleur, ainsi qu'un autre délai de propagation dans le tube. Ces délais limitent la capacité de la mémoire, qui dépend du nombre d'ondes sonores qui peuvent parcourir le tube. Chaque bit est codée exactement par une impulsion sonore, qui a une forme et une durée très précise, qui dépend de la qualité du circuit (microphone, haut-parleur, et autres) : notons ce temps <math>\Tau</math>. La capacité totale est, par définition, égale au nombre d'impulsions qui se trouvent en même temps dans le tube de matière (les unes à la suite des autres). Pour la calculer, on peut diviser le temps que met une impulsion à se propager dans le tube, par la durée d'une impulsion. ===Les différents types de mémoires à lignes de délai=== Les premières mémoires de ce type étaient fabriquées avec des tubes de mercure : ce sont des '''lignes à délai de mercure'''. [[File:Mercury memory.jpg|centre|vignette|SEAC Computer, avec une mémoire à ligne de Mercure.]] Mais les inconvénients du mercure (toxicité, notamment) ont mené au remplacement du mercure par des tubes de matériaux conducteurs (des fils électriques, dit autrement) : ce sont des '''lignes de délai à torsion de fil'''. [[File:Torsion wire delay line.jpg|centre|vignette|Exemple de ligne de délai à torsion de fil.]] ==Les tubes Williams et Selectron== Les '''tubes ''Williams''''' et '''Selectron''' sont basés sur un écran CRT modifié. Il s'agissait de mémoires de type mémoires vives volatiles qui devaient être rafraichies régulièrement. En clair, ce sont l'ancêtre des mémoires DRAM ! Les ''tubes Williams'' étaient utilisés sur les tout premiers ordinateurs, au tout début de l'histoire de l'informatique, dans les années 50, à une époque où les ordinateurs étaient des monstres qui occupaient une pièce entière et étaient plus proches de petites usines à calcul qu'autre chose. Une technologie alternative basée sur un principe simialire est le ''Tube Selectron''. D'une capacité de 256 bits, il n'a été utilisé que sur un seul ordinateur : le JOHNNIAC de la RAND Corporation. Ils ont tous deux était rapidement remplacé par les mémoires à ligne de délai, plus simples et moins chères. [[File:Williams-tube.jpg|centre|vignette|upright=2|Williams-tube]] ===Les écrans CRT (''Cathode Ray Tube'')=== Tubes Williams et Selectron se basent sur la même technologie : celle des écrans CRT. Un écran CRT est composé de plusieurs composants, qui marchent de concert : un canon à électron, des bobines de contrôle et la surface de l'écran proprement dite. Le canon à électron émet un faisceau d'électron concentré, qui touche la surface de l'écran. Cette dernière, du moins derrière la vitre transparente, est d'une composition chimique particulière et est notamment riche en phosphore. Elle est souvent appelée ''surface phosphorescente''. Quand elle est touchée par le faisceau d’électron, le phosphore s'illumine pendant quelques millisecondes. Les bobines visent à détourner le faisceau d'électron de manière à ce qu'il balaye tout l'écran de gauche à droite et de haut en bas. [[File:Cathode ray tube fr.svg|centre|vignette|upright=2|Cathode ray tube.]] La surface de l'écran est découpée en pixels, et l'intensité du canon varie pour chaque pixel lorsque le faisceau passe sur ce pixelde l'écran. En commandant l'intensité du canon d'électron, on arrive à afficher des images en noir et blanc ainsi. Un canon intense pendant x millisecondes donnera un point blanc sur l'écran, là où tombe de faisceau. un canon éteint donnera un point noir à l'écran. Il est possible de gérer la couleurs avec des écrans CRT plus complexes, mais ce n'est pas le sujet et nous n'en avons pas besoin pour les explications qui vont suivre. ====La physique de la surface phosphorescente : émission secondaire et puits de potentiels==== Un point important est que la physique de la surface phosphorescente n'est pas intuitive et peu donner lieu à des phénomènes assez importants pour ce qui va suivre. Deux d'entre eu vont nous intéresser. Le premier est que les électrons émis par le canaux à électrons frappent la surface phosphorescente, l'illuminent, mais qu'il arrive que des électrons soient piégés dans la surface, à l'endroit de l'impact. En conséquence, une petite charge électrique s'accumule progressivement à chaque passage du faisceau, dans chaque pixel. Les électrons ne restent pas en place de manière permanente, ils finissent par s'échapper après un certain temps, ce qui fait que la charge finit par s'atténuer, mais elle peut durer quelques secondes sur les CRT conçus pour exploiter cet effet au mieux. Le second phénomène est l''''émission secondaire'''. Quand l'énergie du faisceau à électron est trop forte, les électrons naturellement présents dans les atomes du matériau phosphorescent sont dégagés. Les électrons éjectés deviennent alors des électrons libres qui vont allumer les zones alentours, ce qui perturbe l'affichage. Et cela arrive lors que la zone frappée par le faisceau a perdu des électrons et ne s'allume plus. Le résultat est que si une image était affichée sur l'écran auparavant, utiliser un faisceau trop fort l'efface totalement via émission secondaire. Il s'agit là d'un défaut à éviter sur les écrans d'affichage, mais c'est ce phénomène qui est utilisé sur les mémoires à tubes de stockage. ====Les CRT rémanents==== Il existe des écrans CRT conçus pour afficher des images sur une longue durée de temps, et pas seulement pour un 50ème ou 60ème de seconde. Ils sont appelés des '''écrans rémanents''' ou encore '''''storage tubes''''', ou tubes de stockage. Avec eux, l'image affichée s'efface progressivement et lentement, mais reste visible durant quelques secondes. Pour cela, les écran de stockage sont fabriqués en utilisant un matériau phosphorescent spécial, différent de celui des autres CRT, mais le reste du CRT fonctionne de la même manière. La rémanence est liée au premier phénomène mentionné plus haut, à savoir la capture d'électrons par la surface, mais ce phénoméne est maximisé par l'usage du matériau adéquat. Cette rémanence de quelques secondes fait que l'image a besoin d'être rafraichie moins souvent, comparée à un écran CRT normal. Et les mémoires Selectron et de Williams sont basées sur de tels tubes de stockage. La rémanence de l'image a de nombreuses applications et est utile quand on n'a pas besoin d'une réactivité importante. Elle était utile dans les radars, dans certains oscilloscopes qui demandent de capturer des évènements très brefs, etc. Quelques écrans d'ordinateur ont tenté d'utiliser ce système, notamment les écrans de la marque Textronix. Ils portent le nom de '''''Direct-view bistable storage tube'''''. L'idée est d'utiliser un écran CRT rémanent pour afficher une image pour éviter de rafraichir l'écran souvent. Mais pour quel l'écran soit réactif et éviter des artefacts graphiques liés à la rémanence, on est obligé d'effacer l'écran avant d'afficher une nouvelle image. Et l'effacement se fait grâce à l'émission secondaire. Pour cela, de tels écrans contenaient deu faisceaux : un faisceau normal pour afficher une image, un autre faisceau très puissant qui déclenche une émission secondaire pour effacer l'écran. ===Les tubes Williams=== [[File:SWAC 003.jpg|vignette|Image affichée par un tube Williams en fonctionnement, sur l'ordinateur SWAC.]] L'idée derrière les tubes tubes Williams et Selectron est de mémoriser les données sous la forme d'images à l'écran. Un bit à 1 correspond à un pixel allumé/lumineux, un bit à 0 à un pixel éteint/noir. Les écrans de l'époque ne géraient pas la couleur, aussi seul le noir et blanc était disponible (avec les niveaux de gris), ce qui est parfait pour un stockage en binaire. L'image affichée par un écran CRT est affichée ligne par ligne, avec un petit temps de pause entre l'affichage de deux lignes pour repositionner le canon à électron sur le début de la ligne suivante. Par simplicité, sur les tubes Williams, chaque ligne correspond à un mot mémoire, une case mémoire. La taille d'un mot mémoire et le nombre d'adresse dépend donc de la résolution utilisée. Un tube Williams est composé d'un tube CRT rémanent et d'une plaque de métal placée devant l'écran, et de circuits électroniques annexes. La plaque de métal est collée à l'écran, ce qui fait qu'on ne peut pas voir l'écran proprement dit. Elle sert uniquement lors des lectures et pas pour les écritures. Lors d'une lecture, on mesure la tension sur la plaque, qui dépendra du bit stocké au moment de la lecture. La lecture se fait bit par bit, un par un. Elle est reliée à un circuit amplificateur de tension, qui amplifie la tension mesurée par la plaque. On trouve aussi des circuits pour le contrôle de l'écran CRT, à savoir des registres X et Y pour commander les bobines de défléction, de quoi générer un signal d'horloge, et des circuits électroniques pour gérer les lectures/écritures. [[File:WilliamsTubeFigure1.tiff|centre|vignette|upright=2|WilliamsTubeFigure1]] L'écriture et l’effacement de l'image est ce qu'il y a de plus facile : écrire une image utilise un faisceau d’électrons normal qu'on allume ou éteint convenablement lors du balayage de l'écran, l'effacer demande de faire la même chose en utilisant un faisceau très puissant. Un faisceau normal allume le phosphore et le charge pendant un certain temps, alors que l'émission secondaire efface ce qui a été enregistré sur le phosphore. Pour lire un bit, on envoie un faisceau d'électron sur sa position sur l'écran, dont l'intensité est situé juste en-dessous du seuil pour l'émission secondaire. Si le bit stocké est à 0, l'intensité ne sera pas suffisante pour générer une émission secondaire. Mais si cil stocke un 1, la charge électrique stockée sur la surface phosphorescente va s'additionner à l’intensité du faisceau et déclencher une émission secondaire. L’émission secondaire a déclencher une augmentation local de la tension électrique, que la plaque de métal va capter. Un amplifieur amplifie la tension mesurée sur la plaque, pour en faire une tension capable de coder un 0 ou un 1. Vous remarquerez que la lecture est destructrice, ce qui fait que toute lecture de l'écran est suivie par une écriture pour compenser, comme sur les DRAM. [[File:Williams tube timing.jpg|centre|vignette|upright=2|Williams tube timing]] Passons maintenant au rafraichissement mémoire. Il faut rafraichir l'écran pour une raison simple : l'image affichée par l'écran s'efface au bout de quelques millisecondes, quelques secondes, tout dépend du type d'écran utilisé. Le rafraichissement se fait en effectuant une lecture suivie d'une écriture : on récupère le contenu de la mémoire/tube, avant de le réécrire. Autour de la plaque de métal et du tube CRT, on trouve divers circuits qui gèrent les lectures et écritures. Les lectures et écritures se font bit par bit, on peut masquer certains bits lors des écritures, autoriser ou interdire les lectures/écritures durant un temps, etc. [[File:SEACComputer 004.jpg|centre|vignette|upright=2|Fonctionnement d'un tube Williams, avec les circuits associés]] <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> 6misyapxuwobescxhwfbgawop7trchb Les cartes graphiques/Le processeur de commandes 0 69571 744011 739201 2025-06-02T20:41:16Z Mewtow 31375 /* Le tampon de commandes */ 744011 wikitext text/x-wiki Dans ce chapitre, nous allons parler de tous les intermédiaires qui se placent entre une application de rendu 3D et les circuits de rendu 3D proprement dit. En premier lieu, on trouve le pilote de la carte graphique, aux fonctions multiples et variées. En second lieu, nous allons parler d'un circuit de la carte graphique qui fait l'interface entre le logiciel et les circuits de rendu 3D de la carte graphique : le processeur de commandes. Ce processeur de commandes est un circuit qui sert de chef d'orchestre, qui pilote le fonctionnement global de la carte graphique. API 3D, pilote de carte graphique et processeur de commande travaillent de concert pour que l'application communique avec la carte graphique. Nous allons d'abord voir le pilote de la carte graphique, avant de voir le fonctionnement du processeur de commande. ==Le pilote de carte graphique== Le pilote de la carte graphique est un logiciel qui s'occupe de faire l'interface entre le logiciel et la carte graphique. De manière générale, les pilotes de périphérique sont des intermédiaires entre les applications/APIs et le matériel. En théorie, le système d'exploitation est censé jouer ce rôle, mais il n'est pas programmé pour être compatible avec tous les périphériques vendus sur le marché. À la place, le système d'exploitation ne gère pas directement certains périphériques, mais fournit de quoi ajouter ce qui manque. Le pilote d'un périphérique sert justement à ajouter ce qui manque : ils ajoutent au système d'exploitation de quoi reconnaître le périphérique, de quoi l'utiliser au mieux. Pour une carte graphique, il a diverses fonctions que nous allons voir ci-dessous. Avant toute chose, précisons que les systèmes d'exploitation usuels (Windows, Linux, MacOsX et autres) sont fournis avec un pilote de carte graphique générique, compatible avec la plupart des cartes graphiques existantes. Rien de magique derrière cela : toutes les cartes graphiques vendues depuis plusieurs décennies respectent des standards, comme le VGA, le VESA, et d'autres. Et le pilote de base fournit avec le système d'exploitation est justement compatible avec ces standards minimaux. Mais le pilote ne peut pas profiter des fonctionnalités qui sont au-delà de ce standard. L'accélération 3D est presque inexistante avec le pilote de base, qui ne sert qu'à faire du rendu 2D (de quoi afficher l’interface de base du système d'exploitation, comme le bureau de Windows). Et même pour du rendu 2D, la plupart des fonctionnalités de la carte graphique ne sont pas disponibles. Par exemple, certaines résolutions ne sont pas disponibles, notamment les grandes résolutions. Ou encore, les performances sont loin d'être excellentes. Si vous avez déjà utilisé un PC sans pilote de carte graphique installé, vous avez certainement remarqué qu'il était particulièrement lent. ===La gestion des interruptions=== Une fonction particulièrement importante du pilote de carte graphique est la réponse aux interruptions lancées par la carte graphique. Pour rappel, les interruptions sont une fonctionnalité qui permet à un périphérique de communiquer avec le processeur, tout en économisant le temps de calcul de ce dernier. Typiquement, lorsqu'un périphérique lance une interruption, le processeur stoppe son travail et exécute automatiquement une routine d'interruption, un petit programme qui s'occupe de gérer le périphérique, de faire ce qu'il faut, ce que l'interruption a demandé. Il y a plusieurs interruptions possibles, chacune ayant son propre numéro et sa fonction dédiée, chacune ayant sa propre routine d'interruption. Après tout, la routine qui gère un débordement de la mémoire vidéo n'est pas la même que celle qui gère un changement de fréquence du GPU ou la fin du calcul d'une image 3D. Le pilote fournit l'ensemble des routines d'interruptions nécessaires pour gérer la carte graphique. ===La compilation des ''shaders''=== Le pilote de carte graphique est aussi chargé de traduire les ''shaders'' en code machine. En soi, cette étape est assez complexe, et ressemble beaucoup à la compilation d'un programme informatique normal. Les ''shaders'' sont écrits dans un langage de programmation de haut niveau, comme le HLSL ou le GLSL, mais ce n'est pas ce code source qui est compilé par le pilote de carte graphique. À la place, les ''shaders'' sont pré-compilés vers un langage dit intermédiaire, avant d'être compilé par le pilote en code machine. Le langage intermédiaire, comme son nom l'indique, sert d'intermédiaire entre le code source écrit en HLSL/GLSL et le code machine exécuté par la carte graphique. Il ressemble à un langage assembleur, mais reste malgré tout assez générique pour ne pas être un véritable code machine. Par exemple, il y a peu de limitations quant au nombre de processeurs ou de registres. En clair, il y a deux passes de compilation : une passe de traduction du code source en langage intermédiaire, puis une passe de compilation du code intermédiaire vers le code machine. Notons que la première passe est réalisée par le programmeur des ''shaders'', non pas par l'utilisateur. Par exemple, les ''shaders'' d'un jeu vidéo sont fournis déjà pré-compilés : les fichiers du jeu ne contiennent pas le code source GLSL/HLSL, mais du code intermédiaire. L'avantage de cette méthode est que le travail du pilote est fortement simplifié. Le pilote de périphérique pourrait compiler directement du code HLSL/GLSL, mais le temps de compilation serait très long et cela aurait un impact sur les performances. Avec l'usage du langage intermédiaire, le gros du travail à été fait lors de la première passe de compilation et le pilote graphique ne fait que finir le travail. Les optimisations importantes ont déjà été réalisées lors de la première passe. Il doit bien faire la traduction, ajouter quelques optimisations de bas niveau par-ci par-là, mais rien de bien gourmand en processeur. Autant dire que cela économise plus le processeur que si on devait compiler complètement les ''shaders'' à chaque exécution. Fait amusant, il faut savoir que le pilote peut parfois remplacer les ''shaders'' d'un jeu vidéo à la volée. Les pilotes récents embarquent en effet des ''shaders'' alternatifs pour les jeux les plus vendus et/ou les plus populaires. Lorsque vous lancez un de ces jeux vidéo et que le ''shader'' originel s'exécute, le pilote le détecte automatiquement et le remplace par la version améliorée, fournie par le pilote. Évidemment, le ''shader'' alternatif du pilote est optimisé pour le matériel adéquat. Cela permet de gagner en performance, voire en qualité d'image, sans pour autant que les concepteurs du jeu n'aient quoique ce soit à faire. Enfin, certains ''shaders'' sont fournis par le pilote pour d'autres raisons. Par exemple, les cartes graphiques récentes n'ont pas de circuits fixes pour traiter la géométrie. Autant les anciennes cartes graphiques avaient des circuits de T&L qui s'en occupaient, autant tout cela doit être émulé sur les machines récentes. Sans cette émulation, les vieux jeux vidéo conçus pour exploiter le T&L et d'autres technologies du genre ne fonctionneraient plus du tout. Émuler les circuits fixes disparus sur les cartes récentes est justement le fait de ''shaders'', présents dans le pilote de carte graphique. ===Les autres fonctions=== Le pilote a aussi bien d'autres fonctions. Par exemple, il s'occupe d'initialiser la carte graphique, de fixer la résolution, d'allouer la mémoire vidéo, de gérer le curseur de souris matériel, etc. ==Les commandes graphiques/vidéo/autres : des ordres envoyés au GPU== Tous les traitements que la carte graphique doit effectuer, qu'il s'agisse de rendu 2D, de calculs 2D, du décodage matérielle d'un flux vidéo, ou de calculs généralistes, sont envoyés par le pilote de la carte graphique, sous la forme de '''commandes'''. Ces commandes demandent à la carte graphique d'effectuer une opération 2D, ou une opération 3D, ou encore le rendu d'une vidéo. Les commandes graphiques en question varient beaucoup selon la carte graphique. Les commandes sont régulièrement revues et chaque nouvelle architecture a quelques changements par rapport aux modèles plus anciens. Des commandes peuvent apparaître, d'autres disparaître, d'autre voient leur fonctionnement légèrement altéré, etc. Mais dans les grandes lignes, on peut classer ces commandes en quelques grands types. Les commandes les plus importantes s'occupent de l'affichage 3D : afficher une image à partir de paquets de sommets, préparer le passage d'une image à une autre, changer la résolution, etc. Plus rare, d'autres commandes servent à faire du rendu 2D : afficher un polygone, tracer une ligne, coloriser une surface, etc. Sur les cartes graphiques qui peuvent accélérer le rendu des vidéos, il existe des commandes spécialisées pour l’accélération des vidéos. Pour donner quelques exemples, prenons les commandes 2D de la carte graphique AMD Radeon X1800. {|class="wikitable" |- ! Commandes 2D ! Fonction |- |PAINT |Peindre un rectangle d'une certaine couleur |- |PAINT_MULTI |Peindre des rectangles (pas les mêmes paramètres que PAINT) |- |BITBLT |Copie d'un bloc de mémoire dans un autre |- |BITBLT_MULTI |Plusieurs copies de blocs de mémoire dans d'autres |- |TRANS_BITBLT |Copie de blocs de mémoire avec un masque |- |NEXTCHAR |Afficher un caractère avec une certaine couleur |- |HOSTDATA_BLT |Écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo |- |POLYLINE |Afficher des lignes reliées entre elles |- |POLYSCANLINES |Afficher des lignes |- |PLY_NEXTSCAN |Afficher plusieurs lignes simples |- |SET_SCISSORS |Utiliser des coupes (ciseaux) |- |LOAD_PALETTE |Charger la palette pour affichage 2D |} ===Le tampon de commandes=== L'envoi des commandes à la carte graphique ne se fait pas directement. La carte graphique n'est pas toujours libre pour accepter une nouvelle commande, soit parce qu'elle est occupée par une commande précédente, soit parce qu'elle fait autre chose. Il faut alors faire patienter les données tant que la carte graphique est occupée. Les pilotes de la carte graphique vont les mettre en attente dans le '''tampon de commandes'''. Le tampon de commandes est ce qu'on appelle une file, une zone de mémoire dans laquelle on stocke des données dans l'ordre d'ajout. Si le tampon de commandes est plein, le driver n'accepte plus de demandes en provenance des applications. Un tampon de commandes plein est généralement mauvais signe : cela signifie que la carte graphique est trop lente pour traiter les demandes qui lui sont faites. Par contre, il arrive que le tampon de commandes soit vide : dans ce cas, c'est simplement que la carte graphique est trop rapide comparé au processeur, qui n'arrive alors pas à donner assez de commandes à la carte graphique pour l'occuper suffisamment. Le tampon de commande est soit une mémoire FIFO séparée, soit une portion de la mémoire vidéo. Le NV1, la toute première carte graphique NVIDIA, utilisait une mémoire FIFO intégrée à la carte graphique, séparée des autres circuits. Le NV1 contenait dans le détail : un controleur DMA avec une IO-MMU intégrée, la FIFO de commande, le processeur de commande, un pipeline graphique, un pipeline sonore, un contrôleur de manette. L'ensemble était relié par un bus interne à la carte graphique. : Le fonctionnement de la FIFO du NV1 est décrit dans le brevet ''US5805930A : System for FIFO informing the availability of stages to store commands which include data and virtual address sent directly from application programs''. ===Le processeur de commandes=== Le '''processeur de commande''' est un circuit qui gère les commandes envoyées par le processeur. Il lit la commande la plus ancienne dans le tampon de commande, l’interprète et l’exécute, et recommence ainsi de suite. Le processeur de commande est chargé de piloter les circuits de la carte graphique. Un point important est qu'il répartit le travail entre les différents circuits de la carte graphique et assure que l'ordre du pipeline est respecté. En soi, le processeur de commande est un circuit assez compliqué. Sur les cartes graphiques anciennes, c'était un circuit séquentiel complexe, fabriqué à la main et était la partie la plus complexe du processeur graphique. Sur les cartes graphiques modernes, c'est un véritable microcontrôleur, avec un processeur, de la mémoire RAM, etc. Le processeur de commandes récupère les commandes dans le tampon de commande, en mémoire RAM, pour les recopier dans la mémoire vidéo et/ou une mémoire interne. Cette copie se fait via la technologie DMA, une technologie de transfert de données entre mémoire RAM et périphérique qui n'utilise pas le processeur principal. Une fois la copie faite, le processeur de commande décode la commande et l’exécute sur la carte graphique. Il garde en mémoire l'état de traitement de chaque commande : est-ce qu'elle est en train de s’exécuter sur le processeur graphique, est-ce qu'elle est mise en pause, est-ce qu'elle attend une donnée en provenance de la mémoire, est-ce qu'elle est terminée, etc. Une commande utilise divers circuits de la carte 3D, de la mémoire vidéo, et d'autres ressources au sens large : des processeurs de ''shader'', notamment. La fonction principale du processeur de commande est de répartir le travail entre les différents circuits. Le processeur de commande décide à quel processeur ou circuit doit être envoyé une commande. C'est le processeur de commande qui s'occupe de la gestion des ressources et qui attribue telle ressource à telle commande. A chaque instant, le processeur de commande répartit les ''shaders'' sur les processeurs de ''shaders'', en faisant en sorte qu'ils soient utilisés le plus possible. Dans le cas le plus simple, les unités sont alimentées en vertex/pixels les unes après les autres (principe du round-robin), mais des stratégies plus optimisées sont la règle de nos jours. Cela est très important sur les cartes graphiques : répartir plusieurs commandes sur plusieurs processeurs est une tâche difficile. Il envoie aussi certaines commandes aux circuits fixes, comme l’''input assembler''. Là encore, il faut en sorte que les circuits fixes soient utilisés le plus possible et évite au maximum les situations où ces circuits n'ont rien à faire. Sa tâche est compliquée par le fait que les cartes graphiques actuelles dupliquent leurs unités pour pouvoir faire beaucoup de calculs en parallèle. Elles ont plusieurs unités de traitement des sommets et des pixels, plusieurs ROP, plusieurs unités de textures, etc. Et c'est en partie le travail du processeur de commande que de répartir les calculs sur ces différentes unités. [[File:Architecture de base d'une carte 3D - 1.png|centre|vignette|upright=2.5|Architecture de base d'une carte 3D - 1]] C'est là un problème assez compliqué pour le processeur de commande et ce pour tout un tas de raisons que nous ne ferons que survoler. Les contraintes d'ordonnancement de l'API et les règles de celle-ci sont une partie de la réponse. Mais d'autres raisons sont intrinsèques au rendu 3D ou à la conception des circuits. ===L'ordonnancement et la gestion des ressources=== Le processeur de commande doit souvent mettre en pause certains circuits du pipeline, ainsi que les circuits précédents. Par exemple, si tous les processeurs de ''vertex shader'' sont occupés, l’''input assembler'' ne peut pas charger le paquet suivant car il n'y a aucun processeur de libre pour l’accueillir. Dans ce cas, l'étape d’''input assembly'' est mise en pause en attendant qu'un processeur de ''shader'' soit libre. La même chose a lieu pour l'étape de rastérisation : si aucun processeur de ''shader'' n'est libre, elle est mise en pause. Sauf que pour la rastérisation, cela a des conséquences sur les circuits précédents la rastérisation. Si un processeur de ''shader'' veut envoyer quelque chose au rastériseur alors qu'il est en pause, il devra lui aussi attendre que le rastériseur soit libre. On a la même chose quand les ROP sont occupés : les ''pixel shader'' ou l'unité de texture doivent parfois être mis en pause, ce qui peut entrainer la mise en pause des étapes précédentes, etc. En clair : plus un étape est situé vers la fin du pipeline graphique, plus sa mise en pause a de chances de se répercuter sur les étapes précédentes et de les mettre en pause aussi. Le processeur de commande doit gérer ces situations. ===Le pipelining des commandes=== Dans les cartes graphiques les plus rudimentaires, le processeur de commande exécute les commandes dans l'ordre. Il exécute une commande çà la fois et attend qu'une commande soit terminé pour en lancer une autre. Plusieurs commandes sont accumulées dans le tampon de commande, le processeur de commande les traite de la plus ancienne vers la plus récente. Du moins, les anciennes cartes graphiques faisaient comme cela, les cartes graphiques modernes sont un peu plus complexes. Elles n'attendent pas qu'une commande soit totalement terminée avant d'en lancer une nouvelle. Les processeurs de commande actuels sont capables d’exécuter plusieurs commandes en même temps. L'intérêt est un gain en performance assez important. Pour ceux qui ont déjà eu un cours d'architecture des ordinateurs avancé, lancer plusieurs commandes en même temps permet une forme de pipeline, dont les gains sont substantiels. Par exemple, imaginez qu'une commande de rendu 3D soit bien avancée et n'utilise que les processeurs de ''shaders'' et les ROP, mais laisse les unités géométriques libres. Il est alors possible de démarrer la commande suivante en avance, afin qu'elle remplisse les unités géométriques inutilisées. On a alors deux commandes en cours de traitement : une commande qui utilise la fin du pipeline uniquement, une autre qui utilise seulement le début du pipeline graphique. Le processeur de commande gère donc plusieurs commandes simultanées, à savoir plusieurs commandes qui en sont à des étapes différentes du pipeline. On peut avoir une commande qui est en cours dans l'étage de gestion de la géométrie, une autre dans le rastériseur, et une autre dans les unités de traitement des pixels. Le fait que les étapes du pipeline graphique sont à effectuer dans un ordre bien précis permet ce genre de chose assez facilement. Une autre possibilité est de faire des rendus en parallèle. Par exemple, imaginez qu'on ait des circuits séparés pour le rendu 2D et 3D. Prenons l'exemple où le calcul d'une image finale demande de faire un rendu 3D suivi d'un rendu 2D, par exemple un jeu vidéo en 3D qui a un HUD dessiné en 2D. Dans ce cas, on peut démarrer le calcul de l'image suivante dans le pipeline 3D pendant que la précédente est dans les circuits 2D, au lieu de laisser inutilisé le pipeline 3D pendant le rendu 2D. Mais c'est là un défi compliqué à relever pour le processeur de commande, qui donne lieu à son lot de problèmes. Le problème principal est le partage de ressources entre commandes. Par exemple, on peut prendre le cas où une commande n'utilise pas beaucoup les processeurs de ''shaders''. On pourrait imaginer lancer une seconde commande en parallèle, afin que la seconde commande utiliser les processeurs de ''shaders'' inutilisés. Mais cela n'est possible que si les circuits fixes sont capables d'accepter une seconde commande. Si la première commande sature les circuits fixe, le lancement de la seconde commande sera empêché. Mais si ce n'est pas le cas, les deux commandes pourront être lancées en même temps. Pareil pour le débit mémoire, qui doit alors être partagé entre deux commandes simultanées, ce qui est à prendre en compte. ===La synchronisation de l’exécution des commandes avec le processeur=== Il arrive que le processeur doive savoir où en est le traitement des commandes, ce qui est très utile pour la gestion de la mémoire vidéo. Un premier exemple : comment éviter de saturer une carte graphique de commande, alors qu'on ne sait pas si elles traite les commandes rapidement ou non ? L'idéal est de regarder où en est la carte graphique dans l'exécution des commandes. Si elle n'en est qu'au début du tampon de commande et que celui-ci est bien remplit, alors il vaut mieux lever le pied et ne pas envoyer de nouvelles commandes. A l'inverse, si le tampon de commande est presque vide, envoyer des commandes est la meilleure idée possible. Un autre exemple un peu moins parlant est celui de la gestion de la mémoire vidéo. Rappelons qu'elle est réalisée par le pilote de la carte graphique, sur le processeur principal, qui décide d'allouer et de libérer de la mémoire vidéo. Pour donner un exemple d'utilisation, imaginez que le pilote de la carte graphique doive libérer de la mémoire pour pouvoir ajouter une nouvelle commande. Comment éviter d'enlever une texture tant que les commandes qui l'utilisent ne sont pas terminées ? Ce problème ne se limite pas aux textures, mais vaut pour tout ce qui est placé en mémoire vidéo. Il faut donc que la carte graphique trouve un moyen de prévenir le processeur que le traitement de telle commande est terminée, que telle commande en est rendue à tel ou tel point, etc. Pour cela, on a globalement deux grandes solutions. La première est celle des interruptions, abordées dans les chapitres précédents. Mais elles sont assez couteuses et ne sont utilisées que pour des évènements vraiment importants, critiques, qui demandent une réaction rapide du processeur. L'autre solution est celle du ''pooling'', où le processeur monitore la carte graphique à intervalles réguliers. Deux solutions bien connues de ceux qui ont déjà lu un cours d'architecture des ordinateurs digne de ce nom, rien de bien neuf : la carte graphique communique avec le processeur comme tout périphérique. Pour faciliter l'implémentation du ''pooling'', la carte graphique contient des registres de statut, dans le processeur de commande, qui mémorisent tout ou partie de l'état de la carte graphique. Si un problème survient, certains bits du registre de statut seront mis à 1 pour indiquer que telle erreur bien précise a eu lieu. Il existe aussi un registre de statut qui mémorise le numéro de la commande en cours, ou de la dernière commande terminée, ce qui permet de savoir où en est la carte graphique dans l'exécution des commandes. Et certaines registres de statut sont dédiés à la gestion des commandes. Ils sont totalement programmable, la carte graphique peut écrire dedans sans problème. Les cartes graphiques récentes incorporent des commandes pour modifier ces registres de statut au besoin. Elles sont appelées des '''commandes de synchronisation''' : les barrières (''fences''). Elles permettent d'écrire une valeur dans un registre de statut quand telle ou telle condition est remplie. Par exemple, si jamais une commande est terminée, on peut écrire la valeur 1 dans tel ou tel registre. La condition en question peut être assez complexe et se résumer à quelque chose du genre : "si jamais toutes les ''shaders'' ont fini de traiter tel ensemble de textures, alors écrit la valeur 1024 dans le registre de statut numéro 9". ===La synchronisation de l’exécution des commandes intra-GPU=== Lancer plusieurs commandes en parallèle dans le pipeline permet de gagner en performance.Mais cela a un gros défaut : il n'est pas garantit que les commandes se terminent dans l'ordre. Si on démarre une seconde commande après la première, il arrive que la seconde finisse avant. Pire : il n'est pas garantit qu'elles s'exécutent dans l'ordre. Dans la plupart des cas, cela ne pose pas de problèmes. Mais dans d'autres, cela donne des résultats erronés. Pour donner un exemple, utilisons les commandes de rendu 2D vues plus haut, histoire de simplifier le tout. Imaginez que vous codez un jeu vidéo et que le rendu se fait en 2D, partons sur un jeu de type FPS. Vous avez une série de commandes pour calculer l'image à rendre à l'écran, suivie par une série de commandes finales pour dessiner le HUB. Pour dessiner le HUD, vous utilisez des commandes HOSTDATA_BLT, dont le but est d'écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo. Et bien ces commandes HOSTDATA_BLT doivent démarrer une fois que le rendu de l'image est complétement terminé. Imaginez que vous dessiniez le HUD sur une portion de l'image pas encore terminée et que celui-ci est effacé par des écritures ultérieures ! Pour éviter tout problème, les GPU incorporent des commandes de synchronisation intra-GPU, destinées au processeur de commande, aussis appelées des '''commandes de sémaphore'''. Elles permettent de mettre en pause le lancement d'une nouvelle commande tant que les précédentes ne sont pas totalement ou partiellement terminées. Les plus simples empêchent le démarrage d'une commande tant que les précédentes ne sont pas terminées. D'autres permettent de démarrer une commande si et seulement si certaines commandes sont terminées. D'autres sont encore plus précises : elles empêchent le démarrage d'une nouvelle commande tant qu'une commande précédente n'a pas atteint un certain stade de son exécution. Là encore, de telles commandes sont des commandes du style "attend que le registre de statut numéro N contienne la valeur adéquate avant de poursuivre l'exécution des commandes". Les commandes en question peuvent être sur le même modèle que précédemment, à savoir des commandes qui lisent les registres de statut. Mais elles peuvent aussi se baser sur le fait que telle ou telle ressource de rendu est libre ou non. Des commandes successives se partagent souvent des données, et que de nombreuses commandes différentes peuvent s'exécuter en même temps. Or, si une commande veut modifier les données utilisées par une autre commande, il faut que l'ordre des commandes soit maintenu : la commande la plus récente ne doit pas modifier les données utilisées par une commande plus ancienne. Avec ce modèle, les sémaphores bloquent une commande tant qu'une ressource (une texture) est utilisée par une autre commande. {|class="wikitable" |- ! Commandes de synchronisation ! Fonction |- |NOP |Ne rien faire |- |WAIT_SEMAPHORE |Attendre la synchronisation avec un sémaphore |- |WAIT_MEM |Attendre que la mémoire vidéo soit disponible et inoccupée par le CPU |} ==L'arbitrage de l'accès à la carte graphique== Il n'est pas rare que plusieurs applications souhaitent accéder en même temps à la carte graphique. Imaginons que vous regardez une vidéo en ''streaming'' sur votre navigateur web, avec un programme de ''cloud computing'' de type ''Folding@Home'' qui tourne en arrière-plan, sur Windows. Le décodage de la vidéo est réalisé par la carte graphique, Windows s'occupe de l'affichage du bureau et des fenêtres, le navigateur web doit afficher tout ce qui est autour de la vidéo (la page web), le programme de ''cloud computing'' va lancer ses calculs sur la carte graphique, etc. Des situations de ce genre sont assez courantes et c'est soit le pilote qui s'en charge, soit la carte graphique elle-même. ===L'arbitrage logiciel du GPU=== L'arbitrage logiciel est la méthode la plus simple. Concrètement, c'est le système d'exploitation et/ou le pilote de la carte graphique qui gèrent l'arbitrage du GPU. Dans les deux cas, tout est fait en logiciel. Les commandes sont accumulées dans un tampon de commande, voire plusieurs, et l'OS/pilote décide quelle commande envoyer en priorité. Sur Windows, avant l'arrivée du modèle de driver dit ''Windows Display Driver Model'', de telles situations étaient gérées simplement. Les applications ajoutaient des commandes dans une file de commande unique. Les commandes étaient exécutées dans l'ordre, en mode premier entrée dans la file premier sorti/exécuté. Il n'y avait pour ainsi dire pas d'arbitrage entre les applications. Et ce n'était pas un problème car, à l'époque, les seules applications qui utilisaient le GPU étaient des jeux vidéos fonctionnant en mode plein écran. Avec le modèle de driver ''Windows Display Driver Model'' (WDDM), le GPU est maintenant arbitré, à savoir que les applications ont accès à tour de rôle au GPU, certaines ayant droit à plus de temps GPU que d'autres. Chaque programme a accès à la carte graphique durant quelques dizaines ou centaines de millisecondes, à tour de rôle. Si le programme finissait son travail en moins de temps que la durée impartie, il laissait la main au programme suivant. S’il atteignait la durée maximale allouée, il était interrompu pour laisser la place au programme suivant. Et chaque programme avait droit d'accès à la carte graphique chacun à son tour. Un tel algorithme en tourniquet est très simple, mais avait cependant quelques défauts. De nos jours, les algorithmes d'ordonnancement d'accès sont plus élaborés, bien qu'il soit difficile de trouver de la littérature ou des brevets sur le sujet. Une autre fonctionnalité de WDDM est que les applications utilisant le GPU peuvent se partager la mémoire vidéo sans se marcher dessus. Avant, toutes les applications avaient accès à toute la mémoire vidéo, bien que ce soit par l’intermédiaire de commandes spécifiques. Mais avec WDDM, chaque application dispose de sa propre portion de mémoire vidéo, à laquelle est la seule à avoir accès. Une application ne peut plus lire le contenu réel de la mémoire vidéo, et encore moins lire le contenu des autres applications. : Il s'agit d'un équivalent à l'isolation des processus pour les programmes Windows, mais appliqué à la mémoire vidéo et non la mémoire système. Et cette isolation est rendue d'autant plus simple que les GPU modernes implémentent un système de mémoire virtuelle à pagination très poussé, avec du swap en mémoire RAM système, une protection mémoire, et bien d'autres fonctionnalités. Nous en reparlerons dans les chapitres sur la mémoire vidéo. ===L'arbitrage accéléré par le GPU=== Depuis 2020, avec l'arrivée de la ''Windows 10 May 2020 update'', Windows est capable de déléguer l'arbitrage du GPU au GPU lui-même. Le GPU gère lui-même l'arbitrage, du moins en partie. En partie, car l'OS gére les priorité, à savoir quelle application a droit à plus de temps que les autres. Par contre, la gestion du ''quantum'' de temps ou les commutations de contexte (on stoppe une application pour laisser la place à une autre), est du fait du GPU lui-même. L'avantage est que cela décharge le processeur d'une tâche assez lourde en calcul, pour la déporter sur le GPU. Un autre avantage est que le GPU peut gérer plus finement les ''quantum'' de temps et la commutation de contexte. Le CPU principal gère des durées assez importantes, de l'ordre de la milliseconde. De plus, il doit communiquer avec le GPU par des mécanismes temporellement imprécis, comme des interruptions. Avec l'arbitrage accéléré par le GPU, le GPU n'a plus besoin de communiquer avec le CPU pour l'arbitrage et peut le faire plus précisément, plus immédiatement. Un gain en performance théorique est donc possible. L'arbitrage accéléré par le GPU est le fait soit du processeur de commandes, soit d'un processeur spécialisé, séparé. {{NavChapitre | book=Les cartes graphiques | prev=La hiérarchie mémoire d'un GPU | prevText=La hiérarchie mémoire d'un GPU | next=Le pipeline géométrique d'avant DirectX 10 | netxText=Le pipeline géométrique d'avant DirectX 10 }}{{autocat}} oprf9vu2e5gm04tmdoaqmum7exib550 744033 744011 2025-06-03T13:43:54Z Mewtow 31375 /* Le tampon de commandes */ 744033 wikitext text/x-wiki Dans ce chapitre, nous allons parler de tous les intermédiaires qui se placent entre une application de rendu 3D et les circuits de rendu 3D proprement dit. En premier lieu, on trouve le pilote de la carte graphique, aux fonctions multiples et variées. En second lieu, nous allons parler d'un circuit de la carte graphique qui fait l'interface entre le logiciel et les circuits de rendu 3D de la carte graphique : le processeur de commandes. Ce processeur de commandes est un circuit qui sert de chef d'orchestre, qui pilote le fonctionnement global de la carte graphique. API 3D, pilote de carte graphique et processeur de commande travaillent de concert pour que l'application communique avec la carte graphique. Nous allons d'abord voir le pilote de la carte graphique, avant de voir le fonctionnement du processeur de commande. ==Le pilote de carte graphique== Le pilote de la carte graphique est un logiciel qui s'occupe de faire l'interface entre le logiciel et la carte graphique. De manière générale, les pilotes de périphérique sont des intermédiaires entre les applications/APIs et le matériel. En théorie, le système d'exploitation est censé jouer ce rôle, mais il n'est pas programmé pour être compatible avec tous les périphériques vendus sur le marché. À la place, le système d'exploitation ne gère pas directement certains périphériques, mais fournit de quoi ajouter ce qui manque. Le pilote d'un périphérique sert justement à ajouter ce qui manque : ils ajoutent au système d'exploitation de quoi reconnaître le périphérique, de quoi l'utiliser au mieux. Pour une carte graphique, il a diverses fonctions que nous allons voir ci-dessous. Avant toute chose, précisons que les systèmes d'exploitation usuels (Windows, Linux, MacOsX et autres) sont fournis avec un pilote de carte graphique générique, compatible avec la plupart des cartes graphiques existantes. Rien de magique derrière cela : toutes les cartes graphiques vendues depuis plusieurs décennies respectent des standards, comme le VGA, le VESA, et d'autres. Et le pilote de base fournit avec le système d'exploitation est justement compatible avec ces standards minimaux. Mais le pilote ne peut pas profiter des fonctionnalités qui sont au-delà de ce standard. L'accélération 3D est presque inexistante avec le pilote de base, qui ne sert qu'à faire du rendu 2D (de quoi afficher l’interface de base du système d'exploitation, comme le bureau de Windows). Et même pour du rendu 2D, la plupart des fonctionnalités de la carte graphique ne sont pas disponibles. Par exemple, certaines résolutions ne sont pas disponibles, notamment les grandes résolutions. Ou encore, les performances sont loin d'être excellentes. Si vous avez déjà utilisé un PC sans pilote de carte graphique installé, vous avez certainement remarqué qu'il était particulièrement lent. ===La gestion des interruptions=== Une fonction particulièrement importante du pilote de carte graphique est la réponse aux interruptions lancées par la carte graphique. Pour rappel, les interruptions sont une fonctionnalité qui permet à un périphérique de communiquer avec le processeur, tout en économisant le temps de calcul de ce dernier. Typiquement, lorsqu'un périphérique lance une interruption, le processeur stoppe son travail et exécute automatiquement une routine d'interruption, un petit programme qui s'occupe de gérer le périphérique, de faire ce qu'il faut, ce que l'interruption a demandé. Il y a plusieurs interruptions possibles, chacune ayant son propre numéro et sa fonction dédiée, chacune ayant sa propre routine d'interruption. Après tout, la routine qui gère un débordement de la mémoire vidéo n'est pas la même que celle qui gère un changement de fréquence du GPU ou la fin du calcul d'une image 3D. Le pilote fournit l'ensemble des routines d'interruptions nécessaires pour gérer la carte graphique. ===La compilation des ''shaders''=== Le pilote de carte graphique est aussi chargé de traduire les ''shaders'' en code machine. En soi, cette étape est assez complexe, et ressemble beaucoup à la compilation d'un programme informatique normal. Les ''shaders'' sont écrits dans un langage de programmation de haut niveau, comme le HLSL ou le GLSL, mais ce n'est pas ce code source qui est compilé par le pilote de carte graphique. À la place, les ''shaders'' sont pré-compilés vers un langage dit intermédiaire, avant d'être compilé par le pilote en code machine. Le langage intermédiaire, comme son nom l'indique, sert d'intermédiaire entre le code source écrit en HLSL/GLSL et le code machine exécuté par la carte graphique. Il ressemble à un langage assembleur, mais reste malgré tout assez générique pour ne pas être un véritable code machine. Par exemple, il y a peu de limitations quant au nombre de processeurs ou de registres. En clair, il y a deux passes de compilation : une passe de traduction du code source en langage intermédiaire, puis une passe de compilation du code intermédiaire vers le code machine. Notons que la première passe est réalisée par le programmeur des ''shaders'', non pas par l'utilisateur. Par exemple, les ''shaders'' d'un jeu vidéo sont fournis déjà pré-compilés : les fichiers du jeu ne contiennent pas le code source GLSL/HLSL, mais du code intermédiaire. L'avantage de cette méthode est que le travail du pilote est fortement simplifié. Le pilote de périphérique pourrait compiler directement du code HLSL/GLSL, mais le temps de compilation serait très long et cela aurait un impact sur les performances. Avec l'usage du langage intermédiaire, le gros du travail à été fait lors de la première passe de compilation et le pilote graphique ne fait que finir le travail. Les optimisations importantes ont déjà été réalisées lors de la première passe. Il doit bien faire la traduction, ajouter quelques optimisations de bas niveau par-ci par-là, mais rien de bien gourmand en processeur. Autant dire que cela économise plus le processeur que si on devait compiler complètement les ''shaders'' à chaque exécution. Fait amusant, il faut savoir que le pilote peut parfois remplacer les ''shaders'' d'un jeu vidéo à la volée. Les pilotes récents embarquent en effet des ''shaders'' alternatifs pour les jeux les plus vendus et/ou les plus populaires. Lorsque vous lancez un de ces jeux vidéo et que le ''shader'' originel s'exécute, le pilote le détecte automatiquement et le remplace par la version améliorée, fournie par le pilote. Évidemment, le ''shader'' alternatif du pilote est optimisé pour le matériel adéquat. Cela permet de gagner en performance, voire en qualité d'image, sans pour autant que les concepteurs du jeu n'aient quoique ce soit à faire. Enfin, certains ''shaders'' sont fournis par le pilote pour d'autres raisons. Par exemple, les cartes graphiques récentes n'ont pas de circuits fixes pour traiter la géométrie. Autant les anciennes cartes graphiques avaient des circuits de T&L qui s'en occupaient, autant tout cela doit être émulé sur les machines récentes. Sans cette émulation, les vieux jeux vidéo conçus pour exploiter le T&L et d'autres technologies du genre ne fonctionneraient plus du tout. Émuler les circuits fixes disparus sur les cartes récentes est justement le fait de ''shaders'', présents dans le pilote de carte graphique. ===Les autres fonctions=== Le pilote a aussi bien d'autres fonctions. Par exemple, il s'occupe d'initialiser la carte graphique, de fixer la résolution, d'allouer la mémoire vidéo, de gérer le curseur de souris matériel, etc. ==Les commandes graphiques/vidéo/autres : des ordres envoyés au GPU== Tous les traitements que la carte graphique doit effectuer, qu'il s'agisse de rendu 2D, de calculs 2D, du décodage matérielle d'un flux vidéo, ou de calculs généralistes, sont envoyés par le pilote de la carte graphique, sous la forme de '''commandes'''. Ces commandes demandent à la carte graphique d'effectuer une opération 2D, ou une opération 3D, ou encore le rendu d'une vidéo. Les commandes graphiques en question varient beaucoup selon la carte graphique. Les commandes sont régulièrement revues et chaque nouvelle architecture a quelques changements par rapport aux modèles plus anciens. Des commandes peuvent apparaître, d'autres disparaître, d'autre voient leur fonctionnement légèrement altéré, etc. Mais dans les grandes lignes, on peut classer ces commandes en quelques grands types. Les commandes les plus importantes s'occupent de l'affichage 3D : afficher une image à partir de paquets de sommets, préparer le passage d'une image à une autre, changer la résolution, etc. Plus rare, d'autres commandes servent à faire du rendu 2D : afficher un polygone, tracer une ligne, coloriser une surface, etc. Sur les cartes graphiques qui peuvent accélérer le rendu des vidéos, il existe des commandes spécialisées pour l’accélération des vidéos. Pour donner quelques exemples, prenons les commandes 2D de la carte graphique AMD Radeon X1800. {|class="wikitable" |- ! Commandes 2D ! Fonction |- |PAINT |Peindre un rectangle d'une certaine couleur |- |PAINT_MULTI |Peindre des rectangles (pas les mêmes paramètres que PAINT) |- |BITBLT |Copie d'un bloc de mémoire dans un autre |- |BITBLT_MULTI |Plusieurs copies de blocs de mémoire dans d'autres |- |TRANS_BITBLT |Copie de blocs de mémoire avec un masque |- |NEXTCHAR |Afficher un caractère avec une certaine couleur |- |HOSTDATA_BLT |Écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo |- |POLYLINE |Afficher des lignes reliées entre elles |- |POLYSCANLINES |Afficher des lignes |- |PLY_NEXTSCAN |Afficher plusieurs lignes simples |- |SET_SCISSORS |Utiliser des coupes (ciseaux) |- |LOAD_PALETTE |Charger la palette pour affichage 2D |} ===Le tampon de commandes=== L'envoi des commandes à la carte graphique ne se fait pas directement. La carte graphique n'est pas toujours libre pour accepter une nouvelle commande, soit parce qu'elle est occupée par une commande précédente, soit parce qu'elle fait autre chose. Il faut alors faire patienter les données tant que la carte graphique est occupée. Les pilotes de la carte graphique vont les mettre en attente dans le '''tampon de commandes'''. Le tampon de commandes est ce qu'on appelle une file, une zone de mémoire dans laquelle on stocke des données dans l'ordre d'ajout. Si le tampon de commandes est plein, le driver n'accepte plus de demandes en provenance des applications. Un tampon de commandes plein est généralement mauvais signe : cela signifie que la carte graphique est trop lente pour traiter les demandes qui lui sont faites. Par contre, il arrive que le tampon de commandes soit vide : dans ce cas, c'est simplement que la carte graphique est trop rapide comparé au processeur, qui n'arrive alors pas à donner assez de commandes à la carte graphique pour l'occuper suffisamment. Le tampon de commande est soit une mémoire FIFO séparée, soit une portion de la mémoire vidéo. Le NV1, la toute première carte graphique NVIDIA, utilisait une mémoire FIFO intégrée à la carte graphique, séparée des autres circuits. Le NV1 contenait dans le détail : un controleur DMA avec une IO-MMU intégrée, la FIFO de commande, le processeur de commande, un pipeline graphique, un pipeline sonore, un contrôleur de manette. L'ensemble était relié par un bus interne à la carte graphique. Le processeur envoyait les commandes par rafale au GPU, à savoir qu'il envoyait plusieurs dizaines ou centaines de commandes à la suite, avant de passer à autre chose. Le GPU traitait les commandes une par une, à un rythme bien plus lent. Le processeur pouvait consulter la FIFO pour savoir s'il restait des entrées libres et combien. Le processeur savait ainsi combien d'écritures il pouvait envoyer en une fois au GPU. : Le fonctionnement de la FIFO du NV1 est décrit dans le brevet ''US5805930A : System for FIFO informing the availability of stages to store commands which include data and virtual address sent directly from application programs''. ===Le processeur de commandes=== Le '''processeur de commande''' est un circuit qui gère les commandes envoyées par le processeur. Il lit la commande la plus ancienne dans le tampon de commande, l’interprète et l’exécute, et recommence ainsi de suite. Le processeur de commande est chargé de piloter les circuits de la carte graphique. Un point important est qu'il répartit le travail entre les différents circuits de la carte graphique et assure que l'ordre du pipeline est respecté. En soi, le processeur de commande est un circuit assez compliqué. Sur les cartes graphiques anciennes, c'était un circuit séquentiel complexe, fabriqué à la main et était la partie la plus complexe du processeur graphique. Sur les cartes graphiques modernes, c'est un véritable microcontrôleur, avec un processeur, de la mémoire RAM, etc. Le processeur de commandes récupère les commandes dans le tampon de commande, en mémoire RAM, pour les recopier dans la mémoire vidéo et/ou une mémoire interne. Cette copie se fait via la technologie DMA, une technologie de transfert de données entre mémoire RAM et périphérique qui n'utilise pas le processeur principal. Une fois la copie faite, le processeur de commande décode la commande et l’exécute sur la carte graphique. Il garde en mémoire l'état de traitement de chaque commande : est-ce qu'elle est en train de s’exécuter sur le processeur graphique, est-ce qu'elle est mise en pause, est-ce qu'elle attend une donnée en provenance de la mémoire, est-ce qu'elle est terminée, etc. Une commande utilise divers circuits de la carte 3D, de la mémoire vidéo, et d'autres ressources au sens large : des processeurs de ''shader'', notamment. La fonction principale du processeur de commande est de répartir le travail entre les différents circuits. Le processeur de commande décide à quel processeur ou circuit doit être envoyé une commande. C'est le processeur de commande qui s'occupe de la gestion des ressources et qui attribue telle ressource à telle commande. A chaque instant, le processeur de commande répartit les ''shaders'' sur les processeurs de ''shaders'', en faisant en sorte qu'ils soient utilisés le plus possible. Dans le cas le plus simple, les unités sont alimentées en vertex/pixels les unes après les autres (principe du round-robin), mais des stratégies plus optimisées sont la règle de nos jours. Cela est très important sur les cartes graphiques : répartir plusieurs commandes sur plusieurs processeurs est une tâche difficile. Il envoie aussi certaines commandes aux circuits fixes, comme l’''input assembler''. Là encore, il faut en sorte que les circuits fixes soient utilisés le plus possible et évite au maximum les situations où ces circuits n'ont rien à faire. Sa tâche est compliquée par le fait que les cartes graphiques actuelles dupliquent leurs unités pour pouvoir faire beaucoup de calculs en parallèle. Elles ont plusieurs unités de traitement des sommets et des pixels, plusieurs ROP, plusieurs unités de textures, etc. Et c'est en partie le travail du processeur de commande que de répartir les calculs sur ces différentes unités. [[File:Architecture de base d'une carte 3D - 1.png|centre|vignette|upright=2.5|Architecture de base d'une carte 3D - 1]] C'est là un problème assez compliqué pour le processeur de commande et ce pour tout un tas de raisons que nous ne ferons que survoler. Les contraintes d'ordonnancement de l'API et les règles de celle-ci sont une partie de la réponse. Mais d'autres raisons sont intrinsèques au rendu 3D ou à la conception des circuits. ===L'ordonnancement et la gestion des ressources=== Le processeur de commande doit souvent mettre en pause certains circuits du pipeline, ainsi que les circuits précédents. Par exemple, si tous les processeurs de ''vertex shader'' sont occupés, l’''input assembler'' ne peut pas charger le paquet suivant car il n'y a aucun processeur de libre pour l’accueillir. Dans ce cas, l'étape d’''input assembly'' est mise en pause en attendant qu'un processeur de ''shader'' soit libre. La même chose a lieu pour l'étape de rastérisation : si aucun processeur de ''shader'' n'est libre, elle est mise en pause. Sauf que pour la rastérisation, cela a des conséquences sur les circuits précédents la rastérisation. Si un processeur de ''shader'' veut envoyer quelque chose au rastériseur alors qu'il est en pause, il devra lui aussi attendre que le rastériseur soit libre. On a la même chose quand les ROP sont occupés : les ''pixel shader'' ou l'unité de texture doivent parfois être mis en pause, ce qui peut entrainer la mise en pause des étapes précédentes, etc. En clair : plus un étape est situé vers la fin du pipeline graphique, plus sa mise en pause a de chances de se répercuter sur les étapes précédentes et de les mettre en pause aussi. Le processeur de commande doit gérer ces situations. ===Le pipelining des commandes=== Dans les cartes graphiques les plus rudimentaires, le processeur de commande exécute les commandes dans l'ordre. Il exécute une commande çà la fois et attend qu'une commande soit terminé pour en lancer une autre. Plusieurs commandes sont accumulées dans le tampon de commande, le processeur de commande les traite de la plus ancienne vers la plus récente. Du moins, les anciennes cartes graphiques faisaient comme cela, les cartes graphiques modernes sont un peu plus complexes. Elles n'attendent pas qu'une commande soit totalement terminée avant d'en lancer une nouvelle. Les processeurs de commande actuels sont capables d’exécuter plusieurs commandes en même temps. L'intérêt est un gain en performance assez important. Pour ceux qui ont déjà eu un cours d'architecture des ordinateurs avancé, lancer plusieurs commandes en même temps permet une forme de pipeline, dont les gains sont substantiels. Par exemple, imaginez qu'une commande de rendu 3D soit bien avancée et n'utilise que les processeurs de ''shaders'' et les ROP, mais laisse les unités géométriques libres. Il est alors possible de démarrer la commande suivante en avance, afin qu'elle remplisse les unités géométriques inutilisées. On a alors deux commandes en cours de traitement : une commande qui utilise la fin du pipeline uniquement, une autre qui utilise seulement le début du pipeline graphique. Le processeur de commande gère donc plusieurs commandes simultanées, à savoir plusieurs commandes qui en sont à des étapes différentes du pipeline. On peut avoir une commande qui est en cours dans l'étage de gestion de la géométrie, une autre dans le rastériseur, et une autre dans les unités de traitement des pixels. Le fait que les étapes du pipeline graphique sont à effectuer dans un ordre bien précis permet ce genre de chose assez facilement. Une autre possibilité est de faire des rendus en parallèle. Par exemple, imaginez qu'on ait des circuits séparés pour le rendu 2D et 3D. Prenons l'exemple où le calcul d'une image finale demande de faire un rendu 3D suivi d'un rendu 2D, par exemple un jeu vidéo en 3D qui a un HUD dessiné en 2D. Dans ce cas, on peut démarrer le calcul de l'image suivante dans le pipeline 3D pendant que la précédente est dans les circuits 2D, au lieu de laisser inutilisé le pipeline 3D pendant le rendu 2D. Mais c'est là un défi compliqué à relever pour le processeur de commande, qui donne lieu à son lot de problèmes. Le problème principal est le partage de ressources entre commandes. Par exemple, on peut prendre le cas où une commande n'utilise pas beaucoup les processeurs de ''shaders''. On pourrait imaginer lancer une seconde commande en parallèle, afin que la seconde commande utiliser les processeurs de ''shaders'' inutilisés. Mais cela n'est possible que si les circuits fixes sont capables d'accepter une seconde commande. Si la première commande sature les circuits fixe, le lancement de la seconde commande sera empêché. Mais si ce n'est pas le cas, les deux commandes pourront être lancées en même temps. Pareil pour le débit mémoire, qui doit alors être partagé entre deux commandes simultanées, ce qui est à prendre en compte. ===La synchronisation de l’exécution des commandes avec le processeur=== Il arrive que le processeur doive savoir où en est le traitement des commandes, ce qui est très utile pour la gestion de la mémoire vidéo. Un premier exemple : comment éviter de saturer une carte graphique de commande, alors qu'on ne sait pas si elles traite les commandes rapidement ou non ? L'idéal est de regarder où en est la carte graphique dans l'exécution des commandes. Si elle n'en est qu'au début du tampon de commande et que celui-ci est bien remplit, alors il vaut mieux lever le pied et ne pas envoyer de nouvelles commandes. A l'inverse, si le tampon de commande est presque vide, envoyer des commandes est la meilleure idée possible. Un autre exemple un peu moins parlant est celui de la gestion de la mémoire vidéo. Rappelons qu'elle est réalisée par le pilote de la carte graphique, sur le processeur principal, qui décide d'allouer et de libérer de la mémoire vidéo. Pour donner un exemple d'utilisation, imaginez que le pilote de la carte graphique doive libérer de la mémoire pour pouvoir ajouter une nouvelle commande. Comment éviter d'enlever une texture tant que les commandes qui l'utilisent ne sont pas terminées ? Ce problème ne se limite pas aux textures, mais vaut pour tout ce qui est placé en mémoire vidéo. Il faut donc que la carte graphique trouve un moyen de prévenir le processeur que le traitement de telle commande est terminée, que telle commande en est rendue à tel ou tel point, etc. Pour cela, on a globalement deux grandes solutions. La première est celle des interruptions, abordées dans les chapitres précédents. Mais elles sont assez couteuses et ne sont utilisées que pour des évènements vraiment importants, critiques, qui demandent une réaction rapide du processeur. L'autre solution est celle du ''pooling'', où le processeur monitore la carte graphique à intervalles réguliers. Deux solutions bien connues de ceux qui ont déjà lu un cours d'architecture des ordinateurs digne de ce nom, rien de bien neuf : la carte graphique communique avec le processeur comme tout périphérique. Pour faciliter l'implémentation du ''pooling'', la carte graphique contient des registres de statut, dans le processeur de commande, qui mémorisent tout ou partie de l'état de la carte graphique. Si un problème survient, certains bits du registre de statut seront mis à 1 pour indiquer que telle erreur bien précise a eu lieu. Il existe aussi un registre de statut qui mémorise le numéro de la commande en cours, ou de la dernière commande terminée, ce qui permet de savoir où en est la carte graphique dans l'exécution des commandes. Et certaines registres de statut sont dédiés à la gestion des commandes. Ils sont totalement programmable, la carte graphique peut écrire dedans sans problème. Les cartes graphiques récentes incorporent des commandes pour modifier ces registres de statut au besoin. Elles sont appelées des '''commandes de synchronisation''' : les barrières (''fences''). Elles permettent d'écrire une valeur dans un registre de statut quand telle ou telle condition est remplie. Par exemple, si jamais une commande est terminée, on peut écrire la valeur 1 dans tel ou tel registre. La condition en question peut être assez complexe et se résumer à quelque chose du genre : "si jamais toutes les ''shaders'' ont fini de traiter tel ensemble de textures, alors écrit la valeur 1024 dans le registre de statut numéro 9". ===La synchronisation de l’exécution des commandes intra-GPU=== Lancer plusieurs commandes en parallèle dans le pipeline permet de gagner en performance.Mais cela a un gros défaut : il n'est pas garantit que les commandes se terminent dans l'ordre. Si on démarre une seconde commande après la première, il arrive que la seconde finisse avant. Pire : il n'est pas garantit qu'elles s'exécutent dans l'ordre. Dans la plupart des cas, cela ne pose pas de problèmes. Mais dans d'autres, cela donne des résultats erronés. Pour donner un exemple, utilisons les commandes de rendu 2D vues plus haut, histoire de simplifier le tout. Imaginez que vous codez un jeu vidéo et que le rendu se fait en 2D, partons sur un jeu de type FPS. Vous avez une série de commandes pour calculer l'image à rendre à l'écran, suivie par une série de commandes finales pour dessiner le HUB. Pour dessiner le HUD, vous utilisez des commandes HOSTDATA_BLT, dont le but est d'écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo. Et bien ces commandes HOSTDATA_BLT doivent démarrer une fois que le rendu de l'image est complétement terminé. Imaginez que vous dessiniez le HUD sur une portion de l'image pas encore terminée et que celui-ci est effacé par des écritures ultérieures ! Pour éviter tout problème, les GPU incorporent des commandes de synchronisation intra-GPU, destinées au processeur de commande, aussis appelées des '''commandes de sémaphore'''. Elles permettent de mettre en pause le lancement d'une nouvelle commande tant que les précédentes ne sont pas totalement ou partiellement terminées. Les plus simples empêchent le démarrage d'une commande tant que les précédentes ne sont pas terminées. D'autres permettent de démarrer une commande si et seulement si certaines commandes sont terminées. D'autres sont encore plus précises : elles empêchent le démarrage d'une nouvelle commande tant qu'une commande précédente n'a pas atteint un certain stade de son exécution. Là encore, de telles commandes sont des commandes du style "attend que le registre de statut numéro N contienne la valeur adéquate avant de poursuivre l'exécution des commandes". Les commandes en question peuvent être sur le même modèle que précédemment, à savoir des commandes qui lisent les registres de statut. Mais elles peuvent aussi se baser sur le fait que telle ou telle ressource de rendu est libre ou non. Des commandes successives se partagent souvent des données, et que de nombreuses commandes différentes peuvent s'exécuter en même temps. Or, si une commande veut modifier les données utilisées par une autre commande, il faut que l'ordre des commandes soit maintenu : la commande la plus récente ne doit pas modifier les données utilisées par une commande plus ancienne. Avec ce modèle, les sémaphores bloquent une commande tant qu'une ressource (une texture) est utilisée par une autre commande. {|class="wikitable" |- ! Commandes de synchronisation ! Fonction |- |NOP |Ne rien faire |- |WAIT_SEMAPHORE |Attendre la synchronisation avec un sémaphore |- |WAIT_MEM |Attendre que la mémoire vidéo soit disponible et inoccupée par le CPU |} ==L'arbitrage de l'accès à la carte graphique== Il n'est pas rare que plusieurs applications souhaitent accéder en même temps à la carte graphique. Imaginons que vous regardez une vidéo en ''streaming'' sur votre navigateur web, avec un programme de ''cloud computing'' de type ''Folding@Home'' qui tourne en arrière-plan, sur Windows. Le décodage de la vidéo est réalisé par la carte graphique, Windows s'occupe de l'affichage du bureau et des fenêtres, le navigateur web doit afficher tout ce qui est autour de la vidéo (la page web), le programme de ''cloud computing'' va lancer ses calculs sur la carte graphique, etc. Des situations de ce genre sont assez courantes et c'est soit le pilote qui s'en charge, soit la carte graphique elle-même. ===L'arbitrage logiciel du GPU=== L'arbitrage logiciel est la méthode la plus simple. Concrètement, c'est le système d'exploitation et/ou le pilote de la carte graphique qui gèrent l'arbitrage du GPU. Dans les deux cas, tout est fait en logiciel. Les commandes sont accumulées dans un tampon de commande, voire plusieurs, et l'OS/pilote décide quelle commande envoyer en priorité. Sur Windows, avant l'arrivée du modèle de driver dit ''Windows Display Driver Model'', de telles situations étaient gérées simplement. Les applications ajoutaient des commandes dans une file de commande unique. Les commandes étaient exécutées dans l'ordre, en mode premier entrée dans la file premier sorti/exécuté. Il n'y avait pour ainsi dire pas d'arbitrage entre les applications. Et ce n'était pas un problème car, à l'époque, les seules applications qui utilisaient le GPU étaient des jeux vidéos fonctionnant en mode plein écran. Avec le modèle de driver ''Windows Display Driver Model'' (WDDM), le GPU est maintenant arbitré, à savoir que les applications ont accès à tour de rôle au GPU, certaines ayant droit à plus de temps GPU que d'autres. Chaque programme a accès à la carte graphique durant quelques dizaines ou centaines de millisecondes, à tour de rôle. Si le programme finissait son travail en moins de temps que la durée impartie, il laissait la main au programme suivant. S’il atteignait la durée maximale allouée, il était interrompu pour laisser la place au programme suivant. Et chaque programme avait droit d'accès à la carte graphique chacun à son tour. Un tel algorithme en tourniquet est très simple, mais avait cependant quelques défauts. De nos jours, les algorithmes d'ordonnancement d'accès sont plus élaborés, bien qu'il soit difficile de trouver de la littérature ou des brevets sur le sujet. Une autre fonctionnalité de WDDM est que les applications utilisant le GPU peuvent se partager la mémoire vidéo sans se marcher dessus. Avant, toutes les applications avaient accès à toute la mémoire vidéo, bien que ce soit par l’intermédiaire de commandes spécifiques. Mais avec WDDM, chaque application dispose de sa propre portion de mémoire vidéo, à laquelle est la seule à avoir accès. Une application ne peut plus lire le contenu réel de la mémoire vidéo, et encore moins lire le contenu des autres applications. : Il s'agit d'un équivalent à l'isolation des processus pour les programmes Windows, mais appliqué à la mémoire vidéo et non la mémoire système. Et cette isolation est rendue d'autant plus simple que les GPU modernes implémentent un système de mémoire virtuelle à pagination très poussé, avec du swap en mémoire RAM système, une protection mémoire, et bien d'autres fonctionnalités. Nous en reparlerons dans les chapitres sur la mémoire vidéo. ===L'arbitrage accéléré par le GPU=== Depuis 2020, avec l'arrivée de la ''Windows 10 May 2020 update'', Windows est capable de déléguer l'arbitrage du GPU au GPU lui-même. Le GPU gère lui-même l'arbitrage, du moins en partie. En partie, car l'OS gére les priorité, à savoir quelle application a droit à plus de temps que les autres. Par contre, la gestion du ''quantum'' de temps ou les commutations de contexte (on stoppe une application pour laisser la place à une autre), est du fait du GPU lui-même. L'avantage est que cela décharge le processeur d'une tâche assez lourde en calcul, pour la déporter sur le GPU. Un autre avantage est que le GPU peut gérer plus finement les ''quantum'' de temps et la commutation de contexte. Le CPU principal gère des durées assez importantes, de l'ordre de la milliseconde. De plus, il doit communiquer avec le GPU par des mécanismes temporellement imprécis, comme des interruptions. Avec l'arbitrage accéléré par le GPU, le GPU n'a plus besoin de communiquer avec le CPU pour l'arbitrage et peut le faire plus précisément, plus immédiatement. Un gain en performance théorique est donc possible. L'arbitrage accéléré par le GPU est le fait soit du processeur de commandes, soit d'un processeur spécialisé, séparé. {{NavChapitre | book=Les cartes graphiques | prev=La hiérarchie mémoire d'un GPU | prevText=La hiérarchie mémoire d'un GPU | next=Le pipeline géométrique d'avant DirectX 10 | netxText=Le pipeline géométrique d'avant DirectX 10 }}{{autocat}} rpjowl8on9mmuplhqtfmb7ghvov9iy6 744034 744033 2025-06-03T13:51:04Z Mewtow 31375 /* Le processeur de commandes */ 744034 wikitext text/x-wiki Dans ce chapitre, nous allons parler de tous les intermédiaires qui se placent entre une application de rendu 3D et les circuits de rendu 3D proprement dit. En premier lieu, on trouve le pilote de la carte graphique, aux fonctions multiples et variées. En second lieu, nous allons parler d'un circuit de la carte graphique qui fait l'interface entre le logiciel et les circuits de rendu 3D de la carte graphique : le processeur de commandes. Ce processeur de commandes est un circuit qui sert de chef d'orchestre, qui pilote le fonctionnement global de la carte graphique. API 3D, pilote de carte graphique et processeur de commande travaillent de concert pour que l'application communique avec la carte graphique. Nous allons d'abord voir le pilote de la carte graphique, avant de voir le fonctionnement du processeur de commande. ==Le pilote de carte graphique== Le pilote de la carte graphique est un logiciel qui s'occupe de faire l'interface entre le logiciel et la carte graphique. De manière générale, les pilotes de périphérique sont des intermédiaires entre les applications/APIs et le matériel. En théorie, le système d'exploitation est censé jouer ce rôle, mais il n'est pas programmé pour être compatible avec tous les périphériques vendus sur le marché. À la place, le système d'exploitation ne gère pas directement certains périphériques, mais fournit de quoi ajouter ce qui manque. Le pilote d'un périphérique sert justement à ajouter ce qui manque : ils ajoutent au système d'exploitation de quoi reconnaître le périphérique, de quoi l'utiliser au mieux. Pour une carte graphique, il a diverses fonctions que nous allons voir ci-dessous. Avant toute chose, précisons que les systèmes d'exploitation usuels (Windows, Linux, MacOsX et autres) sont fournis avec un pilote de carte graphique générique, compatible avec la plupart des cartes graphiques existantes. Rien de magique derrière cela : toutes les cartes graphiques vendues depuis plusieurs décennies respectent des standards, comme le VGA, le VESA, et d'autres. Et le pilote de base fournit avec le système d'exploitation est justement compatible avec ces standards minimaux. Mais le pilote ne peut pas profiter des fonctionnalités qui sont au-delà de ce standard. L'accélération 3D est presque inexistante avec le pilote de base, qui ne sert qu'à faire du rendu 2D (de quoi afficher l’interface de base du système d'exploitation, comme le bureau de Windows). Et même pour du rendu 2D, la plupart des fonctionnalités de la carte graphique ne sont pas disponibles. Par exemple, certaines résolutions ne sont pas disponibles, notamment les grandes résolutions. Ou encore, les performances sont loin d'être excellentes. Si vous avez déjà utilisé un PC sans pilote de carte graphique installé, vous avez certainement remarqué qu'il était particulièrement lent. ===La gestion des interruptions=== Une fonction particulièrement importante du pilote de carte graphique est la réponse aux interruptions lancées par la carte graphique. Pour rappel, les interruptions sont une fonctionnalité qui permet à un périphérique de communiquer avec le processeur, tout en économisant le temps de calcul de ce dernier. Typiquement, lorsqu'un périphérique lance une interruption, le processeur stoppe son travail et exécute automatiquement une routine d'interruption, un petit programme qui s'occupe de gérer le périphérique, de faire ce qu'il faut, ce que l'interruption a demandé. Il y a plusieurs interruptions possibles, chacune ayant son propre numéro et sa fonction dédiée, chacune ayant sa propre routine d'interruption. Après tout, la routine qui gère un débordement de la mémoire vidéo n'est pas la même que celle qui gère un changement de fréquence du GPU ou la fin du calcul d'une image 3D. Le pilote fournit l'ensemble des routines d'interruptions nécessaires pour gérer la carte graphique. ===La compilation des ''shaders''=== Le pilote de carte graphique est aussi chargé de traduire les ''shaders'' en code machine. En soi, cette étape est assez complexe, et ressemble beaucoup à la compilation d'un programme informatique normal. Les ''shaders'' sont écrits dans un langage de programmation de haut niveau, comme le HLSL ou le GLSL, mais ce n'est pas ce code source qui est compilé par le pilote de carte graphique. À la place, les ''shaders'' sont pré-compilés vers un langage dit intermédiaire, avant d'être compilé par le pilote en code machine. Le langage intermédiaire, comme son nom l'indique, sert d'intermédiaire entre le code source écrit en HLSL/GLSL et le code machine exécuté par la carte graphique. Il ressemble à un langage assembleur, mais reste malgré tout assez générique pour ne pas être un véritable code machine. Par exemple, il y a peu de limitations quant au nombre de processeurs ou de registres. En clair, il y a deux passes de compilation : une passe de traduction du code source en langage intermédiaire, puis une passe de compilation du code intermédiaire vers le code machine. Notons que la première passe est réalisée par le programmeur des ''shaders'', non pas par l'utilisateur. Par exemple, les ''shaders'' d'un jeu vidéo sont fournis déjà pré-compilés : les fichiers du jeu ne contiennent pas le code source GLSL/HLSL, mais du code intermédiaire. L'avantage de cette méthode est que le travail du pilote est fortement simplifié. Le pilote de périphérique pourrait compiler directement du code HLSL/GLSL, mais le temps de compilation serait très long et cela aurait un impact sur les performances. Avec l'usage du langage intermédiaire, le gros du travail à été fait lors de la première passe de compilation et le pilote graphique ne fait que finir le travail. Les optimisations importantes ont déjà été réalisées lors de la première passe. Il doit bien faire la traduction, ajouter quelques optimisations de bas niveau par-ci par-là, mais rien de bien gourmand en processeur. Autant dire que cela économise plus le processeur que si on devait compiler complètement les ''shaders'' à chaque exécution. Fait amusant, il faut savoir que le pilote peut parfois remplacer les ''shaders'' d'un jeu vidéo à la volée. Les pilotes récents embarquent en effet des ''shaders'' alternatifs pour les jeux les plus vendus et/ou les plus populaires. Lorsque vous lancez un de ces jeux vidéo et que le ''shader'' originel s'exécute, le pilote le détecte automatiquement et le remplace par la version améliorée, fournie par le pilote. Évidemment, le ''shader'' alternatif du pilote est optimisé pour le matériel adéquat. Cela permet de gagner en performance, voire en qualité d'image, sans pour autant que les concepteurs du jeu n'aient quoique ce soit à faire. Enfin, certains ''shaders'' sont fournis par le pilote pour d'autres raisons. Par exemple, les cartes graphiques récentes n'ont pas de circuits fixes pour traiter la géométrie. Autant les anciennes cartes graphiques avaient des circuits de T&L qui s'en occupaient, autant tout cela doit être émulé sur les machines récentes. Sans cette émulation, les vieux jeux vidéo conçus pour exploiter le T&L et d'autres technologies du genre ne fonctionneraient plus du tout. Émuler les circuits fixes disparus sur les cartes récentes est justement le fait de ''shaders'', présents dans le pilote de carte graphique. ===Les autres fonctions=== Le pilote a aussi bien d'autres fonctions. Par exemple, il s'occupe d'initialiser la carte graphique, de fixer la résolution, d'allouer la mémoire vidéo, de gérer le curseur de souris matériel, etc. ==Les commandes graphiques/vidéo/autres : des ordres envoyés au GPU== Tous les traitements que la carte graphique doit effectuer, qu'il s'agisse de rendu 2D, de calculs 2D, du décodage matérielle d'un flux vidéo, ou de calculs généralistes, sont envoyés par le pilote de la carte graphique, sous la forme de '''commandes'''. Ces commandes demandent à la carte graphique d'effectuer une opération 2D, ou une opération 3D, ou encore le rendu d'une vidéo. Les commandes graphiques en question varient beaucoup selon la carte graphique. Les commandes sont régulièrement revues et chaque nouvelle architecture a quelques changements par rapport aux modèles plus anciens. Des commandes peuvent apparaître, d'autres disparaître, d'autre voient leur fonctionnement légèrement altéré, etc. Mais dans les grandes lignes, on peut classer ces commandes en quelques grands types. Les commandes les plus importantes s'occupent de l'affichage 3D : afficher une image à partir de paquets de sommets, préparer le passage d'une image à une autre, changer la résolution, etc. Plus rare, d'autres commandes servent à faire du rendu 2D : afficher un polygone, tracer une ligne, coloriser une surface, etc. Sur les cartes graphiques qui peuvent accélérer le rendu des vidéos, il existe des commandes spécialisées pour l’accélération des vidéos. Pour donner quelques exemples, prenons les commandes 2D de la carte graphique AMD Radeon X1800. {|class="wikitable" |- ! Commandes 2D ! Fonction |- |PAINT |Peindre un rectangle d'une certaine couleur |- |PAINT_MULTI |Peindre des rectangles (pas les mêmes paramètres que PAINT) |- |BITBLT |Copie d'un bloc de mémoire dans un autre |- |BITBLT_MULTI |Plusieurs copies de blocs de mémoire dans d'autres |- |TRANS_BITBLT |Copie de blocs de mémoire avec un masque |- |NEXTCHAR |Afficher un caractère avec une certaine couleur |- |HOSTDATA_BLT |Écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo |- |POLYLINE |Afficher des lignes reliées entre elles |- |POLYSCANLINES |Afficher des lignes |- |PLY_NEXTSCAN |Afficher plusieurs lignes simples |- |SET_SCISSORS |Utiliser des coupes (ciseaux) |- |LOAD_PALETTE |Charger la palette pour affichage 2D |} ===Le tampon de commandes=== L'envoi des commandes à la carte graphique ne se fait pas directement. La carte graphique n'est pas toujours libre pour accepter une nouvelle commande, soit parce qu'elle est occupée par une commande précédente, soit parce qu'elle fait autre chose. Il faut alors faire patienter les données tant que la carte graphique est occupée. Les pilotes de la carte graphique vont les mettre en attente dans le '''tampon de commandes'''. Le tampon de commandes est ce qu'on appelle une file, une zone de mémoire dans laquelle on stocke des données dans l'ordre d'ajout. Si le tampon de commandes est plein, le driver n'accepte plus de demandes en provenance des applications. Un tampon de commandes plein est généralement mauvais signe : cela signifie que la carte graphique est trop lente pour traiter les demandes qui lui sont faites. Par contre, il arrive que le tampon de commandes soit vide : dans ce cas, c'est simplement que la carte graphique est trop rapide comparé au processeur, qui n'arrive alors pas à donner assez de commandes à la carte graphique pour l'occuper suffisamment. Le tampon de commande est soit une mémoire FIFO séparée, soit une portion de la mémoire vidéo. Le NV1, la toute première carte graphique NVIDIA, utilisait une mémoire FIFO intégrée à la carte graphique, séparée des autres circuits. Le NV1 contenait dans le détail : un controleur DMA avec une IO-MMU intégrée, la FIFO de commande, le processeur de commande, un pipeline graphique, un pipeline sonore, un contrôleur de manette. L'ensemble était relié par un bus interne à la carte graphique. Le processeur envoyait les commandes par rafale au GPU, à savoir qu'il envoyait plusieurs dizaines ou centaines de commandes à la suite, avant de passer à autre chose. Le GPU traitait les commandes une par une, à un rythme bien plus lent. Le processeur pouvait consulter la FIFO pour savoir s'il restait des entrées libres et combien. Le processeur savait ainsi combien d'écritures il pouvait envoyer en une fois au GPU. : Le fonctionnement de la FIFO du NV1 est décrit dans le brevet ''US5805930A : System for FIFO informing the availability of stages to store commands which include data and virtual address sent directly from application programs''. ===Le processeur de commandes=== Le '''processeur de commande''' est un circuit qui gère les commandes envoyées par le processeur. Il lit la commande la plus ancienne dans le tampon de commande, l’interprète et l’exécute, puis passe à la suivante. Le processeur de commande est un circuit assez compliqué. Sur les cartes graphiques anciennes, c'était un circuit séquentiel complexe, fabriqué à la main et était la partie la plus complexe du processeur graphique. Sur les cartes graphiques modernes, c'est un véritable microcontrôleur, avec un processeur, de la mémoire RAM, etc. Le processeur de commandes lit une commande dans le tampon de commande, décode la commande et l’exécute sur la carte graphique. Il garde en mémoire l'état de traitement de chaque commande : est-ce qu'elle est en train de s’exécuter sur le processeur graphique, est-ce qu'elle est mise en pause, est-ce qu'elle attend une donnée en provenance de la mémoire, est-ce qu'elle est terminée, etc. Une commande utilise divers circuits de la carte 3D, de la mémoire vidéo, et d'autres ressources au sens large (des processeurs de ''shader'', notamment). Aussi, le processeur de commande pilote les circuits de la carte graphique, il répartit le travail entre les différents circuits de la carte graphique et assure que l'ordre du pipeline est respecté. La fonction principale du processeur de commande est de répartir le travail entre les différents circuits. Le processeur de commande décide à quel processeur ou circuit doit être envoyé une commande. C'est le processeur de commande qui s'occupe de la gestion des ressources et qui attribue telle ressource à telle commande. A chaque instant, le processeur de commande répartit les ''shaders'' sur les processeurs de ''shaders'', en faisant en sorte qu'ils soient utilisés le plus possible. Dans le cas le plus simple, les unités sont alimentées en vertex/pixels les unes après les autres (principe du round-robin), mais des stratégies plus optimisées sont la règle de nos jours. Cela est très important sur les cartes graphiques : répartir plusieurs commandes sur plusieurs processeurs est une tâche difficile. Il envoie aussi certaines commandes aux circuits fixes, comme l’''input assembler''. Là encore, il faut en sorte que les circuits fixes soient utilisés le plus possible et évite au maximum les situations où ces circuits n'ont rien à faire. Sa tâche est compliquée par le fait que les cartes graphiques actuelles dupliquent leurs unités pour pouvoir faire beaucoup de calculs en parallèle. Elles ont plusieurs unités de traitement des sommets et des pixels, plusieurs ROP, plusieurs unités de textures, etc. Et c'est en partie le travail du processeur de commande que de répartir les calculs sur ces différentes unités. [[File:Architecture de base d'une carte 3D - 1.png|centre|vignette|upright=2.5|Architecture de base d'une carte 3D - 1]] C'est là un problème assez compliqué pour le processeur de commande et ce pour tout un tas de raisons que nous ne ferons que survoler. Les contraintes d'ordonnancement de l'API et les règles de celle-ci sont une partie de la réponse. Mais d'autres raisons sont intrinsèques au rendu 3D ou à la conception des circuits. ===L'ordonnancement et la gestion des ressources=== Le processeur de commande doit souvent mettre en pause certains circuits du pipeline, ainsi que les circuits précédents. Par exemple, si tous les processeurs de ''vertex shader'' sont occupés, l’''input assembler'' ne peut pas charger le paquet suivant car il n'y a aucun processeur de libre pour l’accueillir. Dans ce cas, l'étape d’''input assembly'' est mise en pause en attendant qu'un processeur de ''shader'' soit libre. La même chose a lieu pour l'étape de rastérisation : si aucun processeur de ''shader'' n'est libre, elle est mise en pause. Sauf que pour la rastérisation, cela a des conséquences sur les circuits précédents la rastérisation. Si un processeur de ''shader'' veut envoyer quelque chose au rastériseur alors qu'il est en pause, il devra lui aussi attendre que le rastériseur soit libre. On a la même chose quand les ROP sont occupés : les ''pixel shader'' ou l'unité de texture doivent parfois être mis en pause, ce qui peut entrainer la mise en pause des étapes précédentes, etc. En clair : plus un étape est situé vers la fin du pipeline graphique, plus sa mise en pause a de chances de se répercuter sur les étapes précédentes et de les mettre en pause aussi. Le processeur de commande doit gérer ces situations. ===Le pipelining des commandes=== Dans les cartes graphiques les plus rudimentaires, le processeur de commande exécute les commandes dans l'ordre. Il exécute une commande çà la fois et attend qu'une commande soit terminé pour en lancer une autre. Plusieurs commandes sont accumulées dans le tampon de commande, le processeur de commande les traite de la plus ancienne vers la plus récente. Du moins, les anciennes cartes graphiques faisaient comme cela, les cartes graphiques modernes sont un peu plus complexes. Elles n'attendent pas qu'une commande soit totalement terminée avant d'en lancer une nouvelle. Les processeurs de commande actuels sont capables d’exécuter plusieurs commandes en même temps. L'intérêt est un gain en performance assez important. Pour ceux qui ont déjà eu un cours d'architecture des ordinateurs avancé, lancer plusieurs commandes en même temps permet une forme de pipeline, dont les gains sont substantiels. Par exemple, imaginez qu'une commande de rendu 3D soit bien avancée et n'utilise que les processeurs de ''shaders'' et les ROP, mais laisse les unités géométriques libres. Il est alors possible de démarrer la commande suivante en avance, afin qu'elle remplisse les unités géométriques inutilisées. On a alors deux commandes en cours de traitement : une commande qui utilise la fin du pipeline uniquement, une autre qui utilise seulement le début du pipeline graphique. Le processeur de commande gère donc plusieurs commandes simultanées, à savoir plusieurs commandes qui en sont à des étapes différentes du pipeline. On peut avoir une commande qui est en cours dans l'étage de gestion de la géométrie, une autre dans le rastériseur, et une autre dans les unités de traitement des pixels. Le fait que les étapes du pipeline graphique sont à effectuer dans un ordre bien précis permet ce genre de chose assez facilement. Une autre possibilité est de faire des rendus en parallèle. Par exemple, imaginez qu'on ait des circuits séparés pour le rendu 2D et 3D. Prenons l'exemple où le calcul d'une image finale demande de faire un rendu 3D suivi d'un rendu 2D, par exemple un jeu vidéo en 3D qui a un HUD dessiné en 2D. Dans ce cas, on peut démarrer le calcul de l'image suivante dans le pipeline 3D pendant que la précédente est dans les circuits 2D, au lieu de laisser inutilisé le pipeline 3D pendant le rendu 2D. Mais c'est là un défi compliqué à relever pour le processeur de commande, qui donne lieu à son lot de problèmes. Le problème principal est le partage de ressources entre commandes. Par exemple, on peut prendre le cas où une commande n'utilise pas beaucoup les processeurs de ''shaders''. On pourrait imaginer lancer une seconde commande en parallèle, afin que la seconde commande utiliser les processeurs de ''shaders'' inutilisés. Mais cela n'est possible que si les circuits fixes sont capables d'accepter une seconde commande. Si la première commande sature les circuits fixe, le lancement de la seconde commande sera empêché. Mais si ce n'est pas le cas, les deux commandes pourront être lancées en même temps. Pareil pour le débit mémoire, qui doit alors être partagé entre deux commandes simultanées, ce qui est à prendre en compte. ===La synchronisation de l’exécution des commandes avec le processeur=== Il arrive que le processeur doive savoir où en est le traitement des commandes, ce qui est très utile pour la gestion de la mémoire vidéo. Un premier exemple : comment éviter de saturer une carte graphique de commande, alors qu'on ne sait pas si elles traite les commandes rapidement ou non ? L'idéal est de regarder où en est la carte graphique dans l'exécution des commandes. Si elle n'en est qu'au début du tampon de commande et que celui-ci est bien remplit, alors il vaut mieux lever le pied et ne pas envoyer de nouvelles commandes. A l'inverse, si le tampon de commande est presque vide, envoyer des commandes est la meilleure idée possible. Un autre exemple un peu moins parlant est celui de la gestion de la mémoire vidéo. Rappelons qu'elle est réalisée par le pilote de la carte graphique, sur le processeur principal, qui décide d'allouer et de libérer de la mémoire vidéo. Pour donner un exemple d'utilisation, imaginez que le pilote de la carte graphique doive libérer de la mémoire pour pouvoir ajouter une nouvelle commande. Comment éviter d'enlever une texture tant que les commandes qui l'utilisent ne sont pas terminées ? Ce problème ne se limite pas aux textures, mais vaut pour tout ce qui est placé en mémoire vidéo. Il faut donc que la carte graphique trouve un moyen de prévenir le processeur que le traitement de telle commande est terminée, que telle commande en est rendue à tel ou tel point, etc. Pour cela, on a globalement deux grandes solutions. La première est celle des interruptions, abordées dans les chapitres précédents. Mais elles sont assez couteuses et ne sont utilisées que pour des évènements vraiment importants, critiques, qui demandent une réaction rapide du processeur. L'autre solution est celle du ''pooling'', où le processeur monitore la carte graphique à intervalles réguliers. Deux solutions bien connues de ceux qui ont déjà lu un cours d'architecture des ordinateurs digne de ce nom, rien de bien neuf : la carte graphique communique avec le processeur comme tout périphérique. Pour faciliter l'implémentation du ''pooling'', la carte graphique contient des registres de statut, dans le processeur de commande, qui mémorisent tout ou partie de l'état de la carte graphique. Si un problème survient, certains bits du registre de statut seront mis à 1 pour indiquer que telle erreur bien précise a eu lieu. Il existe aussi un registre de statut qui mémorise le numéro de la commande en cours, ou de la dernière commande terminée, ce qui permet de savoir où en est la carte graphique dans l'exécution des commandes. Et certaines registres de statut sont dédiés à la gestion des commandes. Ils sont totalement programmable, la carte graphique peut écrire dedans sans problème. Les cartes graphiques récentes incorporent des commandes pour modifier ces registres de statut au besoin. Elles sont appelées des '''commandes de synchronisation''' : les barrières (''fences''). Elles permettent d'écrire une valeur dans un registre de statut quand telle ou telle condition est remplie. Par exemple, si jamais une commande est terminée, on peut écrire la valeur 1 dans tel ou tel registre. La condition en question peut être assez complexe et se résumer à quelque chose du genre : "si jamais toutes les ''shaders'' ont fini de traiter tel ensemble de textures, alors écrit la valeur 1024 dans le registre de statut numéro 9". ===La synchronisation de l’exécution des commandes intra-GPU=== Lancer plusieurs commandes en parallèle dans le pipeline permet de gagner en performance.Mais cela a un gros défaut : il n'est pas garantit que les commandes se terminent dans l'ordre. Si on démarre une seconde commande après la première, il arrive que la seconde finisse avant. Pire : il n'est pas garantit qu'elles s'exécutent dans l'ordre. Dans la plupart des cas, cela ne pose pas de problèmes. Mais dans d'autres, cela donne des résultats erronés. Pour donner un exemple, utilisons les commandes de rendu 2D vues plus haut, histoire de simplifier le tout. Imaginez que vous codez un jeu vidéo et que le rendu se fait en 2D, partons sur un jeu de type FPS. Vous avez une série de commandes pour calculer l'image à rendre à l'écran, suivie par une série de commandes finales pour dessiner le HUB. Pour dessiner le HUD, vous utilisez des commandes HOSTDATA_BLT, dont le but est d'écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo. Et bien ces commandes HOSTDATA_BLT doivent démarrer une fois que le rendu de l'image est complétement terminé. Imaginez que vous dessiniez le HUD sur une portion de l'image pas encore terminée et que celui-ci est effacé par des écritures ultérieures ! Pour éviter tout problème, les GPU incorporent des commandes de synchronisation intra-GPU, destinées au processeur de commande, aussis appelées des '''commandes de sémaphore'''. Elles permettent de mettre en pause le lancement d'une nouvelle commande tant que les précédentes ne sont pas totalement ou partiellement terminées. Les plus simples empêchent le démarrage d'une commande tant que les précédentes ne sont pas terminées. D'autres permettent de démarrer une commande si et seulement si certaines commandes sont terminées. D'autres sont encore plus précises : elles empêchent le démarrage d'une nouvelle commande tant qu'une commande précédente n'a pas atteint un certain stade de son exécution. Là encore, de telles commandes sont des commandes du style "attend que le registre de statut numéro N contienne la valeur adéquate avant de poursuivre l'exécution des commandes". Les commandes en question peuvent être sur le même modèle que précédemment, à savoir des commandes qui lisent les registres de statut. Mais elles peuvent aussi se baser sur le fait que telle ou telle ressource de rendu est libre ou non. Des commandes successives se partagent souvent des données, et que de nombreuses commandes différentes peuvent s'exécuter en même temps. Or, si une commande veut modifier les données utilisées par une autre commande, il faut que l'ordre des commandes soit maintenu : la commande la plus récente ne doit pas modifier les données utilisées par une commande plus ancienne. Avec ce modèle, les sémaphores bloquent une commande tant qu'une ressource (une texture) est utilisée par une autre commande. {|class="wikitable" |- ! Commandes de synchronisation ! Fonction |- |NOP |Ne rien faire |- |WAIT_SEMAPHORE |Attendre la synchronisation avec un sémaphore |- |WAIT_MEM |Attendre que la mémoire vidéo soit disponible et inoccupée par le CPU |} ==L'arbitrage de l'accès à la carte graphique== Il n'est pas rare que plusieurs applications souhaitent accéder en même temps à la carte graphique. Imaginons que vous regardez une vidéo en ''streaming'' sur votre navigateur web, avec un programme de ''cloud computing'' de type ''Folding@Home'' qui tourne en arrière-plan, sur Windows. Le décodage de la vidéo est réalisé par la carte graphique, Windows s'occupe de l'affichage du bureau et des fenêtres, le navigateur web doit afficher tout ce qui est autour de la vidéo (la page web), le programme de ''cloud computing'' va lancer ses calculs sur la carte graphique, etc. Des situations de ce genre sont assez courantes et c'est soit le pilote qui s'en charge, soit la carte graphique elle-même. ===L'arbitrage logiciel du GPU=== L'arbitrage logiciel est la méthode la plus simple. Concrètement, c'est le système d'exploitation et/ou le pilote de la carte graphique qui gèrent l'arbitrage du GPU. Dans les deux cas, tout est fait en logiciel. Les commandes sont accumulées dans un tampon de commande, voire plusieurs, et l'OS/pilote décide quelle commande envoyer en priorité. Sur Windows, avant l'arrivée du modèle de driver dit ''Windows Display Driver Model'', de telles situations étaient gérées simplement. Les applications ajoutaient des commandes dans une file de commande unique. Les commandes étaient exécutées dans l'ordre, en mode premier entrée dans la file premier sorti/exécuté. Il n'y avait pour ainsi dire pas d'arbitrage entre les applications. Et ce n'était pas un problème car, à l'époque, les seules applications qui utilisaient le GPU étaient des jeux vidéos fonctionnant en mode plein écran. Avec le modèle de driver ''Windows Display Driver Model'' (WDDM), le GPU est maintenant arbitré, à savoir que les applications ont accès à tour de rôle au GPU, certaines ayant droit à plus de temps GPU que d'autres. Chaque programme a accès à la carte graphique durant quelques dizaines ou centaines de millisecondes, à tour de rôle. Si le programme finissait son travail en moins de temps que la durée impartie, il laissait la main au programme suivant. S’il atteignait la durée maximale allouée, il était interrompu pour laisser la place au programme suivant. Et chaque programme avait droit d'accès à la carte graphique chacun à son tour. Un tel algorithme en tourniquet est très simple, mais avait cependant quelques défauts. De nos jours, les algorithmes d'ordonnancement d'accès sont plus élaborés, bien qu'il soit difficile de trouver de la littérature ou des brevets sur le sujet. Une autre fonctionnalité de WDDM est que les applications utilisant le GPU peuvent se partager la mémoire vidéo sans se marcher dessus. Avant, toutes les applications avaient accès à toute la mémoire vidéo, bien que ce soit par l’intermédiaire de commandes spécifiques. Mais avec WDDM, chaque application dispose de sa propre portion de mémoire vidéo, à laquelle est la seule à avoir accès. Une application ne peut plus lire le contenu réel de la mémoire vidéo, et encore moins lire le contenu des autres applications. : Il s'agit d'un équivalent à l'isolation des processus pour les programmes Windows, mais appliqué à la mémoire vidéo et non la mémoire système. Et cette isolation est rendue d'autant plus simple que les GPU modernes implémentent un système de mémoire virtuelle à pagination très poussé, avec du swap en mémoire RAM système, une protection mémoire, et bien d'autres fonctionnalités. Nous en reparlerons dans les chapitres sur la mémoire vidéo. ===L'arbitrage accéléré par le GPU=== Depuis 2020, avec l'arrivée de la ''Windows 10 May 2020 update'', Windows est capable de déléguer l'arbitrage du GPU au GPU lui-même. Le GPU gère lui-même l'arbitrage, du moins en partie. En partie, car l'OS gére les priorité, à savoir quelle application a droit à plus de temps que les autres. Par contre, la gestion du ''quantum'' de temps ou les commutations de contexte (on stoppe une application pour laisser la place à une autre), est du fait du GPU lui-même. L'avantage est que cela décharge le processeur d'une tâche assez lourde en calcul, pour la déporter sur le GPU. Un autre avantage est que le GPU peut gérer plus finement les ''quantum'' de temps et la commutation de contexte. Le CPU principal gère des durées assez importantes, de l'ordre de la milliseconde. De plus, il doit communiquer avec le GPU par des mécanismes temporellement imprécis, comme des interruptions. Avec l'arbitrage accéléré par le GPU, le GPU n'a plus besoin de communiquer avec le CPU pour l'arbitrage et peut le faire plus précisément, plus immédiatement. Un gain en performance théorique est donc possible. L'arbitrage accéléré par le GPU est le fait soit du processeur de commandes, soit d'un processeur spécialisé, séparé. {{NavChapitre | book=Les cartes graphiques | prev=La hiérarchie mémoire d'un GPU | prevText=La hiérarchie mémoire d'un GPU | next=Le pipeline géométrique d'avant DirectX 10 | netxText=Le pipeline géométrique d'avant DirectX 10 }}{{autocat}} 6hblv3izfmnw77b4h0cud01fc7pnx0d 744035 744034 2025-06-03T13:53:37Z Mewtow 31375 /* Le processeur de commandes */ 744035 wikitext text/x-wiki Dans ce chapitre, nous allons parler de tous les intermédiaires qui se placent entre une application de rendu 3D et les circuits de rendu 3D proprement dit. En premier lieu, on trouve le pilote de la carte graphique, aux fonctions multiples et variées. En second lieu, nous allons parler d'un circuit de la carte graphique qui fait l'interface entre le logiciel et les circuits de rendu 3D de la carte graphique : le processeur de commandes. Ce processeur de commandes est un circuit qui sert de chef d'orchestre, qui pilote le fonctionnement global de la carte graphique. API 3D, pilote de carte graphique et processeur de commande travaillent de concert pour que l'application communique avec la carte graphique. Nous allons d'abord voir le pilote de la carte graphique, avant de voir le fonctionnement du processeur de commande. ==Le pilote de carte graphique== Le pilote de la carte graphique est un logiciel qui s'occupe de faire l'interface entre le logiciel et la carte graphique. De manière générale, les pilotes de périphérique sont des intermédiaires entre les applications/APIs et le matériel. En théorie, le système d'exploitation est censé jouer ce rôle, mais il n'est pas programmé pour être compatible avec tous les périphériques vendus sur le marché. À la place, le système d'exploitation ne gère pas directement certains périphériques, mais fournit de quoi ajouter ce qui manque. Le pilote d'un périphérique sert justement à ajouter ce qui manque : ils ajoutent au système d'exploitation de quoi reconnaître le périphérique, de quoi l'utiliser au mieux. Pour une carte graphique, il a diverses fonctions que nous allons voir ci-dessous. Avant toute chose, précisons que les systèmes d'exploitation usuels (Windows, Linux, MacOsX et autres) sont fournis avec un pilote de carte graphique générique, compatible avec la plupart des cartes graphiques existantes. Rien de magique derrière cela : toutes les cartes graphiques vendues depuis plusieurs décennies respectent des standards, comme le VGA, le VESA, et d'autres. Et le pilote de base fournit avec le système d'exploitation est justement compatible avec ces standards minimaux. Mais le pilote ne peut pas profiter des fonctionnalités qui sont au-delà de ce standard. L'accélération 3D est presque inexistante avec le pilote de base, qui ne sert qu'à faire du rendu 2D (de quoi afficher l’interface de base du système d'exploitation, comme le bureau de Windows). Et même pour du rendu 2D, la plupart des fonctionnalités de la carte graphique ne sont pas disponibles. Par exemple, certaines résolutions ne sont pas disponibles, notamment les grandes résolutions. Ou encore, les performances sont loin d'être excellentes. Si vous avez déjà utilisé un PC sans pilote de carte graphique installé, vous avez certainement remarqué qu'il était particulièrement lent. ===La gestion des interruptions=== Une fonction particulièrement importante du pilote de carte graphique est la réponse aux interruptions lancées par la carte graphique. Pour rappel, les interruptions sont une fonctionnalité qui permet à un périphérique de communiquer avec le processeur, tout en économisant le temps de calcul de ce dernier. Typiquement, lorsqu'un périphérique lance une interruption, le processeur stoppe son travail et exécute automatiquement une routine d'interruption, un petit programme qui s'occupe de gérer le périphérique, de faire ce qu'il faut, ce que l'interruption a demandé. Il y a plusieurs interruptions possibles, chacune ayant son propre numéro et sa fonction dédiée, chacune ayant sa propre routine d'interruption. Après tout, la routine qui gère un débordement de la mémoire vidéo n'est pas la même que celle qui gère un changement de fréquence du GPU ou la fin du calcul d'une image 3D. Le pilote fournit l'ensemble des routines d'interruptions nécessaires pour gérer la carte graphique. ===La compilation des ''shaders''=== Le pilote de carte graphique est aussi chargé de traduire les ''shaders'' en code machine. En soi, cette étape est assez complexe, et ressemble beaucoup à la compilation d'un programme informatique normal. Les ''shaders'' sont écrits dans un langage de programmation de haut niveau, comme le HLSL ou le GLSL, mais ce n'est pas ce code source qui est compilé par le pilote de carte graphique. À la place, les ''shaders'' sont pré-compilés vers un langage dit intermédiaire, avant d'être compilé par le pilote en code machine. Le langage intermédiaire, comme son nom l'indique, sert d'intermédiaire entre le code source écrit en HLSL/GLSL et le code machine exécuté par la carte graphique. Il ressemble à un langage assembleur, mais reste malgré tout assez générique pour ne pas être un véritable code machine. Par exemple, il y a peu de limitations quant au nombre de processeurs ou de registres. En clair, il y a deux passes de compilation : une passe de traduction du code source en langage intermédiaire, puis une passe de compilation du code intermédiaire vers le code machine. Notons que la première passe est réalisée par le programmeur des ''shaders'', non pas par l'utilisateur. Par exemple, les ''shaders'' d'un jeu vidéo sont fournis déjà pré-compilés : les fichiers du jeu ne contiennent pas le code source GLSL/HLSL, mais du code intermédiaire. L'avantage de cette méthode est que le travail du pilote est fortement simplifié. Le pilote de périphérique pourrait compiler directement du code HLSL/GLSL, mais le temps de compilation serait très long et cela aurait un impact sur les performances. Avec l'usage du langage intermédiaire, le gros du travail à été fait lors de la première passe de compilation et le pilote graphique ne fait que finir le travail. Les optimisations importantes ont déjà été réalisées lors de la première passe. Il doit bien faire la traduction, ajouter quelques optimisations de bas niveau par-ci par-là, mais rien de bien gourmand en processeur. Autant dire que cela économise plus le processeur que si on devait compiler complètement les ''shaders'' à chaque exécution. Fait amusant, il faut savoir que le pilote peut parfois remplacer les ''shaders'' d'un jeu vidéo à la volée. Les pilotes récents embarquent en effet des ''shaders'' alternatifs pour les jeux les plus vendus et/ou les plus populaires. Lorsque vous lancez un de ces jeux vidéo et que le ''shader'' originel s'exécute, le pilote le détecte automatiquement et le remplace par la version améliorée, fournie par le pilote. Évidemment, le ''shader'' alternatif du pilote est optimisé pour le matériel adéquat. Cela permet de gagner en performance, voire en qualité d'image, sans pour autant que les concepteurs du jeu n'aient quoique ce soit à faire. Enfin, certains ''shaders'' sont fournis par le pilote pour d'autres raisons. Par exemple, les cartes graphiques récentes n'ont pas de circuits fixes pour traiter la géométrie. Autant les anciennes cartes graphiques avaient des circuits de T&L qui s'en occupaient, autant tout cela doit être émulé sur les machines récentes. Sans cette émulation, les vieux jeux vidéo conçus pour exploiter le T&L et d'autres technologies du genre ne fonctionneraient plus du tout. Émuler les circuits fixes disparus sur les cartes récentes est justement le fait de ''shaders'', présents dans le pilote de carte graphique. ===Les autres fonctions=== Le pilote a aussi bien d'autres fonctions. Par exemple, il s'occupe d'initialiser la carte graphique, de fixer la résolution, d'allouer la mémoire vidéo, de gérer le curseur de souris matériel, etc. ==Les commandes graphiques/vidéo/autres : des ordres envoyés au GPU== Tous les traitements que la carte graphique doit effectuer, qu'il s'agisse de rendu 2D, de calculs 2D, du décodage matérielle d'un flux vidéo, ou de calculs généralistes, sont envoyés par le pilote de la carte graphique, sous la forme de '''commandes'''. Ces commandes demandent à la carte graphique d'effectuer une opération 2D, ou une opération 3D, ou encore le rendu d'une vidéo. Les commandes graphiques en question varient beaucoup selon la carte graphique. Les commandes sont régulièrement revues et chaque nouvelle architecture a quelques changements par rapport aux modèles plus anciens. Des commandes peuvent apparaître, d'autres disparaître, d'autre voient leur fonctionnement légèrement altéré, etc. Mais dans les grandes lignes, on peut classer ces commandes en quelques grands types. Les commandes les plus importantes s'occupent de l'affichage 3D : afficher une image à partir de paquets de sommets, préparer le passage d'une image à une autre, changer la résolution, etc. Plus rare, d'autres commandes servent à faire du rendu 2D : afficher un polygone, tracer une ligne, coloriser une surface, etc. Sur les cartes graphiques qui peuvent accélérer le rendu des vidéos, il existe des commandes spécialisées pour l’accélération des vidéos. Pour donner quelques exemples, prenons les commandes 2D de la carte graphique AMD Radeon X1800. {|class="wikitable" |- ! Commandes 2D ! Fonction |- |PAINT |Peindre un rectangle d'une certaine couleur |- |PAINT_MULTI |Peindre des rectangles (pas les mêmes paramètres que PAINT) |- |BITBLT |Copie d'un bloc de mémoire dans un autre |- |BITBLT_MULTI |Plusieurs copies de blocs de mémoire dans d'autres |- |TRANS_BITBLT |Copie de blocs de mémoire avec un masque |- |NEXTCHAR |Afficher un caractère avec une certaine couleur |- |HOSTDATA_BLT |Écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo |- |POLYLINE |Afficher des lignes reliées entre elles |- |POLYSCANLINES |Afficher des lignes |- |PLY_NEXTSCAN |Afficher plusieurs lignes simples |- |SET_SCISSORS |Utiliser des coupes (ciseaux) |- |LOAD_PALETTE |Charger la palette pour affichage 2D |} ===Le tampon de commandes=== L'envoi des commandes à la carte graphique ne se fait pas directement. La carte graphique n'est pas toujours libre pour accepter une nouvelle commande, soit parce qu'elle est occupée par une commande précédente, soit parce qu'elle fait autre chose. Il faut alors faire patienter les données tant que la carte graphique est occupée. Les pilotes de la carte graphique vont les mettre en attente dans le '''tampon de commandes'''. Le tampon de commandes est ce qu'on appelle une file, une zone de mémoire dans laquelle on stocke des données dans l'ordre d'ajout. Si le tampon de commandes est plein, le driver n'accepte plus de demandes en provenance des applications. Un tampon de commandes plein est généralement mauvais signe : cela signifie que la carte graphique est trop lente pour traiter les demandes qui lui sont faites. Par contre, il arrive que le tampon de commandes soit vide : dans ce cas, c'est simplement que la carte graphique est trop rapide comparé au processeur, qui n'arrive alors pas à donner assez de commandes à la carte graphique pour l'occuper suffisamment. Le tampon de commande est soit une mémoire FIFO séparée, soit une portion de la mémoire vidéo. Le NV1, la toute première carte graphique NVIDIA, utilisait une mémoire FIFO intégrée à la carte graphique, séparée des autres circuits. Le NV1 contenait dans le détail : un controleur DMA avec une IO-MMU intégrée, la FIFO de commande, le processeur de commande, un pipeline graphique, un pipeline sonore, un contrôleur de manette. L'ensemble était relié par un bus interne à la carte graphique. Le processeur envoyait les commandes par rafale au GPU, à savoir qu'il envoyait plusieurs dizaines ou centaines de commandes à la suite, avant de passer à autre chose. Le GPU traitait les commandes une par une, à un rythme bien plus lent. Le processeur pouvait consulter la FIFO pour savoir s'il restait des entrées libres et combien. Le processeur savait ainsi combien d'écritures il pouvait envoyer en une fois au GPU. : Le fonctionnement de la FIFO du NV1 est décrit dans le brevet ''US5805930A : System for FIFO informing the availability of stages to store commands which include data and virtual address sent directly from application programs''. ===Le processeur de commandes=== Le '''processeur de commande''' est un circuit qui gère les commandes envoyées par le processeur. Il lit la commande la plus ancienne dans le tampon de commande, l’interprète et l’exécute, puis passe à la suivante. Le processeur de commande est un circuit assez compliqué. Sur les cartes graphiques anciennes, c'était un circuit séquentiel complexe, fabriqué à la main et était la partie la plus complexe du processeur graphique. Sur les cartes graphiques modernes, c'est un véritable microcontrôleur, avec un processeur, de la mémoire RAM, etc. Le processeur de commandes lit une commande dans le tampon de commande, décode la commande et l’exécute sur la carte graphique. Il garde en mémoire l'état de traitement de chaque commande : est-ce qu'elle est en train de s’exécuter sur le processeur graphique, est-ce qu'elle est mise en pause, est-ce qu'elle attend une donnée en provenance de la mémoire, est-ce qu'elle est terminée, etc. Une commande utilise divers circuits de la carte 3D, de la mémoire vidéo, et d'autres ressources au sens large (des processeurs de ''shader'', notamment). Aussi, le processeur de commande pilote les circuits de la carte graphique, il répartit le travail entre les différents circuits de la carte graphique et assure que l'ordre du pipeline est respecté. La fonction principale du processeur de commande est de répartir le travail entre les différents circuits. Le processeur de commande décide à quel processeur ou circuit doit être envoyé une commande. C'est le processeur de commande qui s'occupe de la gestion des ressources et qui attribue telle ressource à telle commande. A chaque instant, le processeur de commande répartit les ''shaders'' sur les processeurs de ''shaders'', en faisant en sorte qu'ils soient utilisés le plus possible. Dans le cas le plus simple, les unités sont alimentées en vertex/pixels les unes après les autres (principe du round-robin), mais des stratégies plus optimisées sont la règle de nos jours. Cela est très important sur les cartes graphiques : répartir plusieurs commandes sur plusieurs processeurs est une tâche difficile. Un chapitre entier sera d'ailleurs dédié à ce sujet. Il envoie aussi certaines commandes aux circuits fixes, comme l’''input assembler''. Là encore, il faut en sorte que les circuits fixes soient utilisés le mieux possible. Sa tâche est compliquée par le fait que les GPU récents ont plusieurs unités de traitement des sommets et des pixels, plusieurs ROP, plusieurs unités de textures, etc. Et c'est en partie le travail du processeur de commande que de répartir les calculs sur ces différentes unités. C'est là un problème assez compliqué pour le processeur de commande et ce pour tout un tas de raisons que nous ne ferons que survoler. Les contraintes d'ordonnancement de l'API et les règles de celle-ci sont une partie de la réponse. Mais d'autres raisons sont intrinsèques au rendu 3D ou à la conception des circuits. [[File:Architecture de base d'une carte 3D - 1.png|centre|vignette|upright=2.5|Architecture de base d'une carte 3D - 1]] ==Le fonctionnement du processeur de commandes== Le processeur de commande lit, décode et exécute des commandes. Intuitivement, on se dit qu'il procède une commande à la fois. Mais les GPU modernes sont plus intelligents et peuvent exécuter plusieurs commandes en même temps, dans des circuits séparés. De nombreuses optimisations de ce type sont utilisées pour gagner en performance. Voyons comment un processeur de commande moderne fonctionne. ===L'ordonnancement et la gestion des ressources=== Le processeur de commande doit souvent mettre en pause certains circuits du pipeline, ainsi que les circuits précédents. Par exemple, si tous les processeurs de ''vertex shader'' sont occupés, l’''input assembler'' ne peut pas charger le paquet suivant car il n'y a aucun processeur de libre pour l’accueillir. Dans ce cas, l'étape d’''input assembly'' est mise en pause en attendant qu'un processeur de ''shader'' soit libre. La même chose a lieu pour l'étape de rastérisation : si aucun processeur de ''shader'' n'est libre, elle est mise en pause. Sauf que pour la rastérisation, cela a des conséquences sur les circuits précédents la rastérisation. Si un processeur de ''shader'' veut envoyer quelque chose au rastériseur alors qu'il est en pause, il devra lui aussi attendre que le rastériseur soit libre. On a la même chose quand les ROP sont occupés : les ''pixel shader'' ou l'unité de texture doivent parfois être mis en pause, ce qui peut entrainer la mise en pause des étapes précédentes, etc. En clair : plus un étape est situé vers la fin du pipeline graphique, plus sa mise en pause a de chances de se répercuter sur les étapes précédentes et de les mettre en pause aussi. Le processeur de commande doit gérer ces situations. ===Le pipelining des commandes=== Dans les cartes graphiques les plus rudimentaires, le processeur de commande exécute les commandes dans l'ordre. Il exécute une commande çà la fois et attend qu'une commande soit terminé pour en lancer une autre. Plusieurs commandes sont accumulées dans le tampon de commande, le processeur de commande les traite de la plus ancienne vers la plus récente. Du moins, les anciennes cartes graphiques faisaient comme cela, les cartes graphiques modernes sont un peu plus complexes. Elles n'attendent pas qu'une commande soit totalement terminée avant d'en lancer une nouvelle. Les processeurs de commande actuels sont capables d’exécuter plusieurs commandes en même temps. L'intérêt est un gain en performance assez important. Pour ceux qui ont déjà eu un cours d'architecture des ordinateurs avancé, lancer plusieurs commandes en même temps permet une forme de pipeline, dont les gains sont substantiels. Par exemple, imaginez qu'une commande de rendu 3D soit bien avancée et n'utilise que les processeurs de ''shaders'' et les ROP, mais laisse les unités géométriques libres. Il est alors possible de démarrer la commande suivante en avance, afin qu'elle remplisse les unités géométriques inutilisées. On a alors deux commandes en cours de traitement : une commande qui utilise la fin du pipeline uniquement, une autre qui utilise seulement le début du pipeline graphique. Le processeur de commande gère donc plusieurs commandes simultanées, à savoir plusieurs commandes qui en sont à des étapes différentes du pipeline. On peut avoir une commande qui est en cours dans l'étage de gestion de la géométrie, une autre dans le rastériseur, et une autre dans les unités de traitement des pixels. Le fait que les étapes du pipeline graphique sont à effectuer dans un ordre bien précis permet ce genre de chose assez facilement. Une autre possibilité est de faire des rendus en parallèle. Par exemple, imaginez qu'on ait des circuits séparés pour le rendu 2D et 3D. Prenons l'exemple où le calcul d'une image finale demande de faire un rendu 3D suivi d'un rendu 2D, par exemple un jeu vidéo en 3D qui a un HUD dessiné en 2D. Dans ce cas, on peut démarrer le calcul de l'image suivante dans le pipeline 3D pendant que la précédente est dans les circuits 2D, au lieu de laisser inutilisé le pipeline 3D pendant le rendu 2D. Mais c'est là un défi compliqué à relever pour le processeur de commande, qui donne lieu à son lot de problèmes. Le problème principal est le partage de ressources entre commandes. Par exemple, on peut prendre le cas où une commande n'utilise pas beaucoup les processeurs de ''shaders''. On pourrait imaginer lancer une seconde commande en parallèle, afin que la seconde commande utiliser les processeurs de ''shaders'' inutilisés. Mais cela n'est possible que si les circuits fixes sont capables d'accepter une seconde commande. Si la première commande sature les circuits fixe, le lancement de la seconde commande sera empêché. Mais si ce n'est pas le cas, les deux commandes pourront être lancées en même temps. Pareil pour le débit mémoire, qui doit alors être partagé entre deux commandes simultanées, ce qui est à prendre en compte. ===La synchronisation de l’exécution des commandes avec le processeur=== Il arrive que le processeur doive savoir où en est le traitement des commandes, ce qui est très utile pour la gestion de la mémoire vidéo. Un premier exemple : comment éviter de saturer une carte graphique de commande, alors qu'on ne sait pas si elles traite les commandes rapidement ou non ? L'idéal est de regarder où en est la carte graphique dans l'exécution des commandes. Si elle n'en est qu'au début du tampon de commande et que celui-ci est bien remplit, alors il vaut mieux lever le pied et ne pas envoyer de nouvelles commandes. A l'inverse, si le tampon de commande est presque vide, envoyer des commandes est la meilleure idée possible. Un autre exemple un peu moins parlant est celui de la gestion de la mémoire vidéo. Rappelons qu'elle est réalisée par le pilote de la carte graphique, sur le processeur principal, qui décide d'allouer et de libérer de la mémoire vidéo. Pour donner un exemple d'utilisation, imaginez que le pilote de la carte graphique doive libérer de la mémoire pour pouvoir ajouter une nouvelle commande. Comment éviter d'enlever une texture tant que les commandes qui l'utilisent ne sont pas terminées ? Ce problème ne se limite pas aux textures, mais vaut pour tout ce qui est placé en mémoire vidéo. Il faut donc que la carte graphique trouve un moyen de prévenir le processeur que le traitement de telle commande est terminée, que telle commande en est rendue à tel ou tel point, etc. Pour cela, on a globalement deux grandes solutions. La première est celle des interruptions, abordées dans les chapitres précédents. Mais elles sont assez couteuses et ne sont utilisées que pour des évènements vraiment importants, critiques, qui demandent une réaction rapide du processeur. L'autre solution est celle du ''pooling'', où le processeur monitore la carte graphique à intervalles réguliers. Deux solutions bien connues de ceux qui ont déjà lu un cours d'architecture des ordinateurs digne de ce nom, rien de bien neuf : la carte graphique communique avec le processeur comme tout périphérique. Pour faciliter l'implémentation du ''pooling'', la carte graphique contient des registres de statut, dans le processeur de commande, qui mémorisent tout ou partie de l'état de la carte graphique. Si un problème survient, certains bits du registre de statut seront mis à 1 pour indiquer que telle erreur bien précise a eu lieu. Il existe aussi un registre de statut qui mémorise le numéro de la commande en cours, ou de la dernière commande terminée, ce qui permet de savoir où en est la carte graphique dans l'exécution des commandes. Et certaines registres de statut sont dédiés à la gestion des commandes. Ils sont totalement programmable, la carte graphique peut écrire dedans sans problème. Les cartes graphiques récentes incorporent des commandes pour modifier ces registres de statut au besoin. Elles sont appelées des '''commandes de synchronisation''' : les barrières (''fences''). Elles permettent d'écrire une valeur dans un registre de statut quand telle ou telle condition est remplie. Par exemple, si jamais une commande est terminée, on peut écrire la valeur 1 dans tel ou tel registre. La condition en question peut être assez complexe et se résumer à quelque chose du genre : "si jamais toutes les ''shaders'' ont fini de traiter tel ensemble de textures, alors écrit la valeur 1024 dans le registre de statut numéro 9". ===La synchronisation de l’exécution des commandes intra-GPU=== Lancer plusieurs commandes en parallèle dans le pipeline permet de gagner en performance.Mais cela a un gros défaut : il n'est pas garantit que les commandes se terminent dans l'ordre. Si on démarre une seconde commande après la première, il arrive que la seconde finisse avant. Pire : il n'est pas garantit qu'elles s'exécutent dans l'ordre. Dans la plupart des cas, cela ne pose pas de problèmes. Mais dans d'autres, cela donne des résultats erronés. Pour donner un exemple, utilisons les commandes de rendu 2D vues plus haut, histoire de simplifier le tout. Imaginez que vous codez un jeu vidéo et que le rendu se fait en 2D, partons sur un jeu de type FPS. Vous avez une série de commandes pour calculer l'image à rendre à l'écran, suivie par une série de commandes finales pour dessiner le HUB. Pour dessiner le HUD, vous utilisez des commandes HOSTDATA_BLT, dont le but est d'écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo. Et bien ces commandes HOSTDATA_BLT doivent démarrer une fois que le rendu de l'image est complétement terminé. Imaginez que vous dessiniez le HUD sur une portion de l'image pas encore terminée et que celui-ci est effacé par des écritures ultérieures ! Pour éviter tout problème, les GPU incorporent des commandes de synchronisation intra-GPU, destinées au processeur de commande, aussis appelées des '''commandes de sémaphore'''. Elles permettent de mettre en pause le lancement d'une nouvelle commande tant que les précédentes ne sont pas totalement ou partiellement terminées. Les plus simples empêchent le démarrage d'une commande tant que les précédentes ne sont pas terminées. D'autres permettent de démarrer une commande si et seulement si certaines commandes sont terminées. D'autres sont encore plus précises : elles empêchent le démarrage d'une nouvelle commande tant qu'une commande précédente n'a pas atteint un certain stade de son exécution. Là encore, de telles commandes sont des commandes du style "attend que le registre de statut numéro N contienne la valeur adéquate avant de poursuivre l'exécution des commandes". Les commandes en question peuvent être sur le même modèle que précédemment, à savoir des commandes qui lisent les registres de statut. Mais elles peuvent aussi se baser sur le fait que telle ou telle ressource de rendu est libre ou non. Des commandes successives se partagent souvent des données, et que de nombreuses commandes différentes peuvent s'exécuter en même temps. Or, si une commande veut modifier les données utilisées par une autre commande, il faut que l'ordre des commandes soit maintenu : la commande la plus récente ne doit pas modifier les données utilisées par une commande plus ancienne. Avec ce modèle, les sémaphores bloquent une commande tant qu'une ressource (une texture) est utilisée par une autre commande. {|class="wikitable" |- ! Commandes de synchronisation ! Fonction |- |NOP |Ne rien faire |- |WAIT_SEMAPHORE |Attendre la synchronisation avec un sémaphore |- |WAIT_MEM |Attendre que la mémoire vidéo soit disponible et inoccupée par le CPU |} ==L'arbitrage de l'accès à la carte graphique== Il n'est pas rare que plusieurs applications souhaitent accéder en même temps à la carte graphique. Imaginons que vous regardez une vidéo en ''streaming'' sur votre navigateur web, avec un programme de ''cloud computing'' de type ''Folding@Home'' qui tourne en arrière-plan, sur Windows. Le décodage de la vidéo est réalisé par la carte graphique, Windows s'occupe de l'affichage du bureau et des fenêtres, le navigateur web doit afficher tout ce qui est autour de la vidéo (la page web), le programme de ''cloud computing'' va lancer ses calculs sur la carte graphique, etc. Des situations de ce genre sont assez courantes et c'est soit le pilote qui s'en charge, soit la carte graphique elle-même. ===L'arbitrage logiciel du GPU=== L'arbitrage logiciel est la méthode la plus simple. Concrètement, c'est le système d'exploitation et/ou le pilote de la carte graphique qui gèrent l'arbitrage du GPU. Dans les deux cas, tout est fait en logiciel. Les commandes sont accumulées dans un tampon de commande, voire plusieurs, et l'OS/pilote décide quelle commande envoyer en priorité. Sur Windows, avant l'arrivée du modèle de driver dit ''Windows Display Driver Model'', de telles situations étaient gérées simplement. Les applications ajoutaient des commandes dans une file de commande unique. Les commandes étaient exécutées dans l'ordre, en mode premier entrée dans la file premier sorti/exécuté. Il n'y avait pour ainsi dire pas d'arbitrage entre les applications. Et ce n'était pas un problème car, à l'époque, les seules applications qui utilisaient le GPU étaient des jeux vidéos fonctionnant en mode plein écran. Avec le modèle de driver ''Windows Display Driver Model'' (WDDM), le GPU est maintenant arbitré, à savoir que les applications ont accès à tour de rôle au GPU, certaines ayant droit à plus de temps GPU que d'autres. Chaque programme a accès à la carte graphique durant quelques dizaines ou centaines de millisecondes, à tour de rôle. Si le programme finissait son travail en moins de temps que la durée impartie, il laissait la main au programme suivant. S’il atteignait la durée maximale allouée, il était interrompu pour laisser la place au programme suivant. Et chaque programme avait droit d'accès à la carte graphique chacun à son tour. Un tel algorithme en tourniquet est très simple, mais avait cependant quelques défauts. De nos jours, les algorithmes d'ordonnancement d'accès sont plus élaborés, bien qu'il soit difficile de trouver de la littérature ou des brevets sur le sujet. Une autre fonctionnalité de WDDM est que les applications utilisant le GPU peuvent se partager la mémoire vidéo sans se marcher dessus. Avant, toutes les applications avaient accès à toute la mémoire vidéo, bien que ce soit par l’intermédiaire de commandes spécifiques. Mais avec WDDM, chaque application dispose de sa propre portion de mémoire vidéo, à laquelle est la seule à avoir accès. Une application ne peut plus lire le contenu réel de la mémoire vidéo, et encore moins lire le contenu des autres applications. : Il s'agit d'un équivalent à l'isolation des processus pour les programmes Windows, mais appliqué à la mémoire vidéo et non la mémoire système. Et cette isolation est rendue d'autant plus simple que les GPU modernes implémentent un système de mémoire virtuelle à pagination très poussé, avec du swap en mémoire RAM système, une protection mémoire, et bien d'autres fonctionnalités. Nous en reparlerons dans les chapitres sur la mémoire vidéo. ===L'arbitrage accéléré par le GPU=== Depuis 2020, avec l'arrivée de la ''Windows 10 May 2020 update'', Windows est capable de déléguer l'arbitrage du GPU au GPU lui-même. Le GPU gère lui-même l'arbitrage, du moins en partie. En partie, car l'OS gére les priorité, à savoir quelle application a droit à plus de temps que les autres. Par contre, la gestion du ''quantum'' de temps ou les commutations de contexte (on stoppe une application pour laisser la place à une autre), est du fait du GPU lui-même. L'avantage est que cela décharge le processeur d'une tâche assez lourde en calcul, pour la déporter sur le GPU. Un autre avantage est que le GPU peut gérer plus finement les ''quantum'' de temps et la commutation de contexte. Le CPU principal gère des durées assez importantes, de l'ordre de la milliseconde. De plus, il doit communiquer avec le GPU par des mécanismes temporellement imprécis, comme des interruptions. Avec l'arbitrage accéléré par le GPU, le GPU n'a plus besoin de communiquer avec le CPU pour l'arbitrage et peut le faire plus précisément, plus immédiatement. Un gain en performance théorique est donc possible. L'arbitrage accéléré par le GPU est le fait soit du processeur de commandes, soit d'un processeur spécialisé, séparé. {{NavChapitre | book=Les cartes graphiques | prev=La hiérarchie mémoire d'un GPU | prevText=La hiérarchie mémoire d'un GPU | next=Le pipeline géométrique d'avant DirectX 10 | netxText=Le pipeline géométrique d'avant DirectX 10 }}{{autocat}} d36a6dam6qp7nmj2mdks0wbyxdxeo8v 744036 744035 2025-06-03T13:54:49Z Mewtow 31375 /* Le tampon de commandes */ 744036 wikitext text/x-wiki Dans ce chapitre, nous allons parler de tous les intermédiaires qui se placent entre une application de rendu 3D et les circuits de rendu 3D proprement dit. En premier lieu, on trouve le pilote de la carte graphique, aux fonctions multiples et variées. En second lieu, nous allons parler d'un circuit de la carte graphique qui fait l'interface entre le logiciel et les circuits de rendu 3D de la carte graphique : le processeur de commandes. Ce processeur de commandes est un circuit qui sert de chef d'orchestre, qui pilote le fonctionnement global de la carte graphique. API 3D, pilote de carte graphique et processeur de commande travaillent de concert pour que l'application communique avec la carte graphique. Nous allons d'abord voir le pilote de la carte graphique, avant de voir le fonctionnement du processeur de commande. ==Le pilote de carte graphique== Le pilote de la carte graphique est un logiciel qui s'occupe de faire l'interface entre le logiciel et la carte graphique. De manière générale, les pilotes de périphérique sont des intermédiaires entre les applications/APIs et le matériel. En théorie, le système d'exploitation est censé jouer ce rôle, mais il n'est pas programmé pour être compatible avec tous les périphériques vendus sur le marché. À la place, le système d'exploitation ne gère pas directement certains périphériques, mais fournit de quoi ajouter ce qui manque. Le pilote d'un périphérique sert justement à ajouter ce qui manque : ils ajoutent au système d'exploitation de quoi reconnaître le périphérique, de quoi l'utiliser au mieux. Pour une carte graphique, il a diverses fonctions que nous allons voir ci-dessous. Avant toute chose, précisons que les systèmes d'exploitation usuels (Windows, Linux, MacOsX et autres) sont fournis avec un pilote de carte graphique générique, compatible avec la plupart des cartes graphiques existantes. Rien de magique derrière cela : toutes les cartes graphiques vendues depuis plusieurs décennies respectent des standards, comme le VGA, le VESA, et d'autres. Et le pilote de base fournit avec le système d'exploitation est justement compatible avec ces standards minimaux. Mais le pilote ne peut pas profiter des fonctionnalités qui sont au-delà de ce standard. L'accélération 3D est presque inexistante avec le pilote de base, qui ne sert qu'à faire du rendu 2D (de quoi afficher l’interface de base du système d'exploitation, comme le bureau de Windows). Et même pour du rendu 2D, la plupart des fonctionnalités de la carte graphique ne sont pas disponibles. Par exemple, certaines résolutions ne sont pas disponibles, notamment les grandes résolutions. Ou encore, les performances sont loin d'être excellentes. Si vous avez déjà utilisé un PC sans pilote de carte graphique installé, vous avez certainement remarqué qu'il était particulièrement lent. ===La gestion des interruptions=== Une fonction particulièrement importante du pilote de carte graphique est la réponse aux interruptions lancées par la carte graphique. Pour rappel, les interruptions sont une fonctionnalité qui permet à un périphérique de communiquer avec le processeur, tout en économisant le temps de calcul de ce dernier. Typiquement, lorsqu'un périphérique lance une interruption, le processeur stoppe son travail et exécute automatiquement une routine d'interruption, un petit programme qui s'occupe de gérer le périphérique, de faire ce qu'il faut, ce que l'interruption a demandé. Il y a plusieurs interruptions possibles, chacune ayant son propre numéro et sa fonction dédiée, chacune ayant sa propre routine d'interruption. Après tout, la routine qui gère un débordement de la mémoire vidéo n'est pas la même que celle qui gère un changement de fréquence du GPU ou la fin du calcul d'une image 3D. Le pilote fournit l'ensemble des routines d'interruptions nécessaires pour gérer la carte graphique. ===La compilation des ''shaders''=== Le pilote de carte graphique est aussi chargé de traduire les ''shaders'' en code machine. En soi, cette étape est assez complexe, et ressemble beaucoup à la compilation d'un programme informatique normal. Les ''shaders'' sont écrits dans un langage de programmation de haut niveau, comme le HLSL ou le GLSL, mais ce n'est pas ce code source qui est compilé par le pilote de carte graphique. À la place, les ''shaders'' sont pré-compilés vers un langage dit intermédiaire, avant d'être compilé par le pilote en code machine. Le langage intermédiaire, comme son nom l'indique, sert d'intermédiaire entre le code source écrit en HLSL/GLSL et le code machine exécuté par la carte graphique. Il ressemble à un langage assembleur, mais reste malgré tout assez générique pour ne pas être un véritable code machine. Par exemple, il y a peu de limitations quant au nombre de processeurs ou de registres. En clair, il y a deux passes de compilation : une passe de traduction du code source en langage intermédiaire, puis une passe de compilation du code intermédiaire vers le code machine. Notons que la première passe est réalisée par le programmeur des ''shaders'', non pas par l'utilisateur. Par exemple, les ''shaders'' d'un jeu vidéo sont fournis déjà pré-compilés : les fichiers du jeu ne contiennent pas le code source GLSL/HLSL, mais du code intermédiaire. L'avantage de cette méthode est que le travail du pilote est fortement simplifié. Le pilote de périphérique pourrait compiler directement du code HLSL/GLSL, mais le temps de compilation serait très long et cela aurait un impact sur les performances. Avec l'usage du langage intermédiaire, le gros du travail à été fait lors de la première passe de compilation et le pilote graphique ne fait que finir le travail. Les optimisations importantes ont déjà été réalisées lors de la première passe. Il doit bien faire la traduction, ajouter quelques optimisations de bas niveau par-ci par-là, mais rien de bien gourmand en processeur. Autant dire que cela économise plus le processeur que si on devait compiler complètement les ''shaders'' à chaque exécution. Fait amusant, il faut savoir que le pilote peut parfois remplacer les ''shaders'' d'un jeu vidéo à la volée. Les pilotes récents embarquent en effet des ''shaders'' alternatifs pour les jeux les plus vendus et/ou les plus populaires. Lorsque vous lancez un de ces jeux vidéo et que le ''shader'' originel s'exécute, le pilote le détecte automatiquement et le remplace par la version améliorée, fournie par le pilote. Évidemment, le ''shader'' alternatif du pilote est optimisé pour le matériel adéquat. Cela permet de gagner en performance, voire en qualité d'image, sans pour autant que les concepteurs du jeu n'aient quoique ce soit à faire. Enfin, certains ''shaders'' sont fournis par le pilote pour d'autres raisons. Par exemple, les cartes graphiques récentes n'ont pas de circuits fixes pour traiter la géométrie. Autant les anciennes cartes graphiques avaient des circuits de T&L qui s'en occupaient, autant tout cela doit être émulé sur les machines récentes. Sans cette émulation, les vieux jeux vidéo conçus pour exploiter le T&L et d'autres technologies du genre ne fonctionneraient plus du tout. Émuler les circuits fixes disparus sur les cartes récentes est justement le fait de ''shaders'', présents dans le pilote de carte graphique. ===Les autres fonctions=== Le pilote a aussi bien d'autres fonctions. Par exemple, il s'occupe d'initialiser la carte graphique, de fixer la résolution, d'allouer la mémoire vidéo, de gérer le curseur de souris matériel, etc. ==Les commandes graphiques/vidéo/autres : des ordres envoyés au GPU== Tous les traitements que la carte graphique doit effectuer, qu'il s'agisse de rendu 2D, de calculs 2D, du décodage matérielle d'un flux vidéo, ou de calculs généralistes, sont envoyés par le pilote de la carte graphique, sous la forme de '''commandes'''. Ces commandes demandent à la carte graphique d'effectuer une opération 2D, ou une opération 3D, ou encore le rendu d'une vidéo. Les commandes graphiques en question varient beaucoup selon la carte graphique. Les commandes sont régulièrement revues et chaque nouvelle architecture a quelques changements par rapport aux modèles plus anciens. Des commandes peuvent apparaître, d'autres disparaître, d'autre voient leur fonctionnement légèrement altéré, etc. Mais dans les grandes lignes, on peut classer ces commandes en quelques grands types. Les commandes les plus importantes s'occupent de l'affichage 3D : afficher une image à partir de paquets de sommets, préparer le passage d'une image à une autre, changer la résolution, etc. Plus rare, d'autres commandes servent à faire du rendu 2D : afficher un polygone, tracer une ligne, coloriser une surface, etc. Sur les cartes graphiques qui peuvent accélérer le rendu des vidéos, il existe des commandes spécialisées pour l’accélération des vidéos. Pour donner quelques exemples, prenons les commandes 2D de la carte graphique AMD Radeon X1800. {|class="wikitable" |- ! Commandes 2D ! Fonction |- |PAINT |Peindre un rectangle d'une certaine couleur |- |PAINT_MULTI |Peindre des rectangles (pas les mêmes paramètres que PAINT) |- |BITBLT |Copie d'un bloc de mémoire dans un autre |- |BITBLT_MULTI |Plusieurs copies de blocs de mémoire dans d'autres |- |TRANS_BITBLT |Copie de blocs de mémoire avec un masque |- |NEXTCHAR |Afficher un caractère avec une certaine couleur |- |HOSTDATA_BLT |Écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo |- |POLYLINE |Afficher des lignes reliées entre elles |- |POLYSCANLINES |Afficher des lignes |- |PLY_NEXTSCAN |Afficher plusieurs lignes simples |- |SET_SCISSORS |Utiliser des coupes (ciseaux) |- |LOAD_PALETTE |Charger la palette pour affichage 2D |} ===Le tampon de commandes=== L'envoi des commandes à la carte graphique ne se fait pas directement. La carte graphique n'est pas toujours libre pour accepter une nouvelle commande, soit parce qu'elle est occupée par une commande précédente, soit parce qu'elle fait autre chose. Il faut alors faire patienter les données tant que la carte graphique est occupée. Les pilotes de la carte graphique vont les mettre en attente dans le '''tampon de commandes'''. Le tampon de commandes est ce qu'on appelle une file, une zone de mémoire dans laquelle on stocke des données dans l'ordre d'ajout. Si le tampon de commandes est plein, le driver n'accepte plus de demandes en provenance des applications. Un tampon de commandes plein est généralement mauvais signe : cela signifie que la carte graphique est trop lente pour traiter les demandes qui lui sont faites. Par contre, il arrive que le tampon de commandes soit vide : dans ce cas, c'est simplement que la carte graphique est trop rapide comparé au processeur, qui n'arrive alors pas à donner assez de commandes à la carte graphique pour l'occuper suffisamment. Le tampon de commande est soit une mémoire FIFO séparée, soit une portion de la mémoire vidéo. Le NV1, la toute première carte graphique NVIDIA, utilisait une mémoire FIFO intégrée à la carte graphique, séparée des autres circuits. Le processeur envoyait les commandes par rafale au GPU, à savoir qu'il envoyait plusieurs dizaines ou centaines de commandes à la suite, avant de passer à autre chose. Le GPU traitait les commandes une par une, à un rythme bien plus lent. Le processeur pouvait consulter la FIFO pour savoir s'il restait des entrées libres et combien. Le processeur savait ainsi combien d'écritures il pouvait envoyer en une fois au GPU. : Le fonctionnement de la FIFO du NV1 est décrit dans le brevet ''US5805930A : System for FIFO informing the availability of stages to store commands which include data and virtual address sent directly from application programs''. ===Le processeur de commandes=== Le '''processeur de commande''' est un circuit qui gère les commandes envoyées par le processeur. Il lit la commande la plus ancienne dans le tampon de commande, l’interprète et l’exécute, puis passe à la suivante. Le processeur de commande est un circuit assez compliqué. Sur les cartes graphiques anciennes, c'était un circuit séquentiel complexe, fabriqué à la main et était la partie la plus complexe du processeur graphique. Sur les cartes graphiques modernes, c'est un véritable microcontrôleur, avec un processeur, de la mémoire RAM, etc. Le processeur de commandes lit une commande dans le tampon de commande, décode la commande et l’exécute sur la carte graphique. Il garde en mémoire l'état de traitement de chaque commande : est-ce qu'elle est en train de s’exécuter sur le processeur graphique, est-ce qu'elle est mise en pause, est-ce qu'elle attend une donnée en provenance de la mémoire, est-ce qu'elle est terminée, etc. Une commande utilise divers circuits de la carte 3D, de la mémoire vidéo, et d'autres ressources au sens large (des processeurs de ''shader'', notamment). Aussi, le processeur de commande pilote les circuits de la carte graphique, il répartit le travail entre les différents circuits de la carte graphique et assure que l'ordre du pipeline est respecté. La fonction principale du processeur de commande est de répartir le travail entre les différents circuits. Le processeur de commande décide à quel processeur ou circuit doit être envoyé une commande. C'est le processeur de commande qui s'occupe de la gestion des ressources et qui attribue telle ressource à telle commande. A chaque instant, le processeur de commande répartit les ''shaders'' sur les processeurs de ''shaders'', en faisant en sorte qu'ils soient utilisés le plus possible. Dans le cas le plus simple, les unités sont alimentées en vertex/pixels les unes après les autres (principe du round-robin), mais des stratégies plus optimisées sont la règle de nos jours. Cela est très important sur les cartes graphiques : répartir plusieurs commandes sur plusieurs processeurs est une tâche difficile. Un chapitre entier sera d'ailleurs dédié à ce sujet. Il envoie aussi certaines commandes aux circuits fixes, comme l’''input assembler''. Là encore, il faut en sorte que les circuits fixes soient utilisés le mieux possible. Sa tâche est compliquée par le fait que les GPU récents ont plusieurs unités de traitement des sommets et des pixels, plusieurs ROP, plusieurs unités de textures, etc. Et c'est en partie le travail du processeur de commande que de répartir les calculs sur ces différentes unités. C'est là un problème assez compliqué pour le processeur de commande et ce pour tout un tas de raisons que nous ne ferons que survoler. Les contraintes d'ordonnancement de l'API et les règles de celle-ci sont une partie de la réponse. Mais d'autres raisons sont intrinsèques au rendu 3D ou à la conception des circuits. [[File:Architecture de base d'une carte 3D - 1.png|centre|vignette|upright=2.5|Architecture de base d'une carte 3D - 1]] ==Le fonctionnement du processeur de commandes== Le processeur de commande lit, décode et exécute des commandes. Intuitivement, on se dit qu'il procède une commande à la fois. Mais les GPU modernes sont plus intelligents et peuvent exécuter plusieurs commandes en même temps, dans des circuits séparés. De nombreuses optimisations de ce type sont utilisées pour gagner en performance. Voyons comment un processeur de commande moderne fonctionne. ===L'ordonnancement et la gestion des ressources=== Le processeur de commande doit souvent mettre en pause certains circuits du pipeline, ainsi que les circuits précédents. Par exemple, si tous les processeurs de ''vertex shader'' sont occupés, l’''input assembler'' ne peut pas charger le paquet suivant car il n'y a aucun processeur de libre pour l’accueillir. Dans ce cas, l'étape d’''input assembly'' est mise en pause en attendant qu'un processeur de ''shader'' soit libre. La même chose a lieu pour l'étape de rastérisation : si aucun processeur de ''shader'' n'est libre, elle est mise en pause. Sauf que pour la rastérisation, cela a des conséquences sur les circuits précédents la rastérisation. Si un processeur de ''shader'' veut envoyer quelque chose au rastériseur alors qu'il est en pause, il devra lui aussi attendre que le rastériseur soit libre. On a la même chose quand les ROP sont occupés : les ''pixel shader'' ou l'unité de texture doivent parfois être mis en pause, ce qui peut entrainer la mise en pause des étapes précédentes, etc. En clair : plus un étape est situé vers la fin du pipeline graphique, plus sa mise en pause a de chances de se répercuter sur les étapes précédentes et de les mettre en pause aussi. Le processeur de commande doit gérer ces situations. ===Le pipelining des commandes=== Dans les cartes graphiques les plus rudimentaires, le processeur de commande exécute les commandes dans l'ordre. Il exécute une commande çà la fois et attend qu'une commande soit terminé pour en lancer une autre. Plusieurs commandes sont accumulées dans le tampon de commande, le processeur de commande les traite de la plus ancienne vers la plus récente. Du moins, les anciennes cartes graphiques faisaient comme cela, les cartes graphiques modernes sont un peu plus complexes. Elles n'attendent pas qu'une commande soit totalement terminée avant d'en lancer une nouvelle. Les processeurs de commande actuels sont capables d’exécuter plusieurs commandes en même temps. L'intérêt est un gain en performance assez important. Pour ceux qui ont déjà eu un cours d'architecture des ordinateurs avancé, lancer plusieurs commandes en même temps permet une forme de pipeline, dont les gains sont substantiels. Par exemple, imaginez qu'une commande de rendu 3D soit bien avancée et n'utilise que les processeurs de ''shaders'' et les ROP, mais laisse les unités géométriques libres. Il est alors possible de démarrer la commande suivante en avance, afin qu'elle remplisse les unités géométriques inutilisées. On a alors deux commandes en cours de traitement : une commande qui utilise la fin du pipeline uniquement, une autre qui utilise seulement le début du pipeline graphique. Le processeur de commande gère donc plusieurs commandes simultanées, à savoir plusieurs commandes qui en sont à des étapes différentes du pipeline. On peut avoir une commande qui est en cours dans l'étage de gestion de la géométrie, une autre dans le rastériseur, et une autre dans les unités de traitement des pixels. Le fait que les étapes du pipeline graphique sont à effectuer dans un ordre bien précis permet ce genre de chose assez facilement. Une autre possibilité est de faire des rendus en parallèle. Par exemple, imaginez qu'on ait des circuits séparés pour le rendu 2D et 3D. Prenons l'exemple où le calcul d'une image finale demande de faire un rendu 3D suivi d'un rendu 2D, par exemple un jeu vidéo en 3D qui a un HUD dessiné en 2D. Dans ce cas, on peut démarrer le calcul de l'image suivante dans le pipeline 3D pendant que la précédente est dans les circuits 2D, au lieu de laisser inutilisé le pipeline 3D pendant le rendu 2D. Mais c'est là un défi compliqué à relever pour le processeur de commande, qui donne lieu à son lot de problèmes. Le problème principal est le partage de ressources entre commandes. Par exemple, on peut prendre le cas où une commande n'utilise pas beaucoup les processeurs de ''shaders''. On pourrait imaginer lancer une seconde commande en parallèle, afin que la seconde commande utiliser les processeurs de ''shaders'' inutilisés. Mais cela n'est possible que si les circuits fixes sont capables d'accepter une seconde commande. Si la première commande sature les circuits fixe, le lancement de la seconde commande sera empêché. Mais si ce n'est pas le cas, les deux commandes pourront être lancées en même temps. Pareil pour le débit mémoire, qui doit alors être partagé entre deux commandes simultanées, ce qui est à prendre en compte. ===La synchronisation de l’exécution des commandes avec le processeur=== Il arrive que le processeur doive savoir où en est le traitement des commandes, ce qui est très utile pour la gestion de la mémoire vidéo. Un premier exemple : comment éviter de saturer une carte graphique de commande, alors qu'on ne sait pas si elles traite les commandes rapidement ou non ? L'idéal est de regarder où en est la carte graphique dans l'exécution des commandes. Si elle n'en est qu'au début du tampon de commande et que celui-ci est bien remplit, alors il vaut mieux lever le pied et ne pas envoyer de nouvelles commandes. A l'inverse, si le tampon de commande est presque vide, envoyer des commandes est la meilleure idée possible. Un autre exemple un peu moins parlant est celui de la gestion de la mémoire vidéo. Rappelons qu'elle est réalisée par le pilote de la carte graphique, sur le processeur principal, qui décide d'allouer et de libérer de la mémoire vidéo. Pour donner un exemple d'utilisation, imaginez que le pilote de la carte graphique doive libérer de la mémoire pour pouvoir ajouter une nouvelle commande. Comment éviter d'enlever une texture tant que les commandes qui l'utilisent ne sont pas terminées ? Ce problème ne se limite pas aux textures, mais vaut pour tout ce qui est placé en mémoire vidéo. Il faut donc que la carte graphique trouve un moyen de prévenir le processeur que le traitement de telle commande est terminée, que telle commande en est rendue à tel ou tel point, etc. Pour cela, on a globalement deux grandes solutions. La première est celle des interruptions, abordées dans les chapitres précédents. Mais elles sont assez couteuses et ne sont utilisées que pour des évènements vraiment importants, critiques, qui demandent une réaction rapide du processeur. L'autre solution est celle du ''pooling'', où le processeur monitore la carte graphique à intervalles réguliers. Deux solutions bien connues de ceux qui ont déjà lu un cours d'architecture des ordinateurs digne de ce nom, rien de bien neuf : la carte graphique communique avec le processeur comme tout périphérique. Pour faciliter l'implémentation du ''pooling'', la carte graphique contient des registres de statut, dans le processeur de commande, qui mémorisent tout ou partie de l'état de la carte graphique. Si un problème survient, certains bits du registre de statut seront mis à 1 pour indiquer que telle erreur bien précise a eu lieu. Il existe aussi un registre de statut qui mémorise le numéro de la commande en cours, ou de la dernière commande terminée, ce qui permet de savoir où en est la carte graphique dans l'exécution des commandes. Et certaines registres de statut sont dédiés à la gestion des commandes. Ils sont totalement programmable, la carte graphique peut écrire dedans sans problème. Les cartes graphiques récentes incorporent des commandes pour modifier ces registres de statut au besoin. Elles sont appelées des '''commandes de synchronisation''' : les barrières (''fences''). Elles permettent d'écrire une valeur dans un registre de statut quand telle ou telle condition est remplie. Par exemple, si jamais une commande est terminée, on peut écrire la valeur 1 dans tel ou tel registre. La condition en question peut être assez complexe et se résumer à quelque chose du genre : "si jamais toutes les ''shaders'' ont fini de traiter tel ensemble de textures, alors écrit la valeur 1024 dans le registre de statut numéro 9". ===La synchronisation de l’exécution des commandes intra-GPU=== Lancer plusieurs commandes en parallèle dans le pipeline permet de gagner en performance.Mais cela a un gros défaut : il n'est pas garantit que les commandes se terminent dans l'ordre. Si on démarre une seconde commande après la première, il arrive que la seconde finisse avant. Pire : il n'est pas garantit qu'elles s'exécutent dans l'ordre. Dans la plupart des cas, cela ne pose pas de problèmes. Mais dans d'autres, cela donne des résultats erronés. Pour donner un exemple, utilisons les commandes de rendu 2D vues plus haut, histoire de simplifier le tout. Imaginez que vous codez un jeu vidéo et que le rendu se fait en 2D, partons sur un jeu de type FPS. Vous avez une série de commandes pour calculer l'image à rendre à l'écran, suivie par une série de commandes finales pour dessiner le HUB. Pour dessiner le HUD, vous utilisez des commandes HOSTDATA_BLT, dont le but est d'écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo. Et bien ces commandes HOSTDATA_BLT doivent démarrer une fois que le rendu de l'image est complétement terminé. Imaginez que vous dessiniez le HUD sur une portion de l'image pas encore terminée et que celui-ci est effacé par des écritures ultérieures ! Pour éviter tout problème, les GPU incorporent des commandes de synchronisation intra-GPU, destinées au processeur de commande, aussis appelées des '''commandes de sémaphore'''. Elles permettent de mettre en pause le lancement d'une nouvelle commande tant que les précédentes ne sont pas totalement ou partiellement terminées. Les plus simples empêchent le démarrage d'une commande tant que les précédentes ne sont pas terminées. D'autres permettent de démarrer une commande si et seulement si certaines commandes sont terminées. D'autres sont encore plus précises : elles empêchent le démarrage d'une nouvelle commande tant qu'une commande précédente n'a pas atteint un certain stade de son exécution. Là encore, de telles commandes sont des commandes du style "attend que le registre de statut numéro N contienne la valeur adéquate avant de poursuivre l'exécution des commandes". Les commandes en question peuvent être sur le même modèle que précédemment, à savoir des commandes qui lisent les registres de statut. Mais elles peuvent aussi se baser sur le fait que telle ou telle ressource de rendu est libre ou non. Des commandes successives se partagent souvent des données, et que de nombreuses commandes différentes peuvent s'exécuter en même temps. Or, si une commande veut modifier les données utilisées par une autre commande, il faut que l'ordre des commandes soit maintenu : la commande la plus récente ne doit pas modifier les données utilisées par une commande plus ancienne. Avec ce modèle, les sémaphores bloquent une commande tant qu'une ressource (une texture) est utilisée par une autre commande. {|class="wikitable" |- ! Commandes de synchronisation ! Fonction |- |NOP |Ne rien faire |- |WAIT_SEMAPHORE |Attendre la synchronisation avec un sémaphore |- |WAIT_MEM |Attendre que la mémoire vidéo soit disponible et inoccupée par le CPU |} ==L'arbitrage de l'accès à la carte graphique== Il n'est pas rare que plusieurs applications souhaitent accéder en même temps à la carte graphique. Imaginons que vous regardez une vidéo en ''streaming'' sur votre navigateur web, avec un programme de ''cloud computing'' de type ''Folding@Home'' qui tourne en arrière-plan, sur Windows. Le décodage de la vidéo est réalisé par la carte graphique, Windows s'occupe de l'affichage du bureau et des fenêtres, le navigateur web doit afficher tout ce qui est autour de la vidéo (la page web), le programme de ''cloud computing'' va lancer ses calculs sur la carte graphique, etc. Des situations de ce genre sont assez courantes et c'est soit le pilote qui s'en charge, soit la carte graphique elle-même. ===L'arbitrage logiciel du GPU=== L'arbitrage logiciel est la méthode la plus simple. Concrètement, c'est le système d'exploitation et/ou le pilote de la carte graphique qui gèrent l'arbitrage du GPU. Dans les deux cas, tout est fait en logiciel. Les commandes sont accumulées dans un tampon de commande, voire plusieurs, et l'OS/pilote décide quelle commande envoyer en priorité. Sur Windows, avant l'arrivée du modèle de driver dit ''Windows Display Driver Model'', de telles situations étaient gérées simplement. Les applications ajoutaient des commandes dans une file de commande unique. Les commandes étaient exécutées dans l'ordre, en mode premier entrée dans la file premier sorti/exécuté. Il n'y avait pour ainsi dire pas d'arbitrage entre les applications. Et ce n'était pas un problème car, à l'époque, les seules applications qui utilisaient le GPU étaient des jeux vidéos fonctionnant en mode plein écran. Avec le modèle de driver ''Windows Display Driver Model'' (WDDM), le GPU est maintenant arbitré, à savoir que les applications ont accès à tour de rôle au GPU, certaines ayant droit à plus de temps GPU que d'autres. Chaque programme a accès à la carte graphique durant quelques dizaines ou centaines de millisecondes, à tour de rôle. Si le programme finissait son travail en moins de temps que la durée impartie, il laissait la main au programme suivant. S’il atteignait la durée maximale allouée, il était interrompu pour laisser la place au programme suivant. Et chaque programme avait droit d'accès à la carte graphique chacun à son tour. Un tel algorithme en tourniquet est très simple, mais avait cependant quelques défauts. De nos jours, les algorithmes d'ordonnancement d'accès sont plus élaborés, bien qu'il soit difficile de trouver de la littérature ou des brevets sur le sujet. Une autre fonctionnalité de WDDM est que les applications utilisant le GPU peuvent se partager la mémoire vidéo sans se marcher dessus. Avant, toutes les applications avaient accès à toute la mémoire vidéo, bien que ce soit par l’intermédiaire de commandes spécifiques. Mais avec WDDM, chaque application dispose de sa propre portion de mémoire vidéo, à laquelle est la seule à avoir accès. Une application ne peut plus lire le contenu réel de la mémoire vidéo, et encore moins lire le contenu des autres applications. : Il s'agit d'un équivalent à l'isolation des processus pour les programmes Windows, mais appliqué à la mémoire vidéo et non la mémoire système. Et cette isolation est rendue d'autant plus simple que les GPU modernes implémentent un système de mémoire virtuelle à pagination très poussé, avec du swap en mémoire RAM système, une protection mémoire, et bien d'autres fonctionnalités. Nous en reparlerons dans les chapitres sur la mémoire vidéo. ===L'arbitrage accéléré par le GPU=== Depuis 2020, avec l'arrivée de la ''Windows 10 May 2020 update'', Windows est capable de déléguer l'arbitrage du GPU au GPU lui-même. Le GPU gère lui-même l'arbitrage, du moins en partie. En partie, car l'OS gére les priorité, à savoir quelle application a droit à plus de temps que les autres. Par contre, la gestion du ''quantum'' de temps ou les commutations de contexte (on stoppe une application pour laisser la place à une autre), est du fait du GPU lui-même. L'avantage est que cela décharge le processeur d'une tâche assez lourde en calcul, pour la déporter sur le GPU. Un autre avantage est que le GPU peut gérer plus finement les ''quantum'' de temps et la commutation de contexte. Le CPU principal gère des durées assez importantes, de l'ordre de la milliseconde. De plus, il doit communiquer avec le GPU par des mécanismes temporellement imprécis, comme des interruptions. Avec l'arbitrage accéléré par le GPU, le GPU n'a plus besoin de communiquer avec le CPU pour l'arbitrage et peut le faire plus précisément, plus immédiatement. Un gain en performance théorique est donc possible. L'arbitrage accéléré par le GPU est le fait soit du processeur de commandes, soit d'un processeur spécialisé, séparé. {{NavChapitre | book=Les cartes graphiques | prev=La hiérarchie mémoire d'un GPU | prevText=La hiérarchie mémoire d'un GPU | next=Le pipeline géométrique d'avant DirectX 10 | netxText=Le pipeline géométrique d'avant DirectX 10 }}{{autocat}} 3xsa0467zoahvmttmmiqfi81t4iprd9 744037 744036 2025-06-03T13:55:37Z Mewtow 31375 /* Le processeur de commandes */ 744037 wikitext text/x-wiki Dans ce chapitre, nous allons parler de tous les intermédiaires qui se placent entre une application de rendu 3D et les circuits de rendu 3D proprement dit. En premier lieu, on trouve le pilote de la carte graphique, aux fonctions multiples et variées. En second lieu, nous allons parler d'un circuit de la carte graphique qui fait l'interface entre le logiciel et les circuits de rendu 3D de la carte graphique : le processeur de commandes. Ce processeur de commandes est un circuit qui sert de chef d'orchestre, qui pilote le fonctionnement global de la carte graphique. API 3D, pilote de carte graphique et processeur de commande travaillent de concert pour que l'application communique avec la carte graphique. Nous allons d'abord voir le pilote de la carte graphique, avant de voir le fonctionnement du processeur de commande. ==Le pilote de carte graphique== Le pilote de la carte graphique est un logiciel qui s'occupe de faire l'interface entre le logiciel et la carte graphique. De manière générale, les pilotes de périphérique sont des intermédiaires entre les applications/APIs et le matériel. En théorie, le système d'exploitation est censé jouer ce rôle, mais il n'est pas programmé pour être compatible avec tous les périphériques vendus sur le marché. À la place, le système d'exploitation ne gère pas directement certains périphériques, mais fournit de quoi ajouter ce qui manque. Le pilote d'un périphérique sert justement à ajouter ce qui manque : ils ajoutent au système d'exploitation de quoi reconnaître le périphérique, de quoi l'utiliser au mieux. Pour une carte graphique, il a diverses fonctions que nous allons voir ci-dessous. Avant toute chose, précisons que les systèmes d'exploitation usuels (Windows, Linux, MacOsX et autres) sont fournis avec un pilote de carte graphique générique, compatible avec la plupart des cartes graphiques existantes. Rien de magique derrière cela : toutes les cartes graphiques vendues depuis plusieurs décennies respectent des standards, comme le VGA, le VESA, et d'autres. Et le pilote de base fournit avec le système d'exploitation est justement compatible avec ces standards minimaux. Mais le pilote ne peut pas profiter des fonctionnalités qui sont au-delà de ce standard. L'accélération 3D est presque inexistante avec le pilote de base, qui ne sert qu'à faire du rendu 2D (de quoi afficher l’interface de base du système d'exploitation, comme le bureau de Windows). Et même pour du rendu 2D, la plupart des fonctionnalités de la carte graphique ne sont pas disponibles. Par exemple, certaines résolutions ne sont pas disponibles, notamment les grandes résolutions. Ou encore, les performances sont loin d'être excellentes. Si vous avez déjà utilisé un PC sans pilote de carte graphique installé, vous avez certainement remarqué qu'il était particulièrement lent. ===La gestion des interruptions=== Une fonction particulièrement importante du pilote de carte graphique est la réponse aux interruptions lancées par la carte graphique. Pour rappel, les interruptions sont une fonctionnalité qui permet à un périphérique de communiquer avec le processeur, tout en économisant le temps de calcul de ce dernier. Typiquement, lorsqu'un périphérique lance une interruption, le processeur stoppe son travail et exécute automatiquement une routine d'interruption, un petit programme qui s'occupe de gérer le périphérique, de faire ce qu'il faut, ce que l'interruption a demandé. Il y a plusieurs interruptions possibles, chacune ayant son propre numéro et sa fonction dédiée, chacune ayant sa propre routine d'interruption. Après tout, la routine qui gère un débordement de la mémoire vidéo n'est pas la même que celle qui gère un changement de fréquence du GPU ou la fin du calcul d'une image 3D. Le pilote fournit l'ensemble des routines d'interruptions nécessaires pour gérer la carte graphique. ===La compilation des ''shaders''=== Le pilote de carte graphique est aussi chargé de traduire les ''shaders'' en code machine. En soi, cette étape est assez complexe, et ressemble beaucoup à la compilation d'un programme informatique normal. Les ''shaders'' sont écrits dans un langage de programmation de haut niveau, comme le HLSL ou le GLSL, mais ce n'est pas ce code source qui est compilé par le pilote de carte graphique. À la place, les ''shaders'' sont pré-compilés vers un langage dit intermédiaire, avant d'être compilé par le pilote en code machine. Le langage intermédiaire, comme son nom l'indique, sert d'intermédiaire entre le code source écrit en HLSL/GLSL et le code machine exécuté par la carte graphique. Il ressemble à un langage assembleur, mais reste malgré tout assez générique pour ne pas être un véritable code machine. Par exemple, il y a peu de limitations quant au nombre de processeurs ou de registres. En clair, il y a deux passes de compilation : une passe de traduction du code source en langage intermédiaire, puis une passe de compilation du code intermédiaire vers le code machine. Notons que la première passe est réalisée par le programmeur des ''shaders'', non pas par l'utilisateur. Par exemple, les ''shaders'' d'un jeu vidéo sont fournis déjà pré-compilés : les fichiers du jeu ne contiennent pas le code source GLSL/HLSL, mais du code intermédiaire. L'avantage de cette méthode est que le travail du pilote est fortement simplifié. Le pilote de périphérique pourrait compiler directement du code HLSL/GLSL, mais le temps de compilation serait très long et cela aurait un impact sur les performances. Avec l'usage du langage intermédiaire, le gros du travail à été fait lors de la première passe de compilation et le pilote graphique ne fait que finir le travail. Les optimisations importantes ont déjà été réalisées lors de la première passe. Il doit bien faire la traduction, ajouter quelques optimisations de bas niveau par-ci par-là, mais rien de bien gourmand en processeur. Autant dire que cela économise plus le processeur que si on devait compiler complètement les ''shaders'' à chaque exécution. Fait amusant, il faut savoir que le pilote peut parfois remplacer les ''shaders'' d'un jeu vidéo à la volée. Les pilotes récents embarquent en effet des ''shaders'' alternatifs pour les jeux les plus vendus et/ou les plus populaires. Lorsque vous lancez un de ces jeux vidéo et que le ''shader'' originel s'exécute, le pilote le détecte automatiquement et le remplace par la version améliorée, fournie par le pilote. Évidemment, le ''shader'' alternatif du pilote est optimisé pour le matériel adéquat. Cela permet de gagner en performance, voire en qualité d'image, sans pour autant que les concepteurs du jeu n'aient quoique ce soit à faire. Enfin, certains ''shaders'' sont fournis par le pilote pour d'autres raisons. Par exemple, les cartes graphiques récentes n'ont pas de circuits fixes pour traiter la géométrie. Autant les anciennes cartes graphiques avaient des circuits de T&L qui s'en occupaient, autant tout cela doit être émulé sur les machines récentes. Sans cette émulation, les vieux jeux vidéo conçus pour exploiter le T&L et d'autres technologies du genre ne fonctionneraient plus du tout. Émuler les circuits fixes disparus sur les cartes récentes est justement le fait de ''shaders'', présents dans le pilote de carte graphique. ===Les autres fonctions=== Le pilote a aussi bien d'autres fonctions. Par exemple, il s'occupe d'initialiser la carte graphique, de fixer la résolution, d'allouer la mémoire vidéo, de gérer le curseur de souris matériel, etc. ==Les commandes graphiques/vidéo/autres : des ordres envoyés au GPU== Tous les traitements que la carte graphique doit effectuer, qu'il s'agisse de rendu 2D, de calculs 2D, du décodage matérielle d'un flux vidéo, ou de calculs généralistes, sont envoyés par le pilote de la carte graphique, sous la forme de '''commandes'''. Ces commandes demandent à la carte graphique d'effectuer une opération 2D, ou une opération 3D, ou encore le rendu d'une vidéo. Les commandes graphiques en question varient beaucoup selon la carte graphique. Les commandes sont régulièrement revues et chaque nouvelle architecture a quelques changements par rapport aux modèles plus anciens. Des commandes peuvent apparaître, d'autres disparaître, d'autre voient leur fonctionnement légèrement altéré, etc. Mais dans les grandes lignes, on peut classer ces commandes en quelques grands types. Les commandes les plus importantes s'occupent de l'affichage 3D : afficher une image à partir de paquets de sommets, préparer le passage d'une image à une autre, changer la résolution, etc. Plus rare, d'autres commandes servent à faire du rendu 2D : afficher un polygone, tracer une ligne, coloriser une surface, etc. Sur les cartes graphiques qui peuvent accélérer le rendu des vidéos, il existe des commandes spécialisées pour l’accélération des vidéos. Pour donner quelques exemples, prenons les commandes 2D de la carte graphique AMD Radeon X1800. {|class="wikitable" |- ! Commandes 2D ! Fonction |- |PAINT |Peindre un rectangle d'une certaine couleur |- |PAINT_MULTI |Peindre des rectangles (pas les mêmes paramètres que PAINT) |- |BITBLT |Copie d'un bloc de mémoire dans un autre |- |BITBLT_MULTI |Plusieurs copies de blocs de mémoire dans d'autres |- |TRANS_BITBLT |Copie de blocs de mémoire avec un masque |- |NEXTCHAR |Afficher un caractère avec une certaine couleur |- |HOSTDATA_BLT |Écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo |- |POLYLINE |Afficher des lignes reliées entre elles |- |POLYSCANLINES |Afficher des lignes |- |PLY_NEXTSCAN |Afficher plusieurs lignes simples |- |SET_SCISSORS |Utiliser des coupes (ciseaux) |- |LOAD_PALETTE |Charger la palette pour affichage 2D |} ===Le tampon de commandes=== L'envoi des commandes à la carte graphique ne se fait pas directement. La carte graphique n'est pas toujours libre pour accepter une nouvelle commande, soit parce qu'elle est occupée par une commande précédente, soit parce qu'elle fait autre chose. Il faut alors faire patienter les données tant que la carte graphique est occupée. Les pilotes de la carte graphique vont les mettre en attente dans le '''tampon de commandes'''. Le tampon de commandes est ce qu'on appelle une file, une zone de mémoire dans laquelle on stocke des données dans l'ordre d'ajout. Si le tampon de commandes est plein, le driver n'accepte plus de demandes en provenance des applications. Un tampon de commandes plein est généralement mauvais signe : cela signifie que la carte graphique est trop lente pour traiter les demandes qui lui sont faites. Par contre, il arrive que le tampon de commandes soit vide : dans ce cas, c'est simplement que la carte graphique est trop rapide comparé au processeur, qui n'arrive alors pas à donner assez de commandes à la carte graphique pour l'occuper suffisamment. Le tampon de commande est soit une mémoire FIFO séparée, soit une portion de la mémoire vidéo. Le NV1, la toute première carte graphique NVIDIA, utilisait une mémoire FIFO intégrée à la carte graphique, séparée des autres circuits. Le processeur envoyait les commandes par rafale au GPU, à savoir qu'il envoyait plusieurs dizaines ou centaines de commandes à la suite, avant de passer à autre chose. Le GPU traitait les commandes une par une, à un rythme bien plus lent. Le processeur pouvait consulter la FIFO pour savoir s'il restait des entrées libres et combien. Le processeur savait ainsi combien d'écritures il pouvait envoyer en une fois au GPU. : Le fonctionnement de la FIFO du NV1 est décrit dans le brevet ''US5805930A : System for FIFO informing the availability of stages to store commands which include data and virtual address sent directly from application programs''. ===Le processeur de commandes=== Le '''processeur de commande''' est un circuit qui gère les commandes envoyées par le processeur. Il lit la commande la plus ancienne dans le tampon de commande, l’interprète et l’exécute, puis passe à la suivante. Le processeur de commande est un circuit assez compliqué. Sur les cartes graphiques anciennes, c'était un circuit séquentiel complexe, fabriqué à la main et était la partie la plus complexe du processeur graphique. Sur les cartes graphiques modernes, c'est un véritable microcontrôleur, avec un processeur, de la mémoire RAM, etc. Le processeur de commandes lit une commande dans le tampon de commande, décode la commande et l’exécute sur la carte graphique. Il garde en mémoire l'état de traitement de chaque commande : est-ce qu'elle est en train de s’exécuter sur le processeur graphique, est-ce qu'elle est mise en pause, est-ce qu'elle attend une donnée en provenance de la mémoire, est-ce qu'elle est terminée, etc. Une commande utilise divers circuits de la carte 3D, de la mémoire vidéo, et d'autres ressources au sens large (des processeurs de ''shader'', notamment). Pour donner un exemple, la première carte graphique de NVIDIA, le NV1, contenait dans le détail : un controleur DMA avec une IO-MMU intégrée, la FIFO de commande, le processeur de commande, un pipeline graphique, un pipeline sonore, un contrôleur de manette. L'ensemble était relié par un bus interne à la carte graphique. Le processeur de commande servait de gestionnaire principal. Le processeur de commande pilote les circuits de la carte graphique, il répartit le travail entre les différents circuits de la carte graphique et assure que l'ordre du pipeline est respecté. La fonction principale du processeur de commande est de répartir le travail entre les différents circuits. Le processeur de commande décide à quel processeur ou circuit doit être envoyé une commande. C'est le processeur de commande qui s'occupe de la gestion des ressources et qui attribue telle ressource à telle commande. A chaque instant, le processeur de commande répartit les ''shaders'' sur les processeurs de ''shaders'', en faisant en sorte qu'ils soient utilisés le plus possible. Dans le cas le plus simple, les unités sont alimentées en vertex/pixels les unes après les autres (principe du round-robin), mais des stratégies plus optimisées sont la règle de nos jours. Cela est très important sur les cartes graphiques : répartir plusieurs commandes sur plusieurs processeurs est une tâche difficile. Un chapitre entier sera d'ailleurs dédié à ce sujet. Il envoie aussi certaines commandes aux circuits fixes, comme l’''input assembler''. Là encore, il faut en sorte que les circuits fixes soient utilisés le mieux possible. Sa tâche est compliquée par le fait que les GPU récents ont plusieurs unités de traitement des sommets et des pixels, plusieurs ROP, plusieurs unités de textures, etc. Et c'est en partie le travail du processeur de commande que de répartir les calculs sur ces différentes unités. C'est là un problème assez compliqué pour le processeur de commande et ce pour tout un tas de raisons que nous ne ferons que survoler. Les contraintes d'ordonnancement de l'API et les règles de celle-ci sont une partie de la réponse. Mais d'autres raisons sont intrinsèques au rendu 3D ou à la conception des circuits. [[File:Architecture de base d'une carte 3D - 1.png|centre|vignette|upright=2.5|Architecture de base d'une carte 3D - 1]] ==Le fonctionnement du processeur de commandes== Le processeur de commande lit, décode et exécute des commandes. Intuitivement, on se dit qu'il procède une commande à la fois. Mais les GPU modernes sont plus intelligents et peuvent exécuter plusieurs commandes en même temps, dans des circuits séparés. De nombreuses optimisations de ce type sont utilisées pour gagner en performance. Voyons comment un processeur de commande moderne fonctionne. ===L'ordonnancement et la gestion des ressources=== Le processeur de commande doit souvent mettre en pause certains circuits du pipeline, ainsi que les circuits précédents. Par exemple, si tous les processeurs de ''vertex shader'' sont occupés, l’''input assembler'' ne peut pas charger le paquet suivant car il n'y a aucun processeur de libre pour l’accueillir. Dans ce cas, l'étape d’''input assembly'' est mise en pause en attendant qu'un processeur de ''shader'' soit libre. La même chose a lieu pour l'étape de rastérisation : si aucun processeur de ''shader'' n'est libre, elle est mise en pause. Sauf que pour la rastérisation, cela a des conséquences sur les circuits précédents la rastérisation. Si un processeur de ''shader'' veut envoyer quelque chose au rastériseur alors qu'il est en pause, il devra lui aussi attendre que le rastériseur soit libre. On a la même chose quand les ROP sont occupés : les ''pixel shader'' ou l'unité de texture doivent parfois être mis en pause, ce qui peut entrainer la mise en pause des étapes précédentes, etc. En clair : plus un étape est situé vers la fin du pipeline graphique, plus sa mise en pause a de chances de se répercuter sur les étapes précédentes et de les mettre en pause aussi. Le processeur de commande doit gérer ces situations. ===Le pipelining des commandes=== Dans les cartes graphiques les plus rudimentaires, le processeur de commande exécute les commandes dans l'ordre. Il exécute une commande çà la fois et attend qu'une commande soit terminé pour en lancer une autre. Plusieurs commandes sont accumulées dans le tampon de commande, le processeur de commande les traite de la plus ancienne vers la plus récente. Du moins, les anciennes cartes graphiques faisaient comme cela, les cartes graphiques modernes sont un peu plus complexes. Elles n'attendent pas qu'une commande soit totalement terminée avant d'en lancer une nouvelle. Les processeurs de commande actuels sont capables d’exécuter plusieurs commandes en même temps. L'intérêt est un gain en performance assez important. Pour ceux qui ont déjà eu un cours d'architecture des ordinateurs avancé, lancer plusieurs commandes en même temps permet une forme de pipeline, dont les gains sont substantiels. Par exemple, imaginez qu'une commande de rendu 3D soit bien avancée et n'utilise que les processeurs de ''shaders'' et les ROP, mais laisse les unités géométriques libres. Il est alors possible de démarrer la commande suivante en avance, afin qu'elle remplisse les unités géométriques inutilisées. On a alors deux commandes en cours de traitement : une commande qui utilise la fin du pipeline uniquement, une autre qui utilise seulement le début du pipeline graphique. Le processeur de commande gère donc plusieurs commandes simultanées, à savoir plusieurs commandes qui en sont à des étapes différentes du pipeline. On peut avoir une commande qui est en cours dans l'étage de gestion de la géométrie, une autre dans le rastériseur, et une autre dans les unités de traitement des pixels. Le fait que les étapes du pipeline graphique sont à effectuer dans un ordre bien précis permet ce genre de chose assez facilement. Une autre possibilité est de faire des rendus en parallèle. Par exemple, imaginez qu'on ait des circuits séparés pour le rendu 2D et 3D. Prenons l'exemple où le calcul d'une image finale demande de faire un rendu 3D suivi d'un rendu 2D, par exemple un jeu vidéo en 3D qui a un HUD dessiné en 2D. Dans ce cas, on peut démarrer le calcul de l'image suivante dans le pipeline 3D pendant que la précédente est dans les circuits 2D, au lieu de laisser inutilisé le pipeline 3D pendant le rendu 2D. Mais c'est là un défi compliqué à relever pour le processeur de commande, qui donne lieu à son lot de problèmes. Le problème principal est le partage de ressources entre commandes. Par exemple, on peut prendre le cas où une commande n'utilise pas beaucoup les processeurs de ''shaders''. On pourrait imaginer lancer une seconde commande en parallèle, afin que la seconde commande utiliser les processeurs de ''shaders'' inutilisés. Mais cela n'est possible que si les circuits fixes sont capables d'accepter une seconde commande. Si la première commande sature les circuits fixe, le lancement de la seconde commande sera empêché. Mais si ce n'est pas le cas, les deux commandes pourront être lancées en même temps. Pareil pour le débit mémoire, qui doit alors être partagé entre deux commandes simultanées, ce qui est à prendre en compte. ===La synchronisation de l’exécution des commandes avec le processeur=== Il arrive que le processeur doive savoir où en est le traitement des commandes, ce qui est très utile pour la gestion de la mémoire vidéo. Un premier exemple : comment éviter de saturer une carte graphique de commande, alors qu'on ne sait pas si elles traite les commandes rapidement ou non ? L'idéal est de regarder où en est la carte graphique dans l'exécution des commandes. Si elle n'en est qu'au début du tampon de commande et que celui-ci est bien remplit, alors il vaut mieux lever le pied et ne pas envoyer de nouvelles commandes. A l'inverse, si le tampon de commande est presque vide, envoyer des commandes est la meilleure idée possible. Un autre exemple un peu moins parlant est celui de la gestion de la mémoire vidéo. Rappelons qu'elle est réalisée par le pilote de la carte graphique, sur le processeur principal, qui décide d'allouer et de libérer de la mémoire vidéo. Pour donner un exemple d'utilisation, imaginez que le pilote de la carte graphique doive libérer de la mémoire pour pouvoir ajouter une nouvelle commande. Comment éviter d'enlever une texture tant que les commandes qui l'utilisent ne sont pas terminées ? Ce problème ne se limite pas aux textures, mais vaut pour tout ce qui est placé en mémoire vidéo. Il faut donc que la carte graphique trouve un moyen de prévenir le processeur que le traitement de telle commande est terminée, que telle commande en est rendue à tel ou tel point, etc. Pour cela, on a globalement deux grandes solutions. La première est celle des interruptions, abordées dans les chapitres précédents. Mais elles sont assez couteuses et ne sont utilisées que pour des évènements vraiment importants, critiques, qui demandent une réaction rapide du processeur. L'autre solution est celle du ''pooling'', où le processeur monitore la carte graphique à intervalles réguliers. Deux solutions bien connues de ceux qui ont déjà lu un cours d'architecture des ordinateurs digne de ce nom, rien de bien neuf : la carte graphique communique avec le processeur comme tout périphérique. Pour faciliter l'implémentation du ''pooling'', la carte graphique contient des registres de statut, dans le processeur de commande, qui mémorisent tout ou partie de l'état de la carte graphique. Si un problème survient, certains bits du registre de statut seront mis à 1 pour indiquer que telle erreur bien précise a eu lieu. Il existe aussi un registre de statut qui mémorise le numéro de la commande en cours, ou de la dernière commande terminée, ce qui permet de savoir où en est la carte graphique dans l'exécution des commandes. Et certaines registres de statut sont dédiés à la gestion des commandes. Ils sont totalement programmable, la carte graphique peut écrire dedans sans problème. Les cartes graphiques récentes incorporent des commandes pour modifier ces registres de statut au besoin. Elles sont appelées des '''commandes de synchronisation''' : les barrières (''fences''). Elles permettent d'écrire une valeur dans un registre de statut quand telle ou telle condition est remplie. Par exemple, si jamais une commande est terminée, on peut écrire la valeur 1 dans tel ou tel registre. La condition en question peut être assez complexe et se résumer à quelque chose du genre : "si jamais toutes les ''shaders'' ont fini de traiter tel ensemble de textures, alors écrit la valeur 1024 dans le registre de statut numéro 9". ===La synchronisation de l’exécution des commandes intra-GPU=== Lancer plusieurs commandes en parallèle dans le pipeline permet de gagner en performance.Mais cela a un gros défaut : il n'est pas garantit que les commandes se terminent dans l'ordre. Si on démarre une seconde commande après la première, il arrive que la seconde finisse avant. Pire : il n'est pas garantit qu'elles s'exécutent dans l'ordre. Dans la plupart des cas, cela ne pose pas de problèmes. Mais dans d'autres, cela donne des résultats erronés. Pour donner un exemple, utilisons les commandes de rendu 2D vues plus haut, histoire de simplifier le tout. Imaginez que vous codez un jeu vidéo et que le rendu se fait en 2D, partons sur un jeu de type FPS. Vous avez une série de commandes pour calculer l'image à rendre à l'écran, suivie par une série de commandes finales pour dessiner le HUB. Pour dessiner le HUD, vous utilisez des commandes HOSTDATA_BLT, dont le but est d'écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo. Et bien ces commandes HOSTDATA_BLT doivent démarrer une fois que le rendu de l'image est complétement terminé. Imaginez que vous dessiniez le HUD sur une portion de l'image pas encore terminée et que celui-ci est effacé par des écritures ultérieures ! Pour éviter tout problème, les GPU incorporent des commandes de synchronisation intra-GPU, destinées au processeur de commande, aussis appelées des '''commandes de sémaphore'''. Elles permettent de mettre en pause le lancement d'une nouvelle commande tant que les précédentes ne sont pas totalement ou partiellement terminées. Les plus simples empêchent le démarrage d'une commande tant que les précédentes ne sont pas terminées. D'autres permettent de démarrer une commande si et seulement si certaines commandes sont terminées. D'autres sont encore plus précises : elles empêchent le démarrage d'une nouvelle commande tant qu'une commande précédente n'a pas atteint un certain stade de son exécution. Là encore, de telles commandes sont des commandes du style "attend que le registre de statut numéro N contienne la valeur adéquate avant de poursuivre l'exécution des commandes". Les commandes en question peuvent être sur le même modèle que précédemment, à savoir des commandes qui lisent les registres de statut. Mais elles peuvent aussi se baser sur le fait que telle ou telle ressource de rendu est libre ou non. Des commandes successives se partagent souvent des données, et que de nombreuses commandes différentes peuvent s'exécuter en même temps. Or, si une commande veut modifier les données utilisées par une autre commande, il faut que l'ordre des commandes soit maintenu : la commande la plus récente ne doit pas modifier les données utilisées par une commande plus ancienne. Avec ce modèle, les sémaphores bloquent une commande tant qu'une ressource (une texture) est utilisée par une autre commande. {|class="wikitable" |- ! Commandes de synchronisation ! Fonction |- |NOP |Ne rien faire |- |WAIT_SEMAPHORE |Attendre la synchronisation avec un sémaphore |- |WAIT_MEM |Attendre que la mémoire vidéo soit disponible et inoccupée par le CPU |} ==L'arbitrage de l'accès à la carte graphique== Il n'est pas rare que plusieurs applications souhaitent accéder en même temps à la carte graphique. Imaginons que vous regardez une vidéo en ''streaming'' sur votre navigateur web, avec un programme de ''cloud computing'' de type ''Folding@Home'' qui tourne en arrière-plan, sur Windows. Le décodage de la vidéo est réalisé par la carte graphique, Windows s'occupe de l'affichage du bureau et des fenêtres, le navigateur web doit afficher tout ce qui est autour de la vidéo (la page web), le programme de ''cloud computing'' va lancer ses calculs sur la carte graphique, etc. Des situations de ce genre sont assez courantes et c'est soit le pilote qui s'en charge, soit la carte graphique elle-même. ===L'arbitrage logiciel du GPU=== L'arbitrage logiciel est la méthode la plus simple. Concrètement, c'est le système d'exploitation et/ou le pilote de la carte graphique qui gèrent l'arbitrage du GPU. Dans les deux cas, tout est fait en logiciel. Les commandes sont accumulées dans un tampon de commande, voire plusieurs, et l'OS/pilote décide quelle commande envoyer en priorité. Sur Windows, avant l'arrivée du modèle de driver dit ''Windows Display Driver Model'', de telles situations étaient gérées simplement. Les applications ajoutaient des commandes dans une file de commande unique. Les commandes étaient exécutées dans l'ordre, en mode premier entrée dans la file premier sorti/exécuté. Il n'y avait pour ainsi dire pas d'arbitrage entre les applications. Et ce n'était pas un problème car, à l'époque, les seules applications qui utilisaient le GPU étaient des jeux vidéos fonctionnant en mode plein écran. Avec le modèle de driver ''Windows Display Driver Model'' (WDDM), le GPU est maintenant arbitré, à savoir que les applications ont accès à tour de rôle au GPU, certaines ayant droit à plus de temps GPU que d'autres. Chaque programme a accès à la carte graphique durant quelques dizaines ou centaines de millisecondes, à tour de rôle. Si le programme finissait son travail en moins de temps que la durée impartie, il laissait la main au programme suivant. S’il atteignait la durée maximale allouée, il était interrompu pour laisser la place au programme suivant. Et chaque programme avait droit d'accès à la carte graphique chacun à son tour. Un tel algorithme en tourniquet est très simple, mais avait cependant quelques défauts. De nos jours, les algorithmes d'ordonnancement d'accès sont plus élaborés, bien qu'il soit difficile de trouver de la littérature ou des brevets sur le sujet. Une autre fonctionnalité de WDDM est que les applications utilisant le GPU peuvent se partager la mémoire vidéo sans se marcher dessus. Avant, toutes les applications avaient accès à toute la mémoire vidéo, bien que ce soit par l’intermédiaire de commandes spécifiques. Mais avec WDDM, chaque application dispose de sa propre portion de mémoire vidéo, à laquelle est la seule à avoir accès. Une application ne peut plus lire le contenu réel de la mémoire vidéo, et encore moins lire le contenu des autres applications. : Il s'agit d'un équivalent à l'isolation des processus pour les programmes Windows, mais appliqué à la mémoire vidéo et non la mémoire système. Et cette isolation est rendue d'autant plus simple que les GPU modernes implémentent un système de mémoire virtuelle à pagination très poussé, avec du swap en mémoire RAM système, une protection mémoire, et bien d'autres fonctionnalités. Nous en reparlerons dans les chapitres sur la mémoire vidéo. ===L'arbitrage accéléré par le GPU=== Depuis 2020, avec l'arrivée de la ''Windows 10 May 2020 update'', Windows est capable de déléguer l'arbitrage du GPU au GPU lui-même. Le GPU gère lui-même l'arbitrage, du moins en partie. En partie, car l'OS gére les priorité, à savoir quelle application a droit à plus de temps que les autres. Par contre, la gestion du ''quantum'' de temps ou les commutations de contexte (on stoppe une application pour laisser la place à une autre), est du fait du GPU lui-même. L'avantage est que cela décharge le processeur d'une tâche assez lourde en calcul, pour la déporter sur le GPU. Un autre avantage est que le GPU peut gérer plus finement les ''quantum'' de temps et la commutation de contexte. Le CPU principal gère des durées assez importantes, de l'ordre de la milliseconde. De plus, il doit communiquer avec le GPU par des mécanismes temporellement imprécis, comme des interruptions. Avec l'arbitrage accéléré par le GPU, le GPU n'a plus besoin de communiquer avec le CPU pour l'arbitrage et peut le faire plus précisément, plus immédiatement. Un gain en performance théorique est donc possible. L'arbitrage accéléré par le GPU est le fait soit du processeur de commandes, soit d'un processeur spécialisé, séparé. {{NavChapitre | book=Les cartes graphiques | prev=La hiérarchie mémoire d'un GPU | prevText=La hiérarchie mémoire d'un GPU | next=Le pipeline géométrique d'avant DirectX 10 | netxText=Le pipeline géométrique d'avant DirectX 10 }}{{autocat}} qynv97pw0ullmt1d9g2iftk48kg4pdk 744038 744037 2025-06-03T14:07:13Z Mewtow 31375 /* Le processeur de commandes */ 744038 wikitext text/x-wiki Dans ce chapitre, nous allons parler de tous les intermédiaires qui se placent entre une application de rendu 3D et les circuits de rendu 3D proprement dit. En premier lieu, on trouve le pilote de la carte graphique, aux fonctions multiples et variées. En second lieu, nous allons parler d'un circuit de la carte graphique qui fait l'interface entre le logiciel et les circuits de rendu 3D de la carte graphique : le processeur de commandes. Ce processeur de commandes est un circuit qui sert de chef d'orchestre, qui pilote le fonctionnement global de la carte graphique. API 3D, pilote de carte graphique et processeur de commande travaillent de concert pour que l'application communique avec la carte graphique. Nous allons d'abord voir le pilote de la carte graphique, avant de voir le fonctionnement du processeur de commande. ==Le pilote de carte graphique== Le pilote de la carte graphique est un logiciel qui s'occupe de faire l'interface entre le logiciel et la carte graphique. De manière générale, les pilotes de périphérique sont des intermédiaires entre les applications/APIs et le matériel. En théorie, le système d'exploitation est censé jouer ce rôle, mais il n'est pas programmé pour être compatible avec tous les périphériques vendus sur le marché. À la place, le système d'exploitation ne gère pas directement certains périphériques, mais fournit de quoi ajouter ce qui manque. Le pilote d'un périphérique sert justement à ajouter ce qui manque : ils ajoutent au système d'exploitation de quoi reconnaître le périphérique, de quoi l'utiliser au mieux. Pour une carte graphique, il a diverses fonctions que nous allons voir ci-dessous. Avant toute chose, précisons que les systèmes d'exploitation usuels (Windows, Linux, MacOsX et autres) sont fournis avec un pilote de carte graphique générique, compatible avec la plupart des cartes graphiques existantes. Rien de magique derrière cela : toutes les cartes graphiques vendues depuis plusieurs décennies respectent des standards, comme le VGA, le VESA, et d'autres. Et le pilote de base fournit avec le système d'exploitation est justement compatible avec ces standards minimaux. Mais le pilote ne peut pas profiter des fonctionnalités qui sont au-delà de ce standard. L'accélération 3D est presque inexistante avec le pilote de base, qui ne sert qu'à faire du rendu 2D (de quoi afficher l’interface de base du système d'exploitation, comme le bureau de Windows). Et même pour du rendu 2D, la plupart des fonctionnalités de la carte graphique ne sont pas disponibles. Par exemple, certaines résolutions ne sont pas disponibles, notamment les grandes résolutions. Ou encore, les performances sont loin d'être excellentes. Si vous avez déjà utilisé un PC sans pilote de carte graphique installé, vous avez certainement remarqué qu'il était particulièrement lent. ===La gestion des interruptions=== Une fonction particulièrement importante du pilote de carte graphique est la réponse aux interruptions lancées par la carte graphique. Pour rappel, les interruptions sont une fonctionnalité qui permet à un périphérique de communiquer avec le processeur, tout en économisant le temps de calcul de ce dernier. Typiquement, lorsqu'un périphérique lance une interruption, le processeur stoppe son travail et exécute automatiquement une routine d'interruption, un petit programme qui s'occupe de gérer le périphérique, de faire ce qu'il faut, ce que l'interruption a demandé. Il y a plusieurs interruptions possibles, chacune ayant son propre numéro et sa fonction dédiée, chacune ayant sa propre routine d'interruption. Après tout, la routine qui gère un débordement de la mémoire vidéo n'est pas la même que celle qui gère un changement de fréquence du GPU ou la fin du calcul d'une image 3D. Le pilote fournit l'ensemble des routines d'interruptions nécessaires pour gérer la carte graphique. ===La compilation des ''shaders''=== Le pilote de carte graphique est aussi chargé de traduire les ''shaders'' en code machine. En soi, cette étape est assez complexe, et ressemble beaucoup à la compilation d'un programme informatique normal. Les ''shaders'' sont écrits dans un langage de programmation de haut niveau, comme le HLSL ou le GLSL, mais ce n'est pas ce code source qui est compilé par le pilote de carte graphique. À la place, les ''shaders'' sont pré-compilés vers un langage dit intermédiaire, avant d'être compilé par le pilote en code machine. Le langage intermédiaire, comme son nom l'indique, sert d'intermédiaire entre le code source écrit en HLSL/GLSL et le code machine exécuté par la carte graphique. Il ressemble à un langage assembleur, mais reste malgré tout assez générique pour ne pas être un véritable code machine. Par exemple, il y a peu de limitations quant au nombre de processeurs ou de registres. En clair, il y a deux passes de compilation : une passe de traduction du code source en langage intermédiaire, puis une passe de compilation du code intermédiaire vers le code machine. Notons que la première passe est réalisée par le programmeur des ''shaders'', non pas par l'utilisateur. Par exemple, les ''shaders'' d'un jeu vidéo sont fournis déjà pré-compilés : les fichiers du jeu ne contiennent pas le code source GLSL/HLSL, mais du code intermédiaire. L'avantage de cette méthode est que le travail du pilote est fortement simplifié. Le pilote de périphérique pourrait compiler directement du code HLSL/GLSL, mais le temps de compilation serait très long et cela aurait un impact sur les performances. Avec l'usage du langage intermédiaire, le gros du travail à été fait lors de la première passe de compilation et le pilote graphique ne fait que finir le travail. Les optimisations importantes ont déjà été réalisées lors de la première passe. Il doit bien faire la traduction, ajouter quelques optimisations de bas niveau par-ci par-là, mais rien de bien gourmand en processeur. Autant dire que cela économise plus le processeur que si on devait compiler complètement les ''shaders'' à chaque exécution. Fait amusant, il faut savoir que le pilote peut parfois remplacer les ''shaders'' d'un jeu vidéo à la volée. Les pilotes récents embarquent en effet des ''shaders'' alternatifs pour les jeux les plus vendus et/ou les plus populaires. Lorsque vous lancez un de ces jeux vidéo et que le ''shader'' originel s'exécute, le pilote le détecte automatiquement et le remplace par la version améliorée, fournie par le pilote. Évidemment, le ''shader'' alternatif du pilote est optimisé pour le matériel adéquat. Cela permet de gagner en performance, voire en qualité d'image, sans pour autant que les concepteurs du jeu n'aient quoique ce soit à faire. Enfin, certains ''shaders'' sont fournis par le pilote pour d'autres raisons. Par exemple, les cartes graphiques récentes n'ont pas de circuits fixes pour traiter la géométrie. Autant les anciennes cartes graphiques avaient des circuits de T&L qui s'en occupaient, autant tout cela doit être émulé sur les machines récentes. Sans cette émulation, les vieux jeux vidéo conçus pour exploiter le T&L et d'autres technologies du genre ne fonctionneraient plus du tout. Émuler les circuits fixes disparus sur les cartes récentes est justement le fait de ''shaders'', présents dans le pilote de carte graphique. ===Les autres fonctions=== Le pilote a aussi bien d'autres fonctions. Par exemple, il s'occupe d'initialiser la carte graphique, de fixer la résolution, d'allouer la mémoire vidéo, de gérer le curseur de souris matériel, etc. ==Les commandes graphiques/vidéo/autres : des ordres envoyés au GPU== Tous les traitements que la carte graphique doit effectuer, qu'il s'agisse de rendu 2D, de calculs 2D, du décodage matérielle d'un flux vidéo, ou de calculs généralistes, sont envoyés par le pilote de la carte graphique, sous la forme de '''commandes'''. Ces commandes demandent à la carte graphique d'effectuer une opération 2D, ou une opération 3D, ou encore le rendu d'une vidéo. Les commandes graphiques en question varient beaucoup selon la carte graphique. Les commandes sont régulièrement revues et chaque nouvelle architecture a quelques changements par rapport aux modèles plus anciens. Des commandes peuvent apparaître, d'autres disparaître, d'autre voient leur fonctionnement légèrement altéré, etc. Mais dans les grandes lignes, on peut classer ces commandes en quelques grands types. Les commandes les plus importantes s'occupent de l'affichage 3D : afficher une image à partir de paquets de sommets, préparer le passage d'une image à une autre, changer la résolution, etc. Plus rare, d'autres commandes servent à faire du rendu 2D : afficher un polygone, tracer une ligne, coloriser une surface, etc. Sur les cartes graphiques qui peuvent accélérer le rendu des vidéos, il existe des commandes spécialisées pour l’accélération des vidéos. Pour donner quelques exemples, prenons les commandes 2D de la carte graphique AMD Radeon X1800. {|class="wikitable" |- ! Commandes 2D ! Fonction |- |PAINT |Peindre un rectangle d'une certaine couleur |- |PAINT_MULTI |Peindre des rectangles (pas les mêmes paramètres que PAINT) |- |BITBLT |Copie d'un bloc de mémoire dans un autre |- |BITBLT_MULTI |Plusieurs copies de blocs de mémoire dans d'autres |- |TRANS_BITBLT |Copie de blocs de mémoire avec un masque |- |NEXTCHAR |Afficher un caractère avec une certaine couleur |- |HOSTDATA_BLT |Écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo |- |POLYLINE |Afficher des lignes reliées entre elles |- |POLYSCANLINES |Afficher des lignes |- |PLY_NEXTSCAN |Afficher plusieurs lignes simples |- |SET_SCISSORS |Utiliser des coupes (ciseaux) |- |LOAD_PALETTE |Charger la palette pour affichage 2D |} ===Le tampon de commandes=== L'envoi des commandes à la carte graphique ne se fait pas directement. La carte graphique n'est pas toujours libre pour accepter une nouvelle commande, soit parce qu'elle est occupée par une commande précédente, soit parce qu'elle fait autre chose. Il faut alors faire patienter les données tant que la carte graphique est occupée. Les pilotes de la carte graphique vont les mettre en attente dans le '''tampon de commandes'''. Le tampon de commandes est ce qu'on appelle une file, une zone de mémoire dans laquelle on stocke des données dans l'ordre d'ajout. Si le tampon de commandes est plein, le driver n'accepte plus de demandes en provenance des applications. Un tampon de commandes plein est généralement mauvais signe : cela signifie que la carte graphique est trop lente pour traiter les demandes qui lui sont faites. Par contre, il arrive que le tampon de commandes soit vide : dans ce cas, c'est simplement que la carte graphique est trop rapide comparé au processeur, qui n'arrive alors pas à donner assez de commandes à la carte graphique pour l'occuper suffisamment. Le tampon de commande est soit une mémoire FIFO séparée, soit une portion de la mémoire vidéo. Le NV1, la toute première carte graphique NVIDIA, utilisait une mémoire FIFO intégrée à la carte graphique, séparée des autres circuits. Le processeur envoyait les commandes par rafale au GPU, à savoir qu'il envoyait plusieurs dizaines ou centaines de commandes à la suite, avant de passer à autre chose. Le GPU traitait les commandes une par une, à un rythme bien plus lent. Le processeur pouvait consulter la FIFO pour savoir s'il restait des entrées libres et combien. Le processeur savait ainsi combien d'écritures il pouvait envoyer en une fois au GPU. : Le fonctionnement de la FIFO du NV1 est décrit dans le brevet ''US5805930A : System for FIFO informing the availability of stages to store commands which include data and virtual address sent directly from application programs''. ===Le processeur de commandes=== Le '''processeur de commande''' est un circuit qui gère les commandes envoyées par le processeur. Il lit la commande la plus ancienne dans le tampon de commande, l’interprète et l’exécute, puis passe à la suivante. Le processeur de commande est un circuit assez compliqué. Sur les cartes graphiques anciennes, c'était un circuit séquentiel complexe, fabriqué à la main et était la partie la plus complexe du processeur graphique. Sur les cartes graphiques modernes, c'est un véritable microcontrôleur, avec un processeur, de la mémoire RAM, etc. Le processeur de commandes lit une commande dans le tampon de commande, décode la commande et l’exécute sur la carte graphique. Il garde en mémoire l'état de traitement de chaque commande : est-ce qu'elle est en train de s’exécuter sur le processeur graphique, est-ce qu'elle est mise en pause, est-ce qu'elle attend une donnée en provenance de la mémoire, est-ce qu'elle est terminée, etc. Une commande utilise divers circuits de la carte 3D, de la mémoire vidéo, et d'autres ressources au sens large (des processeurs de ''shader'', notamment). Pour donner un exemple, la première carte graphique de NVIDIA, le NV1, contenait dans le détail : un controleur DMA avec une IO-MMU intégrée, la FIFO de commande, le processeur de commande, un pipeline graphique, un pipeline sonore, un contrôleur de manette. L'ensemble était relié par un bus interne à la carte graphique. Le processeur de commande servait de gestionnaire principal. [[File:Microarchitecture du GPU NV1 de NVIDIA.png|centre|vignette|upright=2|Microarchitecture du GPU NV1 de NVIDIA]] Le processeur de commande pilote les circuits de la carte graphique, il répartit le travail entre les différents circuits de la carte graphique et assure que l'ordre du pipeline est respecté. La fonction principale du processeur de commande est de répartir le travail entre les différents circuits. Le processeur de commande décide à quel processeur ou circuit doit être envoyé une commande. C'est le processeur de commande qui s'occupe de la gestion des ressources et qui attribue telle ressource à telle commande. A chaque instant, le processeur de commande répartit les ''shaders'' sur les processeurs de ''shaders'', en faisant en sorte qu'ils soient utilisés le plus possible. Dans le cas le plus simple, les unités sont alimentées en vertex/pixels les unes après les autres (principe du round-robin), mais des stratégies plus optimisées sont la règle de nos jours. Cela est très important sur les cartes graphiques : répartir plusieurs commandes sur plusieurs processeurs est une tâche difficile. Un chapitre entier sera d'ailleurs dédié à ce sujet. Il envoie aussi certaines commandes aux circuits fixes, comme l’''input assembler''. Là encore, il faut en sorte que les circuits fixes soient utilisés le mieux possible. Sa tâche est compliquée par le fait que les GPU récents ont plusieurs unités de traitement des sommets et des pixels, plusieurs ROP, plusieurs unités de textures, etc. Et c'est en partie le travail du processeur de commande que de répartir les calculs sur ces différentes unités. C'est là un problème assez compliqué pour le processeur de commande et ce pour tout un tas de raisons que nous ne ferons que survoler. Les contraintes d'ordonnancement de l'API et les règles de celle-ci sont une partie de la réponse. Mais d'autres raisons sont intrinsèques au rendu 3D ou à la conception des circuits. [[File:Architecture de base d'une carte 3D - 1.png|centre|vignette|upright=2.5|Architecture de base d'une carte 3D - 1]] ==Le fonctionnement du processeur de commandes== Le processeur de commande lit, décode et exécute des commandes. Intuitivement, on se dit qu'il procède une commande à la fois. Mais les GPU modernes sont plus intelligents et peuvent exécuter plusieurs commandes en même temps, dans des circuits séparés. De nombreuses optimisations de ce type sont utilisées pour gagner en performance. Voyons comment un processeur de commande moderne fonctionne. ===L'ordonnancement et la gestion des ressources=== Le processeur de commande doit souvent mettre en pause certains circuits du pipeline, ainsi que les circuits précédents. Par exemple, si tous les processeurs de ''vertex shader'' sont occupés, l’''input assembler'' ne peut pas charger le paquet suivant car il n'y a aucun processeur de libre pour l’accueillir. Dans ce cas, l'étape d’''input assembly'' est mise en pause en attendant qu'un processeur de ''shader'' soit libre. La même chose a lieu pour l'étape de rastérisation : si aucun processeur de ''shader'' n'est libre, elle est mise en pause. Sauf que pour la rastérisation, cela a des conséquences sur les circuits précédents la rastérisation. Si un processeur de ''shader'' veut envoyer quelque chose au rastériseur alors qu'il est en pause, il devra lui aussi attendre que le rastériseur soit libre. On a la même chose quand les ROP sont occupés : les ''pixel shader'' ou l'unité de texture doivent parfois être mis en pause, ce qui peut entrainer la mise en pause des étapes précédentes, etc. En clair : plus un étape est situé vers la fin du pipeline graphique, plus sa mise en pause a de chances de se répercuter sur les étapes précédentes et de les mettre en pause aussi. Le processeur de commande doit gérer ces situations. ===Le pipelining des commandes=== Dans les cartes graphiques les plus rudimentaires, le processeur de commande exécute les commandes dans l'ordre. Il exécute une commande çà la fois et attend qu'une commande soit terminé pour en lancer une autre. Plusieurs commandes sont accumulées dans le tampon de commande, le processeur de commande les traite de la plus ancienne vers la plus récente. Du moins, les anciennes cartes graphiques faisaient comme cela, les cartes graphiques modernes sont un peu plus complexes. Elles n'attendent pas qu'une commande soit totalement terminée avant d'en lancer une nouvelle. Les processeurs de commande actuels sont capables d’exécuter plusieurs commandes en même temps. L'intérêt est un gain en performance assez important. Pour ceux qui ont déjà eu un cours d'architecture des ordinateurs avancé, lancer plusieurs commandes en même temps permet une forme de pipeline, dont les gains sont substantiels. Par exemple, imaginez qu'une commande de rendu 3D soit bien avancée et n'utilise que les processeurs de ''shaders'' et les ROP, mais laisse les unités géométriques libres. Il est alors possible de démarrer la commande suivante en avance, afin qu'elle remplisse les unités géométriques inutilisées. On a alors deux commandes en cours de traitement : une commande qui utilise la fin du pipeline uniquement, une autre qui utilise seulement le début du pipeline graphique. Le processeur de commande gère donc plusieurs commandes simultanées, à savoir plusieurs commandes qui en sont à des étapes différentes du pipeline. On peut avoir une commande qui est en cours dans l'étage de gestion de la géométrie, une autre dans le rastériseur, et une autre dans les unités de traitement des pixels. Le fait que les étapes du pipeline graphique sont à effectuer dans un ordre bien précis permet ce genre de chose assez facilement. Une autre possibilité est de faire des rendus en parallèle. Par exemple, imaginez qu'on ait des circuits séparés pour le rendu 2D et 3D. Prenons l'exemple où le calcul d'une image finale demande de faire un rendu 3D suivi d'un rendu 2D, par exemple un jeu vidéo en 3D qui a un HUD dessiné en 2D. Dans ce cas, on peut démarrer le calcul de l'image suivante dans le pipeline 3D pendant que la précédente est dans les circuits 2D, au lieu de laisser inutilisé le pipeline 3D pendant le rendu 2D. Mais c'est là un défi compliqué à relever pour le processeur de commande, qui donne lieu à son lot de problèmes. Le problème principal est le partage de ressources entre commandes. Par exemple, on peut prendre le cas où une commande n'utilise pas beaucoup les processeurs de ''shaders''. On pourrait imaginer lancer une seconde commande en parallèle, afin que la seconde commande utiliser les processeurs de ''shaders'' inutilisés. Mais cela n'est possible que si les circuits fixes sont capables d'accepter une seconde commande. Si la première commande sature les circuits fixe, le lancement de la seconde commande sera empêché. Mais si ce n'est pas le cas, les deux commandes pourront être lancées en même temps. Pareil pour le débit mémoire, qui doit alors être partagé entre deux commandes simultanées, ce qui est à prendre en compte. ===La synchronisation de l’exécution des commandes avec le processeur=== Il arrive que le processeur doive savoir où en est le traitement des commandes, ce qui est très utile pour la gestion de la mémoire vidéo. Un premier exemple : comment éviter de saturer une carte graphique de commande, alors qu'on ne sait pas si elles traite les commandes rapidement ou non ? L'idéal est de regarder où en est la carte graphique dans l'exécution des commandes. Si elle n'en est qu'au début du tampon de commande et que celui-ci est bien remplit, alors il vaut mieux lever le pied et ne pas envoyer de nouvelles commandes. A l'inverse, si le tampon de commande est presque vide, envoyer des commandes est la meilleure idée possible. Un autre exemple un peu moins parlant est celui de la gestion de la mémoire vidéo. Rappelons qu'elle est réalisée par le pilote de la carte graphique, sur le processeur principal, qui décide d'allouer et de libérer de la mémoire vidéo. Pour donner un exemple d'utilisation, imaginez que le pilote de la carte graphique doive libérer de la mémoire pour pouvoir ajouter une nouvelle commande. Comment éviter d'enlever une texture tant que les commandes qui l'utilisent ne sont pas terminées ? Ce problème ne se limite pas aux textures, mais vaut pour tout ce qui est placé en mémoire vidéo. Il faut donc que la carte graphique trouve un moyen de prévenir le processeur que le traitement de telle commande est terminée, que telle commande en est rendue à tel ou tel point, etc. Pour cela, on a globalement deux grandes solutions. La première est celle des interruptions, abordées dans les chapitres précédents. Mais elles sont assez couteuses et ne sont utilisées que pour des évènements vraiment importants, critiques, qui demandent une réaction rapide du processeur. L'autre solution est celle du ''pooling'', où le processeur monitore la carte graphique à intervalles réguliers. Deux solutions bien connues de ceux qui ont déjà lu un cours d'architecture des ordinateurs digne de ce nom, rien de bien neuf : la carte graphique communique avec le processeur comme tout périphérique. Pour faciliter l'implémentation du ''pooling'', la carte graphique contient des registres de statut, dans le processeur de commande, qui mémorisent tout ou partie de l'état de la carte graphique. Si un problème survient, certains bits du registre de statut seront mis à 1 pour indiquer que telle erreur bien précise a eu lieu. Il existe aussi un registre de statut qui mémorise le numéro de la commande en cours, ou de la dernière commande terminée, ce qui permet de savoir où en est la carte graphique dans l'exécution des commandes. Et certaines registres de statut sont dédiés à la gestion des commandes. Ils sont totalement programmable, la carte graphique peut écrire dedans sans problème. Les cartes graphiques récentes incorporent des commandes pour modifier ces registres de statut au besoin. Elles sont appelées des '''commandes de synchronisation''' : les barrières (''fences''). Elles permettent d'écrire une valeur dans un registre de statut quand telle ou telle condition est remplie. Par exemple, si jamais une commande est terminée, on peut écrire la valeur 1 dans tel ou tel registre. La condition en question peut être assez complexe et se résumer à quelque chose du genre : "si jamais toutes les ''shaders'' ont fini de traiter tel ensemble de textures, alors écrit la valeur 1024 dans le registre de statut numéro 9". ===La synchronisation de l’exécution des commandes intra-GPU=== Lancer plusieurs commandes en parallèle dans le pipeline permet de gagner en performance.Mais cela a un gros défaut : il n'est pas garantit que les commandes se terminent dans l'ordre. Si on démarre une seconde commande après la première, il arrive que la seconde finisse avant. Pire : il n'est pas garantit qu'elles s'exécutent dans l'ordre. Dans la plupart des cas, cela ne pose pas de problèmes. Mais dans d'autres, cela donne des résultats erronés. Pour donner un exemple, utilisons les commandes de rendu 2D vues plus haut, histoire de simplifier le tout. Imaginez que vous codez un jeu vidéo et que le rendu se fait en 2D, partons sur un jeu de type FPS. Vous avez une série de commandes pour calculer l'image à rendre à l'écran, suivie par une série de commandes finales pour dessiner le HUB. Pour dessiner le HUD, vous utilisez des commandes HOSTDATA_BLT, dont le but est d'écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo. Et bien ces commandes HOSTDATA_BLT doivent démarrer une fois que le rendu de l'image est complétement terminé. Imaginez que vous dessiniez le HUD sur une portion de l'image pas encore terminée et que celui-ci est effacé par des écritures ultérieures ! Pour éviter tout problème, les GPU incorporent des commandes de synchronisation intra-GPU, destinées au processeur de commande, aussis appelées des '''commandes de sémaphore'''. Elles permettent de mettre en pause le lancement d'une nouvelle commande tant que les précédentes ne sont pas totalement ou partiellement terminées. Les plus simples empêchent le démarrage d'une commande tant que les précédentes ne sont pas terminées. D'autres permettent de démarrer une commande si et seulement si certaines commandes sont terminées. D'autres sont encore plus précises : elles empêchent le démarrage d'une nouvelle commande tant qu'une commande précédente n'a pas atteint un certain stade de son exécution. Là encore, de telles commandes sont des commandes du style "attend que le registre de statut numéro N contienne la valeur adéquate avant de poursuivre l'exécution des commandes". Les commandes en question peuvent être sur le même modèle que précédemment, à savoir des commandes qui lisent les registres de statut. Mais elles peuvent aussi se baser sur le fait que telle ou telle ressource de rendu est libre ou non. Des commandes successives se partagent souvent des données, et que de nombreuses commandes différentes peuvent s'exécuter en même temps. Or, si une commande veut modifier les données utilisées par une autre commande, il faut que l'ordre des commandes soit maintenu : la commande la plus récente ne doit pas modifier les données utilisées par une commande plus ancienne. Avec ce modèle, les sémaphores bloquent une commande tant qu'une ressource (une texture) est utilisée par une autre commande. {|class="wikitable" |- ! Commandes de synchronisation ! Fonction |- |NOP |Ne rien faire |- |WAIT_SEMAPHORE |Attendre la synchronisation avec un sémaphore |- |WAIT_MEM |Attendre que la mémoire vidéo soit disponible et inoccupée par le CPU |} ==L'arbitrage de l'accès à la carte graphique== Il n'est pas rare que plusieurs applications souhaitent accéder en même temps à la carte graphique. Imaginons que vous regardez une vidéo en ''streaming'' sur votre navigateur web, avec un programme de ''cloud computing'' de type ''Folding@Home'' qui tourne en arrière-plan, sur Windows. Le décodage de la vidéo est réalisé par la carte graphique, Windows s'occupe de l'affichage du bureau et des fenêtres, le navigateur web doit afficher tout ce qui est autour de la vidéo (la page web), le programme de ''cloud computing'' va lancer ses calculs sur la carte graphique, etc. Des situations de ce genre sont assez courantes et c'est soit le pilote qui s'en charge, soit la carte graphique elle-même. ===L'arbitrage logiciel du GPU=== L'arbitrage logiciel est la méthode la plus simple. Concrètement, c'est le système d'exploitation et/ou le pilote de la carte graphique qui gèrent l'arbitrage du GPU. Dans les deux cas, tout est fait en logiciel. Les commandes sont accumulées dans un tampon de commande, voire plusieurs, et l'OS/pilote décide quelle commande envoyer en priorité. Sur Windows, avant l'arrivée du modèle de driver dit ''Windows Display Driver Model'', de telles situations étaient gérées simplement. Les applications ajoutaient des commandes dans une file de commande unique. Les commandes étaient exécutées dans l'ordre, en mode premier entrée dans la file premier sorti/exécuté. Il n'y avait pour ainsi dire pas d'arbitrage entre les applications. Et ce n'était pas un problème car, à l'époque, les seules applications qui utilisaient le GPU étaient des jeux vidéos fonctionnant en mode plein écran. Avec le modèle de driver ''Windows Display Driver Model'' (WDDM), le GPU est maintenant arbitré, à savoir que les applications ont accès à tour de rôle au GPU, certaines ayant droit à plus de temps GPU que d'autres. Chaque programme a accès à la carte graphique durant quelques dizaines ou centaines de millisecondes, à tour de rôle. Si le programme finissait son travail en moins de temps que la durée impartie, il laissait la main au programme suivant. S’il atteignait la durée maximale allouée, il était interrompu pour laisser la place au programme suivant. Et chaque programme avait droit d'accès à la carte graphique chacun à son tour. Un tel algorithme en tourniquet est très simple, mais avait cependant quelques défauts. De nos jours, les algorithmes d'ordonnancement d'accès sont plus élaborés, bien qu'il soit difficile de trouver de la littérature ou des brevets sur le sujet. Une autre fonctionnalité de WDDM est que les applications utilisant le GPU peuvent se partager la mémoire vidéo sans se marcher dessus. Avant, toutes les applications avaient accès à toute la mémoire vidéo, bien que ce soit par l’intermédiaire de commandes spécifiques. Mais avec WDDM, chaque application dispose de sa propre portion de mémoire vidéo, à laquelle est la seule à avoir accès. Une application ne peut plus lire le contenu réel de la mémoire vidéo, et encore moins lire le contenu des autres applications. : Il s'agit d'un équivalent à l'isolation des processus pour les programmes Windows, mais appliqué à la mémoire vidéo et non la mémoire système. Et cette isolation est rendue d'autant plus simple que les GPU modernes implémentent un système de mémoire virtuelle à pagination très poussé, avec du swap en mémoire RAM système, une protection mémoire, et bien d'autres fonctionnalités. Nous en reparlerons dans les chapitres sur la mémoire vidéo. ===L'arbitrage accéléré par le GPU=== Depuis 2020, avec l'arrivée de la ''Windows 10 May 2020 update'', Windows est capable de déléguer l'arbitrage du GPU au GPU lui-même. Le GPU gère lui-même l'arbitrage, du moins en partie. En partie, car l'OS gére les priorité, à savoir quelle application a droit à plus de temps que les autres. Par contre, la gestion du ''quantum'' de temps ou les commutations de contexte (on stoppe une application pour laisser la place à une autre), est du fait du GPU lui-même. L'avantage est que cela décharge le processeur d'une tâche assez lourde en calcul, pour la déporter sur le GPU. Un autre avantage est que le GPU peut gérer plus finement les ''quantum'' de temps et la commutation de contexte. Le CPU principal gère des durées assez importantes, de l'ordre de la milliseconde. De plus, il doit communiquer avec le GPU par des mécanismes temporellement imprécis, comme des interruptions. Avec l'arbitrage accéléré par le GPU, le GPU n'a plus besoin de communiquer avec le CPU pour l'arbitrage et peut le faire plus précisément, plus immédiatement. Un gain en performance théorique est donc possible. L'arbitrage accéléré par le GPU est le fait soit du processeur de commandes, soit d'un processeur spécialisé, séparé. {{NavChapitre | book=Les cartes graphiques | prev=La hiérarchie mémoire d'un GPU | prevText=La hiérarchie mémoire d'un GPU | next=Le pipeline géométrique d'avant DirectX 10 | netxText=Le pipeline géométrique d'avant DirectX 10 }}{{autocat}} aaxj8lvkma159v81rxhge6n2t7atbph 744039 744038 2025-06-03T14:17:38Z Mewtow 31375 /* Le processeur de commandes */ 744039 wikitext text/x-wiki Dans ce chapitre, nous allons parler de tous les intermédiaires qui se placent entre une application de rendu 3D et les circuits de rendu 3D proprement dit. En premier lieu, on trouve le pilote de la carte graphique, aux fonctions multiples et variées. En second lieu, nous allons parler d'un circuit de la carte graphique qui fait l'interface entre le logiciel et les circuits de rendu 3D de la carte graphique : le processeur de commandes. Ce processeur de commandes est un circuit qui sert de chef d'orchestre, qui pilote le fonctionnement global de la carte graphique. API 3D, pilote de carte graphique et processeur de commande travaillent de concert pour que l'application communique avec la carte graphique. Nous allons d'abord voir le pilote de la carte graphique, avant de voir le fonctionnement du processeur de commande. ==Le pilote de carte graphique== Le pilote de la carte graphique est un logiciel qui s'occupe de faire l'interface entre le logiciel et la carte graphique. De manière générale, les pilotes de périphérique sont des intermédiaires entre les applications/APIs et le matériel. En théorie, le système d'exploitation est censé jouer ce rôle, mais il n'est pas programmé pour être compatible avec tous les périphériques vendus sur le marché. À la place, le système d'exploitation ne gère pas directement certains périphériques, mais fournit de quoi ajouter ce qui manque. Le pilote d'un périphérique sert justement à ajouter ce qui manque : ils ajoutent au système d'exploitation de quoi reconnaître le périphérique, de quoi l'utiliser au mieux. Pour une carte graphique, il a diverses fonctions que nous allons voir ci-dessous. Avant toute chose, précisons que les systèmes d'exploitation usuels (Windows, Linux, MacOsX et autres) sont fournis avec un pilote de carte graphique générique, compatible avec la plupart des cartes graphiques existantes. Rien de magique derrière cela : toutes les cartes graphiques vendues depuis plusieurs décennies respectent des standards, comme le VGA, le VESA, et d'autres. Et le pilote de base fournit avec le système d'exploitation est justement compatible avec ces standards minimaux. Mais le pilote ne peut pas profiter des fonctionnalités qui sont au-delà de ce standard. L'accélération 3D est presque inexistante avec le pilote de base, qui ne sert qu'à faire du rendu 2D (de quoi afficher l’interface de base du système d'exploitation, comme le bureau de Windows). Et même pour du rendu 2D, la plupart des fonctionnalités de la carte graphique ne sont pas disponibles. Par exemple, certaines résolutions ne sont pas disponibles, notamment les grandes résolutions. Ou encore, les performances sont loin d'être excellentes. Si vous avez déjà utilisé un PC sans pilote de carte graphique installé, vous avez certainement remarqué qu'il était particulièrement lent. ===La gestion des interruptions=== Une fonction particulièrement importante du pilote de carte graphique est la réponse aux interruptions lancées par la carte graphique. Pour rappel, les interruptions sont une fonctionnalité qui permet à un périphérique de communiquer avec le processeur, tout en économisant le temps de calcul de ce dernier. Typiquement, lorsqu'un périphérique lance une interruption, le processeur stoppe son travail et exécute automatiquement une routine d'interruption, un petit programme qui s'occupe de gérer le périphérique, de faire ce qu'il faut, ce que l'interruption a demandé. Il y a plusieurs interruptions possibles, chacune ayant son propre numéro et sa fonction dédiée, chacune ayant sa propre routine d'interruption. Après tout, la routine qui gère un débordement de la mémoire vidéo n'est pas la même que celle qui gère un changement de fréquence du GPU ou la fin du calcul d'une image 3D. Le pilote fournit l'ensemble des routines d'interruptions nécessaires pour gérer la carte graphique. ===La compilation des ''shaders''=== Le pilote de carte graphique est aussi chargé de traduire les ''shaders'' en code machine. En soi, cette étape est assez complexe, et ressemble beaucoup à la compilation d'un programme informatique normal. Les ''shaders'' sont écrits dans un langage de programmation de haut niveau, comme le HLSL ou le GLSL, mais ce n'est pas ce code source qui est compilé par le pilote de carte graphique. À la place, les ''shaders'' sont pré-compilés vers un langage dit intermédiaire, avant d'être compilé par le pilote en code machine. Le langage intermédiaire, comme son nom l'indique, sert d'intermédiaire entre le code source écrit en HLSL/GLSL et le code machine exécuté par la carte graphique. Il ressemble à un langage assembleur, mais reste malgré tout assez générique pour ne pas être un véritable code machine. Par exemple, il y a peu de limitations quant au nombre de processeurs ou de registres. En clair, il y a deux passes de compilation : une passe de traduction du code source en langage intermédiaire, puis une passe de compilation du code intermédiaire vers le code machine. Notons que la première passe est réalisée par le programmeur des ''shaders'', non pas par l'utilisateur. Par exemple, les ''shaders'' d'un jeu vidéo sont fournis déjà pré-compilés : les fichiers du jeu ne contiennent pas le code source GLSL/HLSL, mais du code intermédiaire. L'avantage de cette méthode est que le travail du pilote est fortement simplifié. Le pilote de périphérique pourrait compiler directement du code HLSL/GLSL, mais le temps de compilation serait très long et cela aurait un impact sur les performances. Avec l'usage du langage intermédiaire, le gros du travail à été fait lors de la première passe de compilation et le pilote graphique ne fait que finir le travail. Les optimisations importantes ont déjà été réalisées lors de la première passe. Il doit bien faire la traduction, ajouter quelques optimisations de bas niveau par-ci par-là, mais rien de bien gourmand en processeur. Autant dire que cela économise plus le processeur que si on devait compiler complètement les ''shaders'' à chaque exécution. Fait amusant, il faut savoir que le pilote peut parfois remplacer les ''shaders'' d'un jeu vidéo à la volée. Les pilotes récents embarquent en effet des ''shaders'' alternatifs pour les jeux les plus vendus et/ou les plus populaires. Lorsque vous lancez un de ces jeux vidéo et que le ''shader'' originel s'exécute, le pilote le détecte automatiquement et le remplace par la version améliorée, fournie par le pilote. Évidemment, le ''shader'' alternatif du pilote est optimisé pour le matériel adéquat. Cela permet de gagner en performance, voire en qualité d'image, sans pour autant que les concepteurs du jeu n'aient quoique ce soit à faire. Enfin, certains ''shaders'' sont fournis par le pilote pour d'autres raisons. Par exemple, les cartes graphiques récentes n'ont pas de circuits fixes pour traiter la géométrie. Autant les anciennes cartes graphiques avaient des circuits de T&L qui s'en occupaient, autant tout cela doit être émulé sur les machines récentes. Sans cette émulation, les vieux jeux vidéo conçus pour exploiter le T&L et d'autres technologies du genre ne fonctionneraient plus du tout. Émuler les circuits fixes disparus sur les cartes récentes est justement le fait de ''shaders'', présents dans le pilote de carte graphique. ===Les autres fonctions=== Le pilote a aussi bien d'autres fonctions. Par exemple, il s'occupe d'initialiser la carte graphique, de fixer la résolution, d'allouer la mémoire vidéo, de gérer le curseur de souris matériel, etc. ==Les commandes graphiques/vidéo/autres : des ordres envoyés au GPU== Tous les traitements que la carte graphique doit effectuer, qu'il s'agisse de rendu 2D, de calculs 2D, du décodage matérielle d'un flux vidéo, ou de calculs généralistes, sont envoyés par le pilote de la carte graphique, sous la forme de '''commandes'''. Ces commandes demandent à la carte graphique d'effectuer une opération 2D, ou une opération 3D, ou encore le rendu d'une vidéo. Les commandes graphiques en question varient beaucoup selon la carte graphique. Les commandes sont régulièrement revues et chaque nouvelle architecture a quelques changements par rapport aux modèles plus anciens. Des commandes peuvent apparaître, d'autres disparaître, d'autre voient leur fonctionnement légèrement altéré, etc. Mais dans les grandes lignes, on peut classer ces commandes en quelques grands types. Les commandes les plus importantes s'occupent de l'affichage 3D : afficher une image à partir de paquets de sommets, préparer le passage d'une image à une autre, changer la résolution, etc. Plus rare, d'autres commandes servent à faire du rendu 2D : afficher un polygone, tracer une ligne, coloriser une surface, etc. Sur les cartes graphiques qui peuvent accélérer le rendu des vidéos, il existe des commandes spécialisées pour l’accélération des vidéos. Pour donner quelques exemples, prenons les commandes 2D de la carte graphique AMD Radeon X1800. {|class="wikitable" |- ! Commandes 2D ! Fonction |- |PAINT |Peindre un rectangle d'une certaine couleur |- |PAINT_MULTI |Peindre des rectangles (pas les mêmes paramètres que PAINT) |- |BITBLT |Copie d'un bloc de mémoire dans un autre |- |BITBLT_MULTI |Plusieurs copies de blocs de mémoire dans d'autres |- |TRANS_BITBLT |Copie de blocs de mémoire avec un masque |- |NEXTCHAR |Afficher un caractère avec une certaine couleur |- |HOSTDATA_BLT |Écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo |- |POLYLINE |Afficher des lignes reliées entre elles |- |POLYSCANLINES |Afficher des lignes |- |PLY_NEXTSCAN |Afficher plusieurs lignes simples |- |SET_SCISSORS |Utiliser des coupes (ciseaux) |- |LOAD_PALETTE |Charger la palette pour affichage 2D |} ===Le tampon de commandes=== L'envoi des commandes à la carte graphique ne se fait pas directement. La carte graphique n'est pas toujours libre pour accepter une nouvelle commande, soit parce qu'elle est occupée par une commande précédente, soit parce qu'elle fait autre chose. Il faut alors faire patienter les données tant que la carte graphique est occupée. Les pilotes de la carte graphique vont les mettre en attente dans le '''tampon de commandes'''. Le tampon de commandes est ce qu'on appelle une file, une zone de mémoire dans laquelle on stocke des données dans l'ordre d'ajout. Si le tampon de commandes est plein, le driver n'accepte plus de demandes en provenance des applications. Un tampon de commandes plein est généralement mauvais signe : cela signifie que la carte graphique est trop lente pour traiter les demandes qui lui sont faites. Par contre, il arrive que le tampon de commandes soit vide : dans ce cas, c'est simplement que la carte graphique est trop rapide comparé au processeur, qui n'arrive alors pas à donner assez de commandes à la carte graphique pour l'occuper suffisamment. Le tampon de commande est soit une mémoire FIFO séparée, soit une portion de la mémoire vidéo. Le NV1, la toute première carte graphique NVIDIA, utilisait une mémoire FIFO intégrée à la carte graphique, séparée des autres circuits. Le processeur envoyait les commandes par rafale au GPU, à savoir qu'il envoyait plusieurs dizaines ou centaines de commandes à la suite, avant de passer à autre chose. Le GPU traitait les commandes une par une, à un rythme bien plus lent. Le processeur pouvait consulter la FIFO pour savoir s'il restait des entrées libres et combien. Le processeur savait ainsi combien d'écritures il pouvait envoyer en une fois au GPU. : Le fonctionnement de la FIFO du NV1 est décrit dans le brevet ''US5805930A : System for FIFO informing the availability of stages to store commands which include data and virtual address sent directly from application programs''. ===Le processeur de commandes=== Le '''processeur de commande''' est un circuit qui gère les commandes envoyées par le processeur. Il lit la commande la plus ancienne dans le tampon de commande, l’interprète et l’exécute, puis passe à la suivante. Le processeur de commande est un circuit assez compliqué. Sur les cartes graphiques anciennes, c'était un circuit séquentiel complexe, fabriqué à la main et était la partie la plus complexe du processeur graphique. Sur les cartes graphiques modernes, c'est un véritable microcontrôleur, avec un processeur, de la mémoire RAM, etc. Une commande utilise divers circuits de la carte 3D, de la mémoire vidéo, et d'autres ressources au sens large (des processeurs de ''shader'', notamment). Pour donner un exemple, prenons la première carte graphique de NVIDIA, le NV1. Il s'agissait d'une carte multimédia qui incorporait non seulement une carte 2D/3D, mais aussi une carte son un contrôleur de disque et de quoi communiquer avec des manettes. De plus, il incorporait un contrôleur DMA pour échanger des données entre RAM système et les autres circuits. Et à tout cela, il fallait ajouter la FIFO de commandes et le processeur de commande. L'ensemble était relié par un bus interne à la carte graphique. Le processeur de commande servait de gestionnaire principal. Il envoyait des ordres interne aux circuits de rendu 3D, à sa carte son, au contrôleur DMA. Par exemple, lorsque le processeur voulait copier des données en mémoire vidéo, il envoyait une commande de copie, qui était stockée dans le tampon de commande, puis était exécutée par le processeur de commande. Le processeur de commande envoyait alors les ordres adéquats au contrôleur DMA, qui faisait la copie des données. [[File:Microarchitecture du GPU NV1 de NVIDIA.png|centre|vignette|upright=2|Microarchitecture du GPU NV1 de NVIDIA]] Le processeur de commandes lit une commande dans le tampon de commande, décode la commande et l’exécute sur la carte graphique. Il garde en mémoire l'état de traitement de chaque commande : est-ce qu'elle est en train de s’exécuter sur le processeur graphique, est-ce qu'elle est mise en pause, est-ce qu'elle attend une donnée en provenance de la mémoire, est-ce qu'elle est terminée, etc. Le processeur de commande pilote les circuits de la carte graphique, il répartit le travail entre les différents circuits de la carte graphique et assure que l'ordre du pipeline est respecté. La fonction principale du processeur de commande est de répartir le travail entre les différents circuits. Le processeur de commande décide à quel processeur ou circuit doit être envoyé une commande. C'est le processeur de commande qui s'occupe de la gestion des ressources et qui attribue telle ressource à telle commande. A chaque instant, le processeur de commande répartit les ''shaders'' sur les processeurs de ''shaders'', en faisant en sorte qu'ils soient utilisés le plus possible. Dans le cas le plus simple, les unités sont alimentées en vertex/pixels les unes après les autres (principe du round-robin), mais des stratégies plus optimisées sont la règle de nos jours. Cela est très important sur les cartes graphiques : répartir plusieurs commandes sur plusieurs processeurs est une tâche difficile. Un chapitre entier sera d'ailleurs dédié à ce sujet. Il envoie aussi certaines commandes aux circuits fixes, comme l’''input assembler''. Là encore, il faut en sorte que les circuits fixes soient utilisés le mieux possible. Sa tâche est compliquée par le fait que les GPU récents ont plusieurs unités de traitement des sommets et des pixels, plusieurs ROP, plusieurs unités de textures, etc. Et c'est en partie le travail du processeur de commande que de répartir les calculs sur ces différentes unités. C'est là un problème assez compliqué pour le processeur de commande et ce pour tout un tas de raisons que nous ne ferons que survoler. Les contraintes d'ordonnancement de l'API et les règles de celle-ci sont une partie de la réponse. Mais d'autres raisons sont intrinsèques au rendu 3D ou à la conception des circuits. [[File:Architecture de base d'une carte 3D - 1.png|centre|vignette|upright=2.5|Architecture de base d'une carte 3D - 1]] ==Le fonctionnement du processeur de commandes== Le processeur de commande lit, décode et exécute des commandes. Intuitivement, on se dit qu'il procède une commande à la fois. Mais les GPU modernes sont plus intelligents et peuvent exécuter plusieurs commandes en même temps, dans des circuits séparés. De nombreuses optimisations de ce type sont utilisées pour gagner en performance. Voyons comment un processeur de commande moderne fonctionne. ===L'ordonnancement et la gestion des ressources=== Le processeur de commande doit souvent mettre en pause certains circuits du pipeline, ainsi que les circuits précédents. Par exemple, si tous les processeurs de ''vertex shader'' sont occupés, l’''input assembler'' ne peut pas charger le paquet suivant car il n'y a aucun processeur de libre pour l’accueillir. Dans ce cas, l'étape d’''input assembly'' est mise en pause en attendant qu'un processeur de ''shader'' soit libre. La même chose a lieu pour l'étape de rastérisation : si aucun processeur de ''shader'' n'est libre, elle est mise en pause. Sauf que pour la rastérisation, cela a des conséquences sur les circuits précédents la rastérisation. Si un processeur de ''shader'' veut envoyer quelque chose au rastériseur alors qu'il est en pause, il devra lui aussi attendre que le rastériseur soit libre. On a la même chose quand les ROP sont occupés : les ''pixel shader'' ou l'unité de texture doivent parfois être mis en pause, ce qui peut entrainer la mise en pause des étapes précédentes, etc. En clair : plus un étape est situé vers la fin du pipeline graphique, plus sa mise en pause a de chances de se répercuter sur les étapes précédentes et de les mettre en pause aussi. Le processeur de commande doit gérer ces situations. ===Le pipelining des commandes=== Dans les cartes graphiques les plus rudimentaires, le processeur de commande exécute les commandes dans l'ordre. Il exécute une commande çà la fois et attend qu'une commande soit terminé pour en lancer une autre. Plusieurs commandes sont accumulées dans le tampon de commande, le processeur de commande les traite de la plus ancienne vers la plus récente. Du moins, les anciennes cartes graphiques faisaient comme cela, les cartes graphiques modernes sont un peu plus complexes. Elles n'attendent pas qu'une commande soit totalement terminée avant d'en lancer une nouvelle. Les processeurs de commande actuels sont capables d’exécuter plusieurs commandes en même temps. L'intérêt est un gain en performance assez important. Pour ceux qui ont déjà eu un cours d'architecture des ordinateurs avancé, lancer plusieurs commandes en même temps permet une forme de pipeline, dont les gains sont substantiels. Par exemple, imaginez qu'une commande de rendu 3D soit bien avancée et n'utilise que les processeurs de ''shaders'' et les ROP, mais laisse les unités géométriques libres. Il est alors possible de démarrer la commande suivante en avance, afin qu'elle remplisse les unités géométriques inutilisées. On a alors deux commandes en cours de traitement : une commande qui utilise la fin du pipeline uniquement, une autre qui utilise seulement le début du pipeline graphique. Le processeur de commande gère donc plusieurs commandes simultanées, à savoir plusieurs commandes qui en sont à des étapes différentes du pipeline. On peut avoir une commande qui est en cours dans l'étage de gestion de la géométrie, une autre dans le rastériseur, et une autre dans les unités de traitement des pixels. Le fait que les étapes du pipeline graphique sont à effectuer dans un ordre bien précis permet ce genre de chose assez facilement. Une autre possibilité est de faire des rendus en parallèle. Par exemple, imaginez qu'on ait des circuits séparés pour le rendu 2D et 3D. Prenons l'exemple où le calcul d'une image finale demande de faire un rendu 3D suivi d'un rendu 2D, par exemple un jeu vidéo en 3D qui a un HUD dessiné en 2D. Dans ce cas, on peut démarrer le calcul de l'image suivante dans le pipeline 3D pendant que la précédente est dans les circuits 2D, au lieu de laisser inutilisé le pipeline 3D pendant le rendu 2D. Mais c'est là un défi compliqué à relever pour le processeur de commande, qui donne lieu à son lot de problèmes. Le problème principal est le partage de ressources entre commandes. Par exemple, on peut prendre le cas où une commande n'utilise pas beaucoup les processeurs de ''shaders''. On pourrait imaginer lancer une seconde commande en parallèle, afin que la seconde commande utiliser les processeurs de ''shaders'' inutilisés. Mais cela n'est possible que si les circuits fixes sont capables d'accepter une seconde commande. Si la première commande sature les circuits fixe, le lancement de la seconde commande sera empêché. Mais si ce n'est pas le cas, les deux commandes pourront être lancées en même temps. Pareil pour le débit mémoire, qui doit alors être partagé entre deux commandes simultanées, ce qui est à prendre en compte. ===La synchronisation de l’exécution des commandes avec le processeur=== Il arrive que le processeur doive savoir où en est le traitement des commandes, ce qui est très utile pour la gestion de la mémoire vidéo. Un premier exemple : comment éviter de saturer une carte graphique de commande, alors qu'on ne sait pas si elles traite les commandes rapidement ou non ? L'idéal est de regarder où en est la carte graphique dans l'exécution des commandes. Si elle n'en est qu'au début du tampon de commande et que celui-ci est bien remplit, alors il vaut mieux lever le pied et ne pas envoyer de nouvelles commandes. A l'inverse, si le tampon de commande est presque vide, envoyer des commandes est la meilleure idée possible. Un autre exemple un peu moins parlant est celui de la gestion de la mémoire vidéo. Rappelons qu'elle est réalisée par le pilote de la carte graphique, sur le processeur principal, qui décide d'allouer et de libérer de la mémoire vidéo. Pour donner un exemple d'utilisation, imaginez que le pilote de la carte graphique doive libérer de la mémoire pour pouvoir ajouter une nouvelle commande. Comment éviter d'enlever une texture tant que les commandes qui l'utilisent ne sont pas terminées ? Ce problème ne se limite pas aux textures, mais vaut pour tout ce qui est placé en mémoire vidéo. Il faut donc que la carte graphique trouve un moyen de prévenir le processeur que le traitement de telle commande est terminée, que telle commande en est rendue à tel ou tel point, etc. Pour cela, on a globalement deux grandes solutions. La première est celle des interruptions, abordées dans les chapitres précédents. Mais elles sont assez couteuses et ne sont utilisées que pour des évènements vraiment importants, critiques, qui demandent une réaction rapide du processeur. L'autre solution est celle du ''pooling'', où le processeur monitore la carte graphique à intervalles réguliers. Deux solutions bien connues de ceux qui ont déjà lu un cours d'architecture des ordinateurs digne de ce nom, rien de bien neuf : la carte graphique communique avec le processeur comme tout périphérique. Pour faciliter l'implémentation du ''pooling'', la carte graphique contient des registres de statut, dans le processeur de commande, qui mémorisent tout ou partie de l'état de la carte graphique. Si un problème survient, certains bits du registre de statut seront mis à 1 pour indiquer que telle erreur bien précise a eu lieu. Il existe aussi un registre de statut qui mémorise le numéro de la commande en cours, ou de la dernière commande terminée, ce qui permet de savoir où en est la carte graphique dans l'exécution des commandes. Et certaines registres de statut sont dédiés à la gestion des commandes. Ils sont totalement programmable, la carte graphique peut écrire dedans sans problème. Les cartes graphiques récentes incorporent des commandes pour modifier ces registres de statut au besoin. Elles sont appelées des '''commandes de synchronisation''' : les barrières (''fences''). Elles permettent d'écrire une valeur dans un registre de statut quand telle ou telle condition est remplie. Par exemple, si jamais une commande est terminée, on peut écrire la valeur 1 dans tel ou tel registre. La condition en question peut être assez complexe et se résumer à quelque chose du genre : "si jamais toutes les ''shaders'' ont fini de traiter tel ensemble de textures, alors écrit la valeur 1024 dans le registre de statut numéro 9". ===La synchronisation de l’exécution des commandes intra-GPU=== Lancer plusieurs commandes en parallèle dans le pipeline permet de gagner en performance.Mais cela a un gros défaut : il n'est pas garantit que les commandes se terminent dans l'ordre. Si on démarre une seconde commande après la première, il arrive que la seconde finisse avant. Pire : il n'est pas garantit qu'elles s'exécutent dans l'ordre. Dans la plupart des cas, cela ne pose pas de problèmes. Mais dans d'autres, cela donne des résultats erronés. Pour donner un exemple, utilisons les commandes de rendu 2D vues plus haut, histoire de simplifier le tout. Imaginez que vous codez un jeu vidéo et que le rendu se fait en 2D, partons sur un jeu de type FPS. Vous avez une série de commandes pour calculer l'image à rendre à l'écran, suivie par une série de commandes finales pour dessiner le HUB. Pour dessiner le HUD, vous utilisez des commandes HOSTDATA_BLT, dont le but est d'écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo. Et bien ces commandes HOSTDATA_BLT doivent démarrer une fois que le rendu de l'image est complétement terminé. Imaginez que vous dessiniez le HUD sur une portion de l'image pas encore terminée et que celui-ci est effacé par des écritures ultérieures ! Pour éviter tout problème, les GPU incorporent des commandes de synchronisation intra-GPU, destinées au processeur de commande, aussis appelées des '''commandes de sémaphore'''. Elles permettent de mettre en pause le lancement d'une nouvelle commande tant que les précédentes ne sont pas totalement ou partiellement terminées. Les plus simples empêchent le démarrage d'une commande tant que les précédentes ne sont pas terminées. D'autres permettent de démarrer une commande si et seulement si certaines commandes sont terminées. D'autres sont encore plus précises : elles empêchent le démarrage d'une nouvelle commande tant qu'une commande précédente n'a pas atteint un certain stade de son exécution. Là encore, de telles commandes sont des commandes du style "attend que le registre de statut numéro N contienne la valeur adéquate avant de poursuivre l'exécution des commandes". Les commandes en question peuvent être sur le même modèle que précédemment, à savoir des commandes qui lisent les registres de statut. Mais elles peuvent aussi se baser sur le fait que telle ou telle ressource de rendu est libre ou non. Des commandes successives se partagent souvent des données, et que de nombreuses commandes différentes peuvent s'exécuter en même temps. Or, si une commande veut modifier les données utilisées par une autre commande, il faut que l'ordre des commandes soit maintenu : la commande la plus récente ne doit pas modifier les données utilisées par une commande plus ancienne. Avec ce modèle, les sémaphores bloquent une commande tant qu'une ressource (une texture) est utilisée par une autre commande. {|class="wikitable" |- ! Commandes de synchronisation ! Fonction |- |NOP |Ne rien faire |- |WAIT_SEMAPHORE |Attendre la synchronisation avec un sémaphore |- |WAIT_MEM |Attendre que la mémoire vidéo soit disponible et inoccupée par le CPU |} ==L'arbitrage de l'accès à la carte graphique== Il n'est pas rare que plusieurs applications souhaitent accéder en même temps à la carte graphique. Imaginons que vous regardez une vidéo en ''streaming'' sur votre navigateur web, avec un programme de ''cloud computing'' de type ''Folding@Home'' qui tourne en arrière-plan, sur Windows. Le décodage de la vidéo est réalisé par la carte graphique, Windows s'occupe de l'affichage du bureau et des fenêtres, le navigateur web doit afficher tout ce qui est autour de la vidéo (la page web), le programme de ''cloud computing'' va lancer ses calculs sur la carte graphique, etc. Des situations de ce genre sont assez courantes et c'est soit le pilote qui s'en charge, soit la carte graphique elle-même. ===L'arbitrage logiciel du GPU=== L'arbitrage logiciel est la méthode la plus simple. Concrètement, c'est le système d'exploitation et/ou le pilote de la carte graphique qui gèrent l'arbitrage du GPU. Dans les deux cas, tout est fait en logiciel. Les commandes sont accumulées dans un tampon de commande, voire plusieurs, et l'OS/pilote décide quelle commande envoyer en priorité. Sur Windows, avant l'arrivée du modèle de driver dit ''Windows Display Driver Model'', de telles situations étaient gérées simplement. Les applications ajoutaient des commandes dans une file de commande unique. Les commandes étaient exécutées dans l'ordre, en mode premier entrée dans la file premier sorti/exécuté. Il n'y avait pour ainsi dire pas d'arbitrage entre les applications. Et ce n'était pas un problème car, à l'époque, les seules applications qui utilisaient le GPU étaient des jeux vidéos fonctionnant en mode plein écran. Avec le modèle de driver ''Windows Display Driver Model'' (WDDM), le GPU est maintenant arbitré, à savoir que les applications ont accès à tour de rôle au GPU, certaines ayant droit à plus de temps GPU que d'autres. Chaque programme a accès à la carte graphique durant quelques dizaines ou centaines de millisecondes, à tour de rôle. Si le programme finissait son travail en moins de temps que la durée impartie, il laissait la main au programme suivant. S’il atteignait la durée maximale allouée, il était interrompu pour laisser la place au programme suivant. Et chaque programme avait droit d'accès à la carte graphique chacun à son tour. Un tel algorithme en tourniquet est très simple, mais avait cependant quelques défauts. De nos jours, les algorithmes d'ordonnancement d'accès sont plus élaborés, bien qu'il soit difficile de trouver de la littérature ou des brevets sur le sujet. Une autre fonctionnalité de WDDM est que les applications utilisant le GPU peuvent se partager la mémoire vidéo sans se marcher dessus. Avant, toutes les applications avaient accès à toute la mémoire vidéo, bien que ce soit par l’intermédiaire de commandes spécifiques. Mais avec WDDM, chaque application dispose de sa propre portion de mémoire vidéo, à laquelle est la seule à avoir accès. Une application ne peut plus lire le contenu réel de la mémoire vidéo, et encore moins lire le contenu des autres applications. : Il s'agit d'un équivalent à l'isolation des processus pour les programmes Windows, mais appliqué à la mémoire vidéo et non la mémoire système. Et cette isolation est rendue d'autant plus simple que les GPU modernes implémentent un système de mémoire virtuelle à pagination très poussé, avec du swap en mémoire RAM système, une protection mémoire, et bien d'autres fonctionnalités. Nous en reparlerons dans les chapitres sur la mémoire vidéo. ===L'arbitrage accéléré par le GPU=== Depuis 2020, avec l'arrivée de la ''Windows 10 May 2020 update'', Windows est capable de déléguer l'arbitrage du GPU au GPU lui-même. Le GPU gère lui-même l'arbitrage, du moins en partie. En partie, car l'OS gére les priorité, à savoir quelle application a droit à plus de temps que les autres. Par contre, la gestion du ''quantum'' de temps ou les commutations de contexte (on stoppe une application pour laisser la place à une autre), est du fait du GPU lui-même. L'avantage est que cela décharge le processeur d'une tâche assez lourde en calcul, pour la déporter sur le GPU. Un autre avantage est que le GPU peut gérer plus finement les ''quantum'' de temps et la commutation de contexte. Le CPU principal gère des durées assez importantes, de l'ordre de la milliseconde. De plus, il doit communiquer avec le GPU par des mécanismes temporellement imprécis, comme des interruptions. Avec l'arbitrage accéléré par le GPU, le GPU n'a plus besoin de communiquer avec le CPU pour l'arbitrage et peut le faire plus précisément, plus immédiatement. Un gain en performance théorique est donc possible. L'arbitrage accéléré par le GPU est le fait soit du processeur de commandes, soit d'un processeur spécialisé, séparé. {{NavChapitre | book=Les cartes graphiques | prev=La hiérarchie mémoire d'un GPU | prevText=La hiérarchie mémoire d'un GPU | next=Le pipeline géométrique d'avant DirectX 10 | netxText=Le pipeline géométrique d'avant DirectX 10 }}{{autocat}} l28htpqczxe3lslqksy9ny04mi7k0fr 744040 744039 2025-06-03T14:20:32Z Mewtow 31375 /* Le processeur de commandes */ 744040 wikitext text/x-wiki Dans ce chapitre, nous allons parler de tous les intermédiaires qui se placent entre une application de rendu 3D et les circuits de rendu 3D proprement dit. En premier lieu, on trouve le pilote de la carte graphique, aux fonctions multiples et variées. En second lieu, nous allons parler d'un circuit de la carte graphique qui fait l'interface entre le logiciel et les circuits de rendu 3D de la carte graphique : le processeur de commandes. Ce processeur de commandes est un circuit qui sert de chef d'orchestre, qui pilote le fonctionnement global de la carte graphique. API 3D, pilote de carte graphique et processeur de commande travaillent de concert pour que l'application communique avec la carte graphique. Nous allons d'abord voir le pilote de la carte graphique, avant de voir le fonctionnement du processeur de commande. ==Le pilote de carte graphique== Le pilote de la carte graphique est un logiciel qui s'occupe de faire l'interface entre le logiciel et la carte graphique. De manière générale, les pilotes de périphérique sont des intermédiaires entre les applications/APIs et le matériel. En théorie, le système d'exploitation est censé jouer ce rôle, mais il n'est pas programmé pour être compatible avec tous les périphériques vendus sur le marché. À la place, le système d'exploitation ne gère pas directement certains périphériques, mais fournit de quoi ajouter ce qui manque. Le pilote d'un périphérique sert justement à ajouter ce qui manque : ils ajoutent au système d'exploitation de quoi reconnaître le périphérique, de quoi l'utiliser au mieux. Pour une carte graphique, il a diverses fonctions que nous allons voir ci-dessous. Avant toute chose, précisons que les systèmes d'exploitation usuels (Windows, Linux, MacOsX et autres) sont fournis avec un pilote de carte graphique générique, compatible avec la plupart des cartes graphiques existantes. Rien de magique derrière cela : toutes les cartes graphiques vendues depuis plusieurs décennies respectent des standards, comme le VGA, le VESA, et d'autres. Et le pilote de base fournit avec le système d'exploitation est justement compatible avec ces standards minimaux. Mais le pilote ne peut pas profiter des fonctionnalités qui sont au-delà de ce standard. L'accélération 3D est presque inexistante avec le pilote de base, qui ne sert qu'à faire du rendu 2D (de quoi afficher l’interface de base du système d'exploitation, comme le bureau de Windows). Et même pour du rendu 2D, la plupart des fonctionnalités de la carte graphique ne sont pas disponibles. Par exemple, certaines résolutions ne sont pas disponibles, notamment les grandes résolutions. Ou encore, les performances sont loin d'être excellentes. Si vous avez déjà utilisé un PC sans pilote de carte graphique installé, vous avez certainement remarqué qu'il était particulièrement lent. ===La gestion des interruptions=== Une fonction particulièrement importante du pilote de carte graphique est la réponse aux interruptions lancées par la carte graphique. Pour rappel, les interruptions sont une fonctionnalité qui permet à un périphérique de communiquer avec le processeur, tout en économisant le temps de calcul de ce dernier. Typiquement, lorsqu'un périphérique lance une interruption, le processeur stoppe son travail et exécute automatiquement une routine d'interruption, un petit programme qui s'occupe de gérer le périphérique, de faire ce qu'il faut, ce que l'interruption a demandé. Il y a plusieurs interruptions possibles, chacune ayant son propre numéro et sa fonction dédiée, chacune ayant sa propre routine d'interruption. Après tout, la routine qui gère un débordement de la mémoire vidéo n'est pas la même que celle qui gère un changement de fréquence du GPU ou la fin du calcul d'une image 3D. Le pilote fournit l'ensemble des routines d'interruptions nécessaires pour gérer la carte graphique. ===La compilation des ''shaders''=== Le pilote de carte graphique est aussi chargé de traduire les ''shaders'' en code machine. En soi, cette étape est assez complexe, et ressemble beaucoup à la compilation d'un programme informatique normal. Les ''shaders'' sont écrits dans un langage de programmation de haut niveau, comme le HLSL ou le GLSL, mais ce n'est pas ce code source qui est compilé par le pilote de carte graphique. À la place, les ''shaders'' sont pré-compilés vers un langage dit intermédiaire, avant d'être compilé par le pilote en code machine. Le langage intermédiaire, comme son nom l'indique, sert d'intermédiaire entre le code source écrit en HLSL/GLSL et le code machine exécuté par la carte graphique. Il ressemble à un langage assembleur, mais reste malgré tout assez générique pour ne pas être un véritable code machine. Par exemple, il y a peu de limitations quant au nombre de processeurs ou de registres. En clair, il y a deux passes de compilation : une passe de traduction du code source en langage intermédiaire, puis une passe de compilation du code intermédiaire vers le code machine. Notons que la première passe est réalisée par le programmeur des ''shaders'', non pas par l'utilisateur. Par exemple, les ''shaders'' d'un jeu vidéo sont fournis déjà pré-compilés : les fichiers du jeu ne contiennent pas le code source GLSL/HLSL, mais du code intermédiaire. L'avantage de cette méthode est que le travail du pilote est fortement simplifié. Le pilote de périphérique pourrait compiler directement du code HLSL/GLSL, mais le temps de compilation serait très long et cela aurait un impact sur les performances. Avec l'usage du langage intermédiaire, le gros du travail à été fait lors de la première passe de compilation et le pilote graphique ne fait que finir le travail. Les optimisations importantes ont déjà été réalisées lors de la première passe. Il doit bien faire la traduction, ajouter quelques optimisations de bas niveau par-ci par-là, mais rien de bien gourmand en processeur. Autant dire que cela économise plus le processeur que si on devait compiler complètement les ''shaders'' à chaque exécution. Fait amusant, il faut savoir que le pilote peut parfois remplacer les ''shaders'' d'un jeu vidéo à la volée. Les pilotes récents embarquent en effet des ''shaders'' alternatifs pour les jeux les plus vendus et/ou les plus populaires. Lorsque vous lancez un de ces jeux vidéo et que le ''shader'' originel s'exécute, le pilote le détecte automatiquement et le remplace par la version améliorée, fournie par le pilote. Évidemment, le ''shader'' alternatif du pilote est optimisé pour le matériel adéquat. Cela permet de gagner en performance, voire en qualité d'image, sans pour autant que les concepteurs du jeu n'aient quoique ce soit à faire. Enfin, certains ''shaders'' sont fournis par le pilote pour d'autres raisons. Par exemple, les cartes graphiques récentes n'ont pas de circuits fixes pour traiter la géométrie. Autant les anciennes cartes graphiques avaient des circuits de T&L qui s'en occupaient, autant tout cela doit être émulé sur les machines récentes. Sans cette émulation, les vieux jeux vidéo conçus pour exploiter le T&L et d'autres technologies du genre ne fonctionneraient plus du tout. Émuler les circuits fixes disparus sur les cartes récentes est justement le fait de ''shaders'', présents dans le pilote de carte graphique. ===Les autres fonctions=== Le pilote a aussi bien d'autres fonctions. Par exemple, il s'occupe d'initialiser la carte graphique, de fixer la résolution, d'allouer la mémoire vidéo, de gérer le curseur de souris matériel, etc. ==Les commandes graphiques/vidéo/autres : des ordres envoyés au GPU== Tous les traitements que la carte graphique doit effectuer, qu'il s'agisse de rendu 2D, de calculs 2D, du décodage matérielle d'un flux vidéo, ou de calculs généralistes, sont envoyés par le pilote de la carte graphique, sous la forme de '''commandes'''. Ces commandes demandent à la carte graphique d'effectuer une opération 2D, ou une opération 3D, ou encore le rendu d'une vidéo. Les commandes graphiques en question varient beaucoup selon la carte graphique. Les commandes sont régulièrement revues et chaque nouvelle architecture a quelques changements par rapport aux modèles plus anciens. Des commandes peuvent apparaître, d'autres disparaître, d'autre voient leur fonctionnement légèrement altéré, etc. Mais dans les grandes lignes, on peut classer ces commandes en quelques grands types. Les commandes les plus importantes s'occupent de l'affichage 3D : afficher une image à partir de paquets de sommets, préparer le passage d'une image à une autre, changer la résolution, etc. Plus rare, d'autres commandes servent à faire du rendu 2D : afficher un polygone, tracer une ligne, coloriser une surface, etc. Sur les cartes graphiques qui peuvent accélérer le rendu des vidéos, il existe des commandes spécialisées pour l’accélération des vidéos. Pour donner quelques exemples, prenons les commandes 2D de la carte graphique AMD Radeon X1800. {|class="wikitable" |- ! Commandes 2D ! Fonction |- |PAINT |Peindre un rectangle d'une certaine couleur |- |PAINT_MULTI |Peindre des rectangles (pas les mêmes paramètres que PAINT) |- |BITBLT |Copie d'un bloc de mémoire dans un autre |- |BITBLT_MULTI |Plusieurs copies de blocs de mémoire dans d'autres |- |TRANS_BITBLT |Copie de blocs de mémoire avec un masque |- |NEXTCHAR |Afficher un caractère avec une certaine couleur |- |HOSTDATA_BLT |Écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo |- |POLYLINE |Afficher des lignes reliées entre elles |- |POLYSCANLINES |Afficher des lignes |- |PLY_NEXTSCAN |Afficher plusieurs lignes simples |- |SET_SCISSORS |Utiliser des coupes (ciseaux) |- |LOAD_PALETTE |Charger la palette pour affichage 2D |} ===Le tampon de commandes=== L'envoi des commandes à la carte graphique ne se fait pas directement. La carte graphique n'est pas toujours libre pour accepter une nouvelle commande, soit parce qu'elle est occupée par une commande précédente, soit parce qu'elle fait autre chose. Il faut alors faire patienter les données tant que la carte graphique est occupée. Les pilotes de la carte graphique vont les mettre en attente dans le '''tampon de commandes'''. Le tampon de commandes est ce qu'on appelle une file, une zone de mémoire dans laquelle on stocke des données dans l'ordre d'ajout. Si le tampon de commandes est plein, le driver n'accepte plus de demandes en provenance des applications. Un tampon de commandes plein est généralement mauvais signe : cela signifie que la carte graphique est trop lente pour traiter les demandes qui lui sont faites. Par contre, il arrive que le tampon de commandes soit vide : dans ce cas, c'est simplement que la carte graphique est trop rapide comparé au processeur, qui n'arrive alors pas à donner assez de commandes à la carte graphique pour l'occuper suffisamment. Le tampon de commande est soit une mémoire FIFO séparée, soit une portion de la mémoire vidéo. Le NV1, la toute première carte graphique NVIDIA, utilisait une mémoire FIFO intégrée à la carte graphique, séparée des autres circuits. Le processeur envoyait les commandes par rafale au GPU, à savoir qu'il envoyait plusieurs dizaines ou centaines de commandes à la suite, avant de passer à autre chose. Le GPU traitait les commandes une par une, à un rythme bien plus lent. Le processeur pouvait consulter la FIFO pour savoir s'il restait des entrées libres et combien. Le processeur savait ainsi combien d'écritures il pouvait envoyer en une fois au GPU. : Le fonctionnement de la FIFO du NV1 est décrit dans le brevet ''US5805930A : System for FIFO informing the availability of stages to store commands which include data and virtual address sent directly from application programs''. ===Le processeur de commandes=== Le '''processeur de commande''' est un circuit qui gère les commandes envoyées par le processeur. Il lit la commande la plus ancienne dans le tampon de commande, l’interprète, l’exécute, puis passe à la suivante. Le processeur de commande est un circuit assez compliqué. Sur les cartes graphiques anciennes, c'était un circuit séquentiel complexe, fabriqué à la main et était la partie la plus complexe du processeur graphique. Sur les cartes graphiques modernes, c'est un véritable microcontrôleur, avec un processeur, de la mémoire RAM, etc. Lors de l'exécution d'une commande, le processeur de commande pilote les circuits de la carte graphique. Précisément, il répartit le travail entre les différents circuits de la carte graphique et assure que l'ordre du pipeline est respecté. Le processeur de commande décide à quel processeur ou circuit doit être envoyé une commande. Pour donner un exemple, prenons la première carte graphique de NVIDIA, le NV1. Il s'agissait d'une carte multimédia qui incorporait non seulement une carte 2D/3D, mais aussi une carte son un contrôleur de disque et de quoi communiquer avec des manettes. De plus, il incorporait un contrôleur DMA pour échanger des données entre RAM système et les autres circuits. Et à tout cela, il fallait ajouter la FIFO de commandes et le processeur de commande. L'ensemble était relié par un bus interne à la carte graphique. Le processeur de commande servait de gestionnaire principal. Il envoyait des ordres interne aux circuits de rendu 3D, à sa carte son, au contrôleur DMA. Par exemple, lorsque le processeur voulait copier des données en mémoire vidéo, il envoyait une commande de copie, qui était stockée dans le tampon de commande, puis était exécutée par le processeur de commande. Le processeur de commande envoyait alors les ordres adéquats au contrôleur DMA, qui faisait la copie des données. Lors d'un rendu 3D, une commande de rendu 3D est envoyée au NV1, le processeur de commande la traite et l'envoi dans les circuits de rendu 3D. [[File:Microarchitecture du GPU NV1 de NVIDIA.png|centre|vignette|upright=2|Microarchitecture du GPU NV1 de NVIDIA]] Le processeur de commandes garde en mémoire l'état de traitement de chaque commande : est-ce qu'elle est en train de s’exécuter sur le processeur graphique, est-ce qu'elle est mise en pause, est-ce qu'elle attend une donnée en provenance de la mémoire, est-ce qu'elle est terminée, etc. A chaque instant, le processeur de commande répartit les ''shaders'' sur les processeurs de ''shaders'', en faisant en sorte qu'ils soient utilisés le plus possible. Dans le cas le plus simple, les unités sont alimentées en vertex/pixels les unes après les autres (principe du round-robin), mais des stratégies plus optimisées sont la règle de nos jours. Cela est très important sur les cartes graphiques : répartir plusieurs commandes sur plusieurs processeurs est une tâche difficile. Un chapitre entier sera d'ailleurs dédié à ce sujet. Il envoie aussi certaines commandes aux circuits fixes, comme l’''input assembler''. Là encore, il faut en sorte que les circuits fixes soient utilisés le mieux possible. Sa tâche est compliquée par le fait que les GPU récents ont plusieurs unités de traitement des sommets et des pixels, plusieurs ROP, plusieurs unités de textures, etc. Et c'est en partie le travail du processeur de commande que de répartir les calculs sur ces différentes unités. C'est là un problème assez compliqué pour le processeur de commande et ce pour tout un tas de raisons que nous ne ferons que survoler. Les contraintes d'ordonnancement de l'API et les règles de celle-ci sont une partie de la réponse. Mais d'autres raisons sont intrinsèques au rendu 3D ou à la conception des circuits. [[File:Architecture de base d'une carte 3D - 1.png|centre|vignette|upright=2.5|Architecture de base d'une carte 3D - 1]] ==Le fonctionnement du processeur de commandes== Le processeur de commande lit, décode et exécute des commandes. Intuitivement, on se dit qu'il procède une commande à la fois. Mais les GPU modernes sont plus intelligents et peuvent exécuter plusieurs commandes en même temps, dans des circuits séparés. De nombreuses optimisations de ce type sont utilisées pour gagner en performance. Voyons comment un processeur de commande moderne fonctionne. ===L'ordonnancement et la gestion des ressources=== Le processeur de commande doit souvent mettre en pause certains circuits du pipeline, ainsi que les circuits précédents. Par exemple, si tous les processeurs de ''vertex shader'' sont occupés, l’''input assembler'' ne peut pas charger le paquet suivant car il n'y a aucun processeur de libre pour l’accueillir. Dans ce cas, l'étape d’''input assembly'' est mise en pause en attendant qu'un processeur de ''shader'' soit libre. La même chose a lieu pour l'étape de rastérisation : si aucun processeur de ''shader'' n'est libre, elle est mise en pause. Sauf que pour la rastérisation, cela a des conséquences sur les circuits précédents la rastérisation. Si un processeur de ''shader'' veut envoyer quelque chose au rastériseur alors qu'il est en pause, il devra lui aussi attendre que le rastériseur soit libre. On a la même chose quand les ROP sont occupés : les ''pixel shader'' ou l'unité de texture doivent parfois être mis en pause, ce qui peut entrainer la mise en pause des étapes précédentes, etc. En clair : plus un étape est situé vers la fin du pipeline graphique, plus sa mise en pause a de chances de se répercuter sur les étapes précédentes et de les mettre en pause aussi. Le processeur de commande doit gérer ces situations. ===Le pipelining des commandes=== Dans les cartes graphiques les plus rudimentaires, le processeur de commande exécute les commandes dans l'ordre. Il exécute une commande çà la fois et attend qu'une commande soit terminé pour en lancer une autre. Plusieurs commandes sont accumulées dans le tampon de commande, le processeur de commande les traite de la plus ancienne vers la plus récente. Du moins, les anciennes cartes graphiques faisaient comme cela, les cartes graphiques modernes sont un peu plus complexes. Elles n'attendent pas qu'une commande soit totalement terminée avant d'en lancer une nouvelle. Les processeurs de commande actuels sont capables d’exécuter plusieurs commandes en même temps. L'intérêt est un gain en performance assez important. Pour ceux qui ont déjà eu un cours d'architecture des ordinateurs avancé, lancer plusieurs commandes en même temps permet une forme de pipeline, dont les gains sont substantiels. Par exemple, imaginez qu'une commande de rendu 3D soit bien avancée et n'utilise que les processeurs de ''shaders'' et les ROP, mais laisse les unités géométriques libres. Il est alors possible de démarrer la commande suivante en avance, afin qu'elle remplisse les unités géométriques inutilisées. On a alors deux commandes en cours de traitement : une commande qui utilise la fin du pipeline uniquement, une autre qui utilise seulement le début du pipeline graphique. Le processeur de commande gère donc plusieurs commandes simultanées, à savoir plusieurs commandes qui en sont à des étapes différentes du pipeline. On peut avoir une commande qui est en cours dans l'étage de gestion de la géométrie, une autre dans le rastériseur, et une autre dans les unités de traitement des pixels. Le fait que les étapes du pipeline graphique sont à effectuer dans un ordre bien précis permet ce genre de chose assez facilement. Une autre possibilité est de faire des rendus en parallèle. Par exemple, imaginez qu'on ait des circuits séparés pour le rendu 2D et 3D. Prenons l'exemple où le calcul d'une image finale demande de faire un rendu 3D suivi d'un rendu 2D, par exemple un jeu vidéo en 3D qui a un HUD dessiné en 2D. Dans ce cas, on peut démarrer le calcul de l'image suivante dans le pipeline 3D pendant que la précédente est dans les circuits 2D, au lieu de laisser inutilisé le pipeline 3D pendant le rendu 2D. Mais c'est là un défi compliqué à relever pour le processeur de commande, qui donne lieu à son lot de problèmes. Le problème principal est le partage de ressources entre commandes. Par exemple, on peut prendre le cas où une commande n'utilise pas beaucoup les processeurs de ''shaders''. On pourrait imaginer lancer une seconde commande en parallèle, afin que la seconde commande utiliser les processeurs de ''shaders'' inutilisés. Mais cela n'est possible que si les circuits fixes sont capables d'accepter une seconde commande. Si la première commande sature les circuits fixe, le lancement de la seconde commande sera empêché. Mais si ce n'est pas le cas, les deux commandes pourront être lancées en même temps. Pareil pour le débit mémoire, qui doit alors être partagé entre deux commandes simultanées, ce qui est à prendre en compte. ===La synchronisation de l’exécution des commandes avec le processeur=== Il arrive que le processeur doive savoir où en est le traitement des commandes, ce qui est très utile pour la gestion de la mémoire vidéo. Un premier exemple : comment éviter de saturer une carte graphique de commande, alors qu'on ne sait pas si elles traite les commandes rapidement ou non ? L'idéal est de regarder où en est la carte graphique dans l'exécution des commandes. Si elle n'en est qu'au début du tampon de commande et que celui-ci est bien remplit, alors il vaut mieux lever le pied et ne pas envoyer de nouvelles commandes. A l'inverse, si le tampon de commande est presque vide, envoyer des commandes est la meilleure idée possible. Un autre exemple un peu moins parlant est celui de la gestion de la mémoire vidéo. Rappelons qu'elle est réalisée par le pilote de la carte graphique, sur le processeur principal, qui décide d'allouer et de libérer de la mémoire vidéo. Pour donner un exemple d'utilisation, imaginez que le pilote de la carte graphique doive libérer de la mémoire pour pouvoir ajouter une nouvelle commande. Comment éviter d'enlever une texture tant que les commandes qui l'utilisent ne sont pas terminées ? Ce problème ne se limite pas aux textures, mais vaut pour tout ce qui est placé en mémoire vidéo. Il faut donc que la carte graphique trouve un moyen de prévenir le processeur que le traitement de telle commande est terminée, que telle commande en est rendue à tel ou tel point, etc. Pour cela, on a globalement deux grandes solutions. La première est celle des interruptions, abordées dans les chapitres précédents. Mais elles sont assez couteuses et ne sont utilisées que pour des évènements vraiment importants, critiques, qui demandent une réaction rapide du processeur. L'autre solution est celle du ''pooling'', où le processeur monitore la carte graphique à intervalles réguliers. Deux solutions bien connues de ceux qui ont déjà lu un cours d'architecture des ordinateurs digne de ce nom, rien de bien neuf : la carte graphique communique avec le processeur comme tout périphérique. Pour faciliter l'implémentation du ''pooling'', la carte graphique contient des registres de statut, dans le processeur de commande, qui mémorisent tout ou partie de l'état de la carte graphique. Si un problème survient, certains bits du registre de statut seront mis à 1 pour indiquer que telle erreur bien précise a eu lieu. Il existe aussi un registre de statut qui mémorise le numéro de la commande en cours, ou de la dernière commande terminée, ce qui permet de savoir où en est la carte graphique dans l'exécution des commandes. Et certaines registres de statut sont dédiés à la gestion des commandes. Ils sont totalement programmable, la carte graphique peut écrire dedans sans problème. Les cartes graphiques récentes incorporent des commandes pour modifier ces registres de statut au besoin. Elles sont appelées des '''commandes de synchronisation''' : les barrières (''fences''). Elles permettent d'écrire une valeur dans un registre de statut quand telle ou telle condition est remplie. Par exemple, si jamais une commande est terminée, on peut écrire la valeur 1 dans tel ou tel registre. La condition en question peut être assez complexe et se résumer à quelque chose du genre : "si jamais toutes les ''shaders'' ont fini de traiter tel ensemble de textures, alors écrit la valeur 1024 dans le registre de statut numéro 9". ===La synchronisation de l’exécution des commandes intra-GPU=== Lancer plusieurs commandes en parallèle dans le pipeline permet de gagner en performance.Mais cela a un gros défaut : il n'est pas garantit que les commandes se terminent dans l'ordre. Si on démarre une seconde commande après la première, il arrive que la seconde finisse avant. Pire : il n'est pas garantit qu'elles s'exécutent dans l'ordre. Dans la plupart des cas, cela ne pose pas de problèmes. Mais dans d'autres, cela donne des résultats erronés. Pour donner un exemple, utilisons les commandes de rendu 2D vues plus haut, histoire de simplifier le tout. Imaginez que vous codez un jeu vidéo et que le rendu se fait en 2D, partons sur un jeu de type FPS. Vous avez une série de commandes pour calculer l'image à rendre à l'écran, suivie par une série de commandes finales pour dessiner le HUB. Pour dessiner le HUD, vous utilisez des commandes HOSTDATA_BLT, dont le but est d'écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo. Et bien ces commandes HOSTDATA_BLT doivent démarrer une fois que le rendu de l'image est complétement terminé. Imaginez que vous dessiniez le HUD sur une portion de l'image pas encore terminée et que celui-ci est effacé par des écritures ultérieures ! Pour éviter tout problème, les GPU incorporent des commandes de synchronisation intra-GPU, destinées au processeur de commande, aussis appelées des '''commandes de sémaphore'''. Elles permettent de mettre en pause le lancement d'une nouvelle commande tant que les précédentes ne sont pas totalement ou partiellement terminées. Les plus simples empêchent le démarrage d'une commande tant que les précédentes ne sont pas terminées. D'autres permettent de démarrer une commande si et seulement si certaines commandes sont terminées. D'autres sont encore plus précises : elles empêchent le démarrage d'une nouvelle commande tant qu'une commande précédente n'a pas atteint un certain stade de son exécution. Là encore, de telles commandes sont des commandes du style "attend que le registre de statut numéro N contienne la valeur adéquate avant de poursuivre l'exécution des commandes". Les commandes en question peuvent être sur le même modèle que précédemment, à savoir des commandes qui lisent les registres de statut. Mais elles peuvent aussi se baser sur le fait que telle ou telle ressource de rendu est libre ou non. Des commandes successives se partagent souvent des données, et que de nombreuses commandes différentes peuvent s'exécuter en même temps. Or, si une commande veut modifier les données utilisées par une autre commande, il faut que l'ordre des commandes soit maintenu : la commande la plus récente ne doit pas modifier les données utilisées par une commande plus ancienne. Avec ce modèle, les sémaphores bloquent une commande tant qu'une ressource (une texture) est utilisée par une autre commande. {|class="wikitable" |- ! Commandes de synchronisation ! Fonction |- |NOP |Ne rien faire |- |WAIT_SEMAPHORE |Attendre la synchronisation avec un sémaphore |- |WAIT_MEM |Attendre que la mémoire vidéo soit disponible et inoccupée par le CPU |} ==L'arbitrage de l'accès à la carte graphique== Il n'est pas rare que plusieurs applications souhaitent accéder en même temps à la carte graphique. Imaginons que vous regardez une vidéo en ''streaming'' sur votre navigateur web, avec un programme de ''cloud computing'' de type ''Folding@Home'' qui tourne en arrière-plan, sur Windows. Le décodage de la vidéo est réalisé par la carte graphique, Windows s'occupe de l'affichage du bureau et des fenêtres, le navigateur web doit afficher tout ce qui est autour de la vidéo (la page web), le programme de ''cloud computing'' va lancer ses calculs sur la carte graphique, etc. Des situations de ce genre sont assez courantes et c'est soit le pilote qui s'en charge, soit la carte graphique elle-même. ===L'arbitrage logiciel du GPU=== L'arbitrage logiciel est la méthode la plus simple. Concrètement, c'est le système d'exploitation et/ou le pilote de la carte graphique qui gèrent l'arbitrage du GPU. Dans les deux cas, tout est fait en logiciel. Les commandes sont accumulées dans un tampon de commande, voire plusieurs, et l'OS/pilote décide quelle commande envoyer en priorité. Sur Windows, avant l'arrivée du modèle de driver dit ''Windows Display Driver Model'', de telles situations étaient gérées simplement. Les applications ajoutaient des commandes dans une file de commande unique. Les commandes étaient exécutées dans l'ordre, en mode premier entrée dans la file premier sorti/exécuté. Il n'y avait pour ainsi dire pas d'arbitrage entre les applications. Et ce n'était pas un problème car, à l'époque, les seules applications qui utilisaient le GPU étaient des jeux vidéos fonctionnant en mode plein écran. Avec le modèle de driver ''Windows Display Driver Model'' (WDDM), le GPU est maintenant arbitré, à savoir que les applications ont accès à tour de rôle au GPU, certaines ayant droit à plus de temps GPU que d'autres. Chaque programme a accès à la carte graphique durant quelques dizaines ou centaines de millisecondes, à tour de rôle. Si le programme finissait son travail en moins de temps que la durée impartie, il laissait la main au programme suivant. S’il atteignait la durée maximale allouée, il était interrompu pour laisser la place au programme suivant. Et chaque programme avait droit d'accès à la carte graphique chacun à son tour. Un tel algorithme en tourniquet est très simple, mais avait cependant quelques défauts. De nos jours, les algorithmes d'ordonnancement d'accès sont plus élaborés, bien qu'il soit difficile de trouver de la littérature ou des brevets sur le sujet. Une autre fonctionnalité de WDDM est que les applications utilisant le GPU peuvent se partager la mémoire vidéo sans se marcher dessus. Avant, toutes les applications avaient accès à toute la mémoire vidéo, bien que ce soit par l’intermédiaire de commandes spécifiques. Mais avec WDDM, chaque application dispose de sa propre portion de mémoire vidéo, à laquelle est la seule à avoir accès. Une application ne peut plus lire le contenu réel de la mémoire vidéo, et encore moins lire le contenu des autres applications. : Il s'agit d'un équivalent à l'isolation des processus pour les programmes Windows, mais appliqué à la mémoire vidéo et non la mémoire système. Et cette isolation est rendue d'autant plus simple que les GPU modernes implémentent un système de mémoire virtuelle à pagination très poussé, avec du swap en mémoire RAM système, une protection mémoire, et bien d'autres fonctionnalités. Nous en reparlerons dans les chapitres sur la mémoire vidéo. ===L'arbitrage accéléré par le GPU=== Depuis 2020, avec l'arrivée de la ''Windows 10 May 2020 update'', Windows est capable de déléguer l'arbitrage du GPU au GPU lui-même. Le GPU gère lui-même l'arbitrage, du moins en partie. En partie, car l'OS gére les priorité, à savoir quelle application a droit à plus de temps que les autres. Par contre, la gestion du ''quantum'' de temps ou les commutations de contexte (on stoppe une application pour laisser la place à une autre), est du fait du GPU lui-même. L'avantage est que cela décharge le processeur d'une tâche assez lourde en calcul, pour la déporter sur le GPU. Un autre avantage est que le GPU peut gérer plus finement les ''quantum'' de temps et la commutation de contexte. Le CPU principal gère des durées assez importantes, de l'ordre de la milliseconde. De plus, il doit communiquer avec le GPU par des mécanismes temporellement imprécis, comme des interruptions. Avec l'arbitrage accéléré par le GPU, le GPU n'a plus besoin de communiquer avec le CPU pour l'arbitrage et peut le faire plus précisément, plus immédiatement. Un gain en performance théorique est donc possible. L'arbitrage accéléré par le GPU est le fait soit du processeur de commandes, soit d'un processeur spécialisé, séparé. {{NavChapitre | book=Les cartes graphiques | prev=La hiérarchie mémoire d'un GPU | prevText=La hiérarchie mémoire d'un GPU | next=Le pipeline géométrique d'avant DirectX 10 | netxText=Le pipeline géométrique d'avant DirectX 10 }}{{autocat}} 5p3cvjkutz493a9ow3kmvdkp17bbpis 744041 744040 2025-06-03T14:24:34Z Mewtow 31375 /* Le processeur de commandes */ 744041 wikitext text/x-wiki Dans ce chapitre, nous allons parler de tous les intermédiaires qui se placent entre une application de rendu 3D et les circuits de rendu 3D proprement dit. En premier lieu, on trouve le pilote de la carte graphique, aux fonctions multiples et variées. En second lieu, nous allons parler d'un circuit de la carte graphique qui fait l'interface entre le logiciel et les circuits de rendu 3D de la carte graphique : le processeur de commandes. Ce processeur de commandes est un circuit qui sert de chef d'orchestre, qui pilote le fonctionnement global de la carte graphique. API 3D, pilote de carte graphique et processeur de commande travaillent de concert pour que l'application communique avec la carte graphique. Nous allons d'abord voir le pilote de la carte graphique, avant de voir le fonctionnement du processeur de commande. ==Le pilote de carte graphique== Le pilote de la carte graphique est un logiciel qui s'occupe de faire l'interface entre le logiciel et la carte graphique. De manière générale, les pilotes de périphérique sont des intermédiaires entre les applications/APIs et le matériel. En théorie, le système d'exploitation est censé jouer ce rôle, mais il n'est pas programmé pour être compatible avec tous les périphériques vendus sur le marché. À la place, le système d'exploitation ne gère pas directement certains périphériques, mais fournit de quoi ajouter ce qui manque. Le pilote d'un périphérique sert justement à ajouter ce qui manque : ils ajoutent au système d'exploitation de quoi reconnaître le périphérique, de quoi l'utiliser au mieux. Pour une carte graphique, il a diverses fonctions que nous allons voir ci-dessous. Avant toute chose, précisons que les systèmes d'exploitation usuels (Windows, Linux, MacOsX et autres) sont fournis avec un pilote de carte graphique générique, compatible avec la plupart des cartes graphiques existantes. Rien de magique derrière cela : toutes les cartes graphiques vendues depuis plusieurs décennies respectent des standards, comme le VGA, le VESA, et d'autres. Et le pilote de base fournit avec le système d'exploitation est justement compatible avec ces standards minimaux. Mais le pilote ne peut pas profiter des fonctionnalités qui sont au-delà de ce standard. L'accélération 3D est presque inexistante avec le pilote de base, qui ne sert qu'à faire du rendu 2D (de quoi afficher l’interface de base du système d'exploitation, comme le bureau de Windows). Et même pour du rendu 2D, la plupart des fonctionnalités de la carte graphique ne sont pas disponibles. Par exemple, certaines résolutions ne sont pas disponibles, notamment les grandes résolutions. Ou encore, les performances sont loin d'être excellentes. Si vous avez déjà utilisé un PC sans pilote de carte graphique installé, vous avez certainement remarqué qu'il était particulièrement lent. ===La gestion des interruptions=== Une fonction particulièrement importante du pilote de carte graphique est la réponse aux interruptions lancées par la carte graphique. Pour rappel, les interruptions sont une fonctionnalité qui permet à un périphérique de communiquer avec le processeur, tout en économisant le temps de calcul de ce dernier. Typiquement, lorsqu'un périphérique lance une interruption, le processeur stoppe son travail et exécute automatiquement une routine d'interruption, un petit programme qui s'occupe de gérer le périphérique, de faire ce qu'il faut, ce que l'interruption a demandé. Il y a plusieurs interruptions possibles, chacune ayant son propre numéro et sa fonction dédiée, chacune ayant sa propre routine d'interruption. Après tout, la routine qui gère un débordement de la mémoire vidéo n'est pas la même que celle qui gère un changement de fréquence du GPU ou la fin du calcul d'une image 3D. Le pilote fournit l'ensemble des routines d'interruptions nécessaires pour gérer la carte graphique. ===La compilation des ''shaders''=== Le pilote de carte graphique est aussi chargé de traduire les ''shaders'' en code machine. En soi, cette étape est assez complexe, et ressemble beaucoup à la compilation d'un programme informatique normal. Les ''shaders'' sont écrits dans un langage de programmation de haut niveau, comme le HLSL ou le GLSL, mais ce n'est pas ce code source qui est compilé par le pilote de carte graphique. À la place, les ''shaders'' sont pré-compilés vers un langage dit intermédiaire, avant d'être compilé par le pilote en code machine. Le langage intermédiaire, comme son nom l'indique, sert d'intermédiaire entre le code source écrit en HLSL/GLSL et le code machine exécuté par la carte graphique. Il ressemble à un langage assembleur, mais reste malgré tout assez générique pour ne pas être un véritable code machine. Par exemple, il y a peu de limitations quant au nombre de processeurs ou de registres. En clair, il y a deux passes de compilation : une passe de traduction du code source en langage intermédiaire, puis une passe de compilation du code intermédiaire vers le code machine. Notons que la première passe est réalisée par le programmeur des ''shaders'', non pas par l'utilisateur. Par exemple, les ''shaders'' d'un jeu vidéo sont fournis déjà pré-compilés : les fichiers du jeu ne contiennent pas le code source GLSL/HLSL, mais du code intermédiaire. L'avantage de cette méthode est que le travail du pilote est fortement simplifié. Le pilote de périphérique pourrait compiler directement du code HLSL/GLSL, mais le temps de compilation serait très long et cela aurait un impact sur les performances. Avec l'usage du langage intermédiaire, le gros du travail à été fait lors de la première passe de compilation et le pilote graphique ne fait que finir le travail. Les optimisations importantes ont déjà été réalisées lors de la première passe. Il doit bien faire la traduction, ajouter quelques optimisations de bas niveau par-ci par-là, mais rien de bien gourmand en processeur. Autant dire que cela économise plus le processeur que si on devait compiler complètement les ''shaders'' à chaque exécution. Fait amusant, il faut savoir que le pilote peut parfois remplacer les ''shaders'' d'un jeu vidéo à la volée. Les pilotes récents embarquent en effet des ''shaders'' alternatifs pour les jeux les plus vendus et/ou les plus populaires. Lorsque vous lancez un de ces jeux vidéo et que le ''shader'' originel s'exécute, le pilote le détecte automatiquement et le remplace par la version améliorée, fournie par le pilote. Évidemment, le ''shader'' alternatif du pilote est optimisé pour le matériel adéquat. Cela permet de gagner en performance, voire en qualité d'image, sans pour autant que les concepteurs du jeu n'aient quoique ce soit à faire. Enfin, certains ''shaders'' sont fournis par le pilote pour d'autres raisons. Par exemple, les cartes graphiques récentes n'ont pas de circuits fixes pour traiter la géométrie. Autant les anciennes cartes graphiques avaient des circuits de T&L qui s'en occupaient, autant tout cela doit être émulé sur les machines récentes. Sans cette émulation, les vieux jeux vidéo conçus pour exploiter le T&L et d'autres technologies du genre ne fonctionneraient plus du tout. Émuler les circuits fixes disparus sur les cartes récentes est justement le fait de ''shaders'', présents dans le pilote de carte graphique. ===Les autres fonctions=== Le pilote a aussi bien d'autres fonctions. Par exemple, il s'occupe d'initialiser la carte graphique, de fixer la résolution, d'allouer la mémoire vidéo, de gérer le curseur de souris matériel, etc. ==Les commandes graphiques/vidéo/autres : des ordres envoyés au GPU== Tous les traitements que la carte graphique doit effectuer, qu'il s'agisse de rendu 2D, de calculs 2D, du décodage matérielle d'un flux vidéo, ou de calculs généralistes, sont envoyés par le pilote de la carte graphique, sous la forme de '''commandes'''. Ces commandes demandent à la carte graphique d'effectuer une opération 2D, ou une opération 3D, ou encore le rendu d'une vidéo. Les commandes graphiques en question varient beaucoup selon la carte graphique. Les commandes sont régulièrement revues et chaque nouvelle architecture a quelques changements par rapport aux modèles plus anciens. Des commandes peuvent apparaître, d'autres disparaître, d'autre voient leur fonctionnement légèrement altéré, etc. Mais dans les grandes lignes, on peut classer ces commandes en quelques grands types. Les commandes les plus importantes s'occupent de l'affichage 3D : afficher une image à partir de paquets de sommets, préparer le passage d'une image à une autre, changer la résolution, etc. Plus rare, d'autres commandes servent à faire du rendu 2D : afficher un polygone, tracer une ligne, coloriser une surface, etc. Sur les cartes graphiques qui peuvent accélérer le rendu des vidéos, il existe des commandes spécialisées pour l’accélération des vidéos. Pour donner quelques exemples, prenons les commandes 2D de la carte graphique AMD Radeon X1800. {|class="wikitable" |- ! Commandes 2D ! Fonction |- |PAINT |Peindre un rectangle d'une certaine couleur |- |PAINT_MULTI |Peindre des rectangles (pas les mêmes paramètres que PAINT) |- |BITBLT |Copie d'un bloc de mémoire dans un autre |- |BITBLT_MULTI |Plusieurs copies de blocs de mémoire dans d'autres |- |TRANS_BITBLT |Copie de blocs de mémoire avec un masque |- |NEXTCHAR |Afficher un caractère avec une certaine couleur |- |HOSTDATA_BLT |Écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo |- |POLYLINE |Afficher des lignes reliées entre elles |- |POLYSCANLINES |Afficher des lignes |- |PLY_NEXTSCAN |Afficher plusieurs lignes simples |- |SET_SCISSORS |Utiliser des coupes (ciseaux) |- |LOAD_PALETTE |Charger la palette pour affichage 2D |} ===Le tampon de commandes=== L'envoi des commandes à la carte graphique ne se fait pas directement. La carte graphique n'est pas toujours libre pour accepter une nouvelle commande, soit parce qu'elle est occupée par une commande précédente, soit parce qu'elle fait autre chose. Il faut alors faire patienter les données tant que la carte graphique est occupée. Les pilotes de la carte graphique vont les mettre en attente dans le '''tampon de commandes'''. Le tampon de commandes est ce qu'on appelle une file, une zone de mémoire dans laquelle on stocke des données dans l'ordre d'ajout. Si le tampon de commandes est plein, le driver n'accepte plus de demandes en provenance des applications. Un tampon de commandes plein est généralement mauvais signe : cela signifie que la carte graphique est trop lente pour traiter les demandes qui lui sont faites. Par contre, il arrive que le tampon de commandes soit vide : dans ce cas, c'est simplement que la carte graphique est trop rapide comparé au processeur, qui n'arrive alors pas à donner assez de commandes à la carte graphique pour l'occuper suffisamment. Le tampon de commande est soit une mémoire FIFO séparée, soit une portion de la mémoire vidéo. Le NV1, la toute première carte graphique NVIDIA, utilisait une mémoire FIFO intégrée à la carte graphique, séparée des autres circuits. Le processeur envoyait les commandes par rafale au GPU, à savoir qu'il envoyait plusieurs dizaines ou centaines de commandes à la suite, avant de passer à autre chose. Le GPU traitait les commandes une par une, à un rythme bien plus lent. Le processeur pouvait consulter la FIFO pour savoir s'il restait des entrées libres et combien. Le processeur savait ainsi combien d'écritures il pouvait envoyer en une fois au GPU. : Le fonctionnement de la FIFO du NV1 est décrit dans le brevet ''US5805930A : System for FIFO informing the availability of stages to store commands which include data and virtual address sent directly from application programs''. ===Le processeur de commandes=== Le '''processeur de commande''' est un circuit qui gère les commandes envoyées par le processeur. Il lit la commande la plus ancienne dans le tampon de commande, l’interprète, l’exécute, puis passe à la suivante. Le processeur de commande est un circuit assez compliqué. Sur les cartes graphiques anciennes, c'était un circuit séquentiel complexe, fabriqué à la main et était la partie la plus complexe du processeur graphique. Sur les cartes graphiques modernes, c'est un véritable microcontrôleur, avec un processeur, de la mémoire RAM, etc. Lors de l'exécution d'une commande, le processeur de commande pilote les circuits de la carte graphique. Précisément, il répartit le travail entre les différents circuits de la carte graphique et assure que l'ordre du pipeline est respecté. Le processeur de commande décide à quel processeur ou circuit doit être envoyé une commande. Pour donner un exemple, prenons la première carte graphique de NVIDIA, le NV1. Il s'agissait d'une carte multimédia qui incorporait non seulement une carte 2D/3D, mais aussi une carte son un contrôleur de disque et de quoi communiquer avec des manettes. De plus, il incorporait un contrôleur DMA pour échanger des données entre RAM système et les autres circuits. Et à tout cela, il fallait ajouter la FIFO de commandes et le processeur de commande. L'ensemble était relié par un bus interne à la carte graphique. Le processeur de commande servait de gestionnaire principal. Il envoyait des ordres internes aux circuits de rendu 3D, à sa carte son, au contrôleur DMA. Par exemple, lorsque le processeur voulait copier des données en mémoire vidéo, il envoyait une commande de copie, qui était stockée dans le tampon de commande, puis était exécutée par le processeur de commande. Le processeur de commande envoyait alors les ordres adéquats au contrôleur DMA, qui faisait la copie des données. Lors d'un rendu 3D, une commande de rendu 3D est envoyée au NV1, le processeur de commande la traite et l'envoi dans les circuits de rendu 3D. [[File:Microarchitecture du GPU NV1 de NVIDIA.png|centre|vignette|upright=2|Microarchitecture du GPU NV1 de NVIDIA]] A chaque instant, le processeur de commande répartit les ''shaders'' sur les processeurs de ''shaders'', en faisant en sorte qu'ils soient utilisés le plus possible. Dans le cas le plus simple, les unités sont alimentées en vertex/pixels les unes après les autres (principe du round-robin), mais des stratégies plus optimisées sont la règle de nos jours. Cela est très important sur les cartes graphiques : répartir plusieurs commandes sur plusieurs processeurs est une tâche difficile. Un chapitre entier sera d'ailleurs dédié à ce sujet. Il envoie aussi certaines commandes aux circuits fixes, comme l’''input assembler''. Là encore, il faut en sorte que les circuits fixes soient utilisés le mieux possible. Sa tâche est compliquée par le fait que les GPU récents ont plusieurs unités de traitement des sommets et des pixels, plusieurs ROP, plusieurs unités de textures, etc. Et c'est en partie le travail du processeur de commande que de répartir les calculs sur ces différentes unités. C'est là un problème assez compliqué pour le processeur de commande et ce pour tout un tas de raisons que nous ne ferons que survoler. Les contraintes d'ordonnancement de l'API et les règles de celle-ci sont une partie de la réponse. Mais d'autres raisons sont intrinsèques au rendu 3D ou à la conception des circuits. [[File:Architecture de base d'une carte 3D - 1.png|centre|vignette|upright=2.5|Architecture de base d'une carte 3D - 1]] Le processeur de commande n'a pas qu'un rôle de répartiteur. Il connait à tout instant l'état de la carte graphique, l'état de chaque sous-circuit. L'implémentation est variable suivant le GPU. La plus simple ajoute un registre d'état à chaque circuit, qui, est consultable en temps réel par le processeur de commande. Mais il est possible d'utiliser un système d'interruptions interne à la puce, ou circuits préviennent le processeur de commande quand ils ont terminé leur travail. Grâce à cela, le processeur de commandes garde en mémoire l'état de traitement de chaque commande : est-ce qu'elle est en train de s’exécuter sur le processeur graphique, est-ce qu'elle est mise en pause, est-ce qu'elle attend une donnée en provenance de la mémoire, est-ce qu'elle est terminée, etc. ==Le fonctionnement du processeur de commandes== Le processeur de commande lit, décode et exécute des commandes. Intuitivement, on se dit qu'il procède une commande à la fois. Mais les GPU modernes sont plus intelligents et peuvent exécuter plusieurs commandes en même temps, dans des circuits séparés. De nombreuses optimisations de ce type sont utilisées pour gagner en performance. Voyons comment un processeur de commande moderne fonctionne. ===L'ordonnancement et la gestion des ressources=== Le processeur de commande doit souvent mettre en pause certains circuits du pipeline, ainsi que les circuits précédents. Par exemple, si tous les processeurs de ''vertex shader'' sont occupés, l’''input assembler'' ne peut pas charger le paquet suivant car il n'y a aucun processeur de libre pour l’accueillir. Dans ce cas, l'étape d’''input assembly'' est mise en pause en attendant qu'un processeur de ''shader'' soit libre. La même chose a lieu pour l'étape de rastérisation : si aucun processeur de ''shader'' n'est libre, elle est mise en pause. Sauf que pour la rastérisation, cela a des conséquences sur les circuits précédents la rastérisation. Si un processeur de ''shader'' veut envoyer quelque chose au rastériseur alors qu'il est en pause, il devra lui aussi attendre que le rastériseur soit libre. On a la même chose quand les ROP sont occupés : les ''pixel shader'' ou l'unité de texture doivent parfois être mis en pause, ce qui peut entrainer la mise en pause des étapes précédentes, etc. En clair : plus un étape est situé vers la fin du pipeline graphique, plus sa mise en pause a de chances de se répercuter sur les étapes précédentes et de les mettre en pause aussi. Le processeur de commande doit gérer ces situations. ===Le pipelining des commandes=== Dans les cartes graphiques les plus rudimentaires, le processeur de commande exécute les commandes dans l'ordre. Il exécute une commande çà la fois et attend qu'une commande soit terminé pour en lancer une autre. Plusieurs commandes sont accumulées dans le tampon de commande, le processeur de commande les traite de la plus ancienne vers la plus récente. Du moins, les anciennes cartes graphiques faisaient comme cela, les cartes graphiques modernes sont un peu plus complexes. Elles n'attendent pas qu'une commande soit totalement terminée avant d'en lancer une nouvelle. Les processeurs de commande actuels sont capables d’exécuter plusieurs commandes en même temps. L'intérêt est un gain en performance assez important. Pour ceux qui ont déjà eu un cours d'architecture des ordinateurs avancé, lancer plusieurs commandes en même temps permet une forme de pipeline, dont les gains sont substantiels. Par exemple, imaginez qu'une commande de rendu 3D soit bien avancée et n'utilise que les processeurs de ''shaders'' et les ROP, mais laisse les unités géométriques libres. Il est alors possible de démarrer la commande suivante en avance, afin qu'elle remplisse les unités géométriques inutilisées. On a alors deux commandes en cours de traitement : une commande qui utilise la fin du pipeline uniquement, une autre qui utilise seulement le début du pipeline graphique. Le processeur de commande gère donc plusieurs commandes simultanées, à savoir plusieurs commandes qui en sont à des étapes différentes du pipeline. On peut avoir une commande qui est en cours dans l'étage de gestion de la géométrie, une autre dans le rastériseur, et une autre dans les unités de traitement des pixels. Le fait que les étapes du pipeline graphique sont à effectuer dans un ordre bien précis permet ce genre de chose assez facilement. Une autre possibilité est de faire des rendus en parallèle. Par exemple, imaginez qu'on ait des circuits séparés pour le rendu 2D et 3D. Prenons l'exemple où le calcul d'une image finale demande de faire un rendu 3D suivi d'un rendu 2D, par exemple un jeu vidéo en 3D qui a un HUD dessiné en 2D. Dans ce cas, on peut démarrer le calcul de l'image suivante dans le pipeline 3D pendant que la précédente est dans les circuits 2D, au lieu de laisser inutilisé le pipeline 3D pendant le rendu 2D. Mais c'est là un défi compliqué à relever pour le processeur de commande, qui donne lieu à son lot de problèmes. Le problème principal est le partage de ressources entre commandes. Par exemple, on peut prendre le cas où une commande n'utilise pas beaucoup les processeurs de ''shaders''. On pourrait imaginer lancer une seconde commande en parallèle, afin que la seconde commande utiliser les processeurs de ''shaders'' inutilisés. Mais cela n'est possible que si les circuits fixes sont capables d'accepter une seconde commande. Si la première commande sature les circuits fixe, le lancement de la seconde commande sera empêché. Mais si ce n'est pas le cas, les deux commandes pourront être lancées en même temps. Pareil pour le débit mémoire, qui doit alors être partagé entre deux commandes simultanées, ce qui est à prendre en compte. ===La synchronisation de l’exécution des commandes avec le processeur=== Il arrive que le processeur doive savoir où en est le traitement des commandes, ce qui est très utile pour la gestion de la mémoire vidéo. Un premier exemple : comment éviter de saturer une carte graphique de commande, alors qu'on ne sait pas si elles traite les commandes rapidement ou non ? L'idéal est de regarder où en est la carte graphique dans l'exécution des commandes. Si elle n'en est qu'au début du tampon de commande et que celui-ci est bien remplit, alors il vaut mieux lever le pied et ne pas envoyer de nouvelles commandes. A l'inverse, si le tampon de commande est presque vide, envoyer des commandes est la meilleure idée possible. Un autre exemple un peu moins parlant est celui de la gestion de la mémoire vidéo. Rappelons qu'elle est réalisée par le pilote de la carte graphique, sur le processeur principal, qui décide d'allouer et de libérer de la mémoire vidéo. Pour donner un exemple d'utilisation, imaginez que le pilote de la carte graphique doive libérer de la mémoire pour pouvoir ajouter une nouvelle commande. Comment éviter d'enlever une texture tant que les commandes qui l'utilisent ne sont pas terminées ? Ce problème ne se limite pas aux textures, mais vaut pour tout ce qui est placé en mémoire vidéo. Il faut donc que la carte graphique trouve un moyen de prévenir le processeur que le traitement de telle commande est terminée, que telle commande en est rendue à tel ou tel point, etc. Pour cela, on a globalement deux grandes solutions. La première est celle des interruptions, abordées dans les chapitres précédents. Mais elles sont assez couteuses et ne sont utilisées que pour des évènements vraiment importants, critiques, qui demandent une réaction rapide du processeur. L'autre solution est celle du ''pooling'', où le processeur monitore la carte graphique à intervalles réguliers. Deux solutions bien connues de ceux qui ont déjà lu un cours d'architecture des ordinateurs digne de ce nom, rien de bien neuf : la carte graphique communique avec le processeur comme tout périphérique. Pour faciliter l'implémentation du ''pooling'', la carte graphique contient des registres de statut, dans le processeur de commande, qui mémorisent tout ou partie de l'état de la carte graphique. Si un problème survient, certains bits du registre de statut seront mis à 1 pour indiquer que telle erreur bien précise a eu lieu. Il existe aussi un registre de statut qui mémorise le numéro de la commande en cours, ou de la dernière commande terminée, ce qui permet de savoir où en est la carte graphique dans l'exécution des commandes. Et certaines registres de statut sont dédiés à la gestion des commandes. Ils sont totalement programmable, la carte graphique peut écrire dedans sans problème. Les cartes graphiques récentes incorporent des commandes pour modifier ces registres de statut au besoin. Elles sont appelées des '''commandes de synchronisation''' : les barrières (''fences''). Elles permettent d'écrire une valeur dans un registre de statut quand telle ou telle condition est remplie. Par exemple, si jamais une commande est terminée, on peut écrire la valeur 1 dans tel ou tel registre. La condition en question peut être assez complexe et se résumer à quelque chose du genre : "si jamais toutes les ''shaders'' ont fini de traiter tel ensemble de textures, alors écrit la valeur 1024 dans le registre de statut numéro 9". ===La synchronisation de l’exécution des commandes intra-GPU=== Lancer plusieurs commandes en parallèle dans le pipeline permet de gagner en performance.Mais cela a un gros défaut : il n'est pas garantit que les commandes se terminent dans l'ordre. Si on démarre une seconde commande après la première, il arrive que la seconde finisse avant. Pire : il n'est pas garantit qu'elles s'exécutent dans l'ordre. Dans la plupart des cas, cela ne pose pas de problèmes. Mais dans d'autres, cela donne des résultats erronés. Pour donner un exemple, utilisons les commandes de rendu 2D vues plus haut, histoire de simplifier le tout. Imaginez que vous codez un jeu vidéo et que le rendu se fait en 2D, partons sur un jeu de type FPS. Vous avez une série de commandes pour calculer l'image à rendre à l'écran, suivie par une série de commandes finales pour dessiner le HUB. Pour dessiner le HUD, vous utilisez des commandes HOSTDATA_BLT, dont le but est d'écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo. Et bien ces commandes HOSTDATA_BLT doivent démarrer une fois que le rendu de l'image est complétement terminé. Imaginez que vous dessiniez le HUD sur une portion de l'image pas encore terminée et que celui-ci est effacé par des écritures ultérieures ! Pour éviter tout problème, les GPU incorporent des commandes de synchronisation intra-GPU, destinées au processeur de commande, aussis appelées des '''commandes de sémaphore'''. Elles permettent de mettre en pause le lancement d'une nouvelle commande tant que les précédentes ne sont pas totalement ou partiellement terminées. Les plus simples empêchent le démarrage d'une commande tant que les précédentes ne sont pas terminées. D'autres permettent de démarrer une commande si et seulement si certaines commandes sont terminées. D'autres sont encore plus précises : elles empêchent le démarrage d'une nouvelle commande tant qu'une commande précédente n'a pas atteint un certain stade de son exécution. Là encore, de telles commandes sont des commandes du style "attend que le registre de statut numéro N contienne la valeur adéquate avant de poursuivre l'exécution des commandes". Les commandes en question peuvent être sur le même modèle que précédemment, à savoir des commandes qui lisent les registres de statut. Mais elles peuvent aussi se baser sur le fait que telle ou telle ressource de rendu est libre ou non. Des commandes successives se partagent souvent des données, et que de nombreuses commandes différentes peuvent s'exécuter en même temps. Or, si une commande veut modifier les données utilisées par une autre commande, il faut que l'ordre des commandes soit maintenu : la commande la plus récente ne doit pas modifier les données utilisées par une commande plus ancienne. Avec ce modèle, les sémaphores bloquent une commande tant qu'une ressource (une texture) est utilisée par une autre commande. {|class="wikitable" |- ! Commandes de synchronisation ! Fonction |- |NOP |Ne rien faire |- |WAIT_SEMAPHORE |Attendre la synchronisation avec un sémaphore |- |WAIT_MEM |Attendre que la mémoire vidéo soit disponible et inoccupée par le CPU |} ==L'arbitrage de l'accès à la carte graphique== Il n'est pas rare que plusieurs applications souhaitent accéder en même temps à la carte graphique. Imaginons que vous regardez une vidéo en ''streaming'' sur votre navigateur web, avec un programme de ''cloud computing'' de type ''Folding@Home'' qui tourne en arrière-plan, sur Windows. Le décodage de la vidéo est réalisé par la carte graphique, Windows s'occupe de l'affichage du bureau et des fenêtres, le navigateur web doit afficher tout ce qui est autour de la vidéo (la page web), le programme de ''cloud computing'' va lancer ses calculs sur la carte graphique, etc. Des situations de ce genre sont assez courantes et c'est soit le pilote qui s'en charge, soit la carte graphique elle-même. ===L'arbitrage logiciel du GPU=== L'arbitrage logiciel est la méthode la plus simple. Concrètement, c'est le système d'exploitation et/ou le pilote de la carte graphique qui gèrent l'arbitrage du GPU. Dans les deux cas, tout est fait en logiciel. Les commandes sont accumulées dans un tampon de commande, voire plusieurs, et l'OS/pilote décide quelle commande envoyer en priorité. Sur Windows, avant l'arrivée du modèle de driver dit ''Windows Display Driver Model'', de telles situations étaient gérées simplement. Les applications ajoutaient des commandes dans une file de commande unique. Les commandes étaient exécutées dans l'ordre, en mode premier entrée dans la file premier sorti/exécuté. Il n'y avait pour ainsi dire pas d'arbitrage entre les applications. Et ce n'était pas un problème car, à l'époque, les seules applications qui utilisaient le GPU étaient des jeux vidéos fonctionnant en mode plein écran. Avec le modèle de driver ''Windows Display Driver Model'' (WDDM), le GPU est maintenant arbitré, à savoir que les applications ont accès à tour de rôle au GPU, certaines ayant droit à plus de temps GPU que d'autres. Chaque programme a accès à la carte graphique durant quelques dizaines ou centaines de millisecondes, à tour de rôle. Si le programme finissait son travail en moins de temps que la durée impartie, il laissait la main au programme suivant. S’il atteignait la durée maximale allouée, il était interrompu pour laisser la place au programme suivant. Et chaque programme avait droit d'accès à la carte graphique chacun à son tour. Un tel algorithme en tourniquet est très simple, mais avait cependant quelques défauts. De nos jours, les algorithmes d'ordonnancement d'accès sont plus élaborés, bien qu'il soit difficile de trouver de la littérature ou des brevets sur le sujet. Une autre fonctionnalité de WDDM est que les applications utilisant le GPU peuvent se partager la mémoire vidéo sans se marcher dessus. Avant, toutes les applications avaient accès à toute la mémoire vidéo, bien que ce soit par l’intermédiaire de commandes spécifiques. Mais avec WDDM, chaque application dispose de sa propre portion de mémoire vidéo, à laquelle est la seule à avoir accès. Une application ne peut plus lire le contenu réel de la mémoire vidéo, et encore moins lire le contenu des autres applications. : Il s'agit d'un équivalent à l'isolation des processus pour les programmes Windows, mais appliqué à la mémoire vidéo et non la mémoire système. Et cette isolation est rendue d'autant plus simple que les GPU modernes implémentent un système de mémoire virtuelle à pagination très poussé, avec du swap en mémoire RAM système, une protection mémoire, et bien d'autres fonctionnalités. Nous en reparlerons dans les chapitres sur la mémoire vidéo. ===L'arbitrage accéléré par le GPU=== Depuis 2020, avec l'arrivée de la ''Windows 10 May 2020 update'', Windows est capable de déléguer l'arbitrage du GPU au GPU lui-même. Le GPU gère lui-même l'arbitrage, du moins en partie. En partie, car l'OS gére les priorité, à savoir quelle application a droit à plus de temps que les autres. Par contre, la gestion du ''quantum'' de temps ou les commutations de contexte (on stoppe une application pour laisser la place à une autre), est du fait du GPU lui-même. L'avantage est que cela décharge le processeur d'une tâche assez lourde en calcul, pour la déporter sur le GPU. Un autre avantage est que le GPU peut gérer plus finement les ''quantum'' de temps et la commutation de contexte. Le CPU principal gère des durées assez importantes, de l'ordre de la milliseconde. De plus, il doit communiquer avec le GPU par des mécanismes temporellement imprécis, comme des interruptions. Avec l'arbitrage accéléré par le GPU, le GPU n'a plus besoin de communiquer avec le CPU pour l'arbitrage et peut le faire plus précisément, plus immédiatement. Un gain en performance théorique est donc possible. L'arbitrage accéléré par le GPU est le fait soit du processeur de commandes, soit d'un processeur spécialisé, séparé. {{NavChapitre | book=Les cartes graphiques | prev=La hiérarchie mémoire d'un GPU | prevText=La hiérarchie mémoire d'un GPU | next=Le pipeline géométrique d'avant DirectX 10 | netxText=Le pipeline géométrique d'avant DirectX 10 }}{{autocat}} 74kzthjlkdrlrx920c4mcbxr7bxzwz0 744042 744041 2025-06-03T14:25:47Z Mewtow 31375 /* Le processeur de commandes */ 744042 wikitext text/x-wiki Dans ce chapitre, nous allons parler de tous les intermédiaires qui se placent entre une application de rendu 3D et les circuits de rendu 3D proprement dit. En premier lieu, on trouve le pilote de la carte graphique, aux fonctions multiples et variées. En second lieu, nous allons parler d'un circuit de la carte graphique qui fait l'interface entre le logiciel et les circuits de rendu 3D de la carte graphique : le processeur de commandes. Ce processeur de commandes est un circuit qui sert de chef d'orchestre, qui pilote le fonctionnement global de la carte graphique. API 3D, pilote de carte graphique et processeur de commande travaillent de concert pour que l'application communique avec la carte graphique. Nous allons d'abord voir le pilote de la carte graphique, avant de voir le fonctionnement du processeur de commande. ==Le pilote de carte graphique== Le pilote de la carte graphique est un logiciel qui s'occupe de faire l'interface entre le logiciel et la carte graphique. De manière générale, les pilotes de périphérique sont des intermédiaires entre les applications/APIs et le matériel. En théorie, le système d'exploitation est censé jouer ce rôle, mais il n'est pas programmé pour être compatible avec tous les périphériques vendus sur le marché. À la place, le système d'exploitation ne gère pas directement certains périphériques, mais fournit de quoi ajouter ce qui manque. Le pilote d'un périphérique sert justement à ajouter ce qui manque : ils ajoutent au système d'exploitation de quoi reconnaître le périphérique, de quoi l'utiliser au mieux. Pour une carte graphique, il a diverses fonctions que nous allons voir ci-dessous. Avant toute chose, précisons que les systèmes d'exploitation usuels (Windows, Linux, MacOsX et autres) sont fournis avec un pilote de carte graphique générique, compatible avec la plupart des cartes graphiques existantes. Rien de magique derrière cela : toutes les cartes graphiques vendues depuis plusieurs décennies respectent des standards, comme le VGA, le VESA, et d'autres. Et le pilote de base fournit avec le système d'exploitation est justement compatible avec ces standards minimaux. Mais le pilote ne peut pas profiter des fonctionnalités qui sont au-delà de ce standard. L'accélération 3D est presque inexistante avec le pilote de base, qui ne sert qu'à faire du rendu 2D (de quoi afficher l’interface de base du système d'exploitation, comme le bureau de Windows). Et même pour du rendu 2D, la plupart des fonctionnalités de la carte graphique ne sont pas disponibles. Par exemple, certaines résolutions ne sont pas disponibles, notamment les grandes résolutions. Ou encore, les performances sont loin d'être excellentes. Si vous avez déjà utilisé un PC sans pilote de carte graphique installé, vous avez certainement remarqué qu'il était particulièrement lent. ===La gestion des interruptions=== Une fonction particulièrement importante du pilote de carte graphique est la réponse aux interruptions lancées par la carte graphique. Pour rappel, les interruptions sont une fonctionnalité qui permet à un périphérique de communiquer avec le processeur, tout en économisant le temps de calcul de ce dernier. Typiquement, lorsqu'un périphérique lance une interruption, le processeur stoppe son travail et exécute automatiquement une routine d'interruption, un petit programme qui s'occupe de gérer le périphérique, de faire ce qu'il faut, ce que l'interruption a demandé. Il y a plusieurs interruptions possibles, chacune ayant son propre numéro et sa fonction dédiée, chacune ayant sa propre routine d'interruption. Après tout, la routine qui gère un débordement de la mémoire vidéo n'est pas la même que celle qui gère un changement de fréquence du GPU ou la fin du calcul d'une image 3D. Le pilote fournit l'ensemble des routines d'interruptions nécessaires pour gérer la carte graphique. ===La compilation des ''shaders''=== Le pilote de carte graphique est aussi chargé de traduire les ''shaders'' en code machine. En soi, cette étape est assez complexe, et ressemble beaucoup à la compilation d'un programme informatique normal. Les ''shaders'' sont écrits dans un langage de programmation de haut niveau, comme le HLSL ou le GLSL, mais ce n'est pas ce code source qui est compilé par le pilote de carte graphique. À la place, les ''shaders'' sont pré-compilés vers un langage dit intermédiaire, avant d'être compilé par le pilote en code machine. Le langage intermédiaire, comme son nom l'indique, sert d'intermédiaire entre le code source écrit en HLSL/GLSL et le code machine exécuté par la carte graphique. Il ressemble à un langage assembleur, mais reste malgré tout assez générique pour ne pas être un véritable code machine. Par exemple, il y a peu de limitations quant au nombre de processeurs ou de registres. En clair, il y a deux passes de compilation : une passe de traduction du code source en langage intermédiaire, puis une passe de compilation du code intermédiaire vers le code machine. Notons que la première passe est réalisée par le programmeur des ''shaders'', non pas par l'utilisateur. Par exemple, les ''shaders'' d'un jeu vidéo sont fournis déjà pré-compilés : les fichiers du jeu ne contiennent pas le code source GLSL/HLSL, mais du code intermédiaire. L'avantage de cette méthode est que le travail du pilote est fortement simplifié. Le pilote de périphérique pourrait compiler directement du code HLSL/GLSL, mais le temps de compilation serait très long et cela aurait un impact sur les performances. Avec l'usage du langage intermédiaire, le gros du travail à été fait lors de la première passe de compilation et le pilote graphique ne fait que finir le travail. Les optimisations importantes ont déjà été réalisées lors de la première passe. Il doit bien faire la traduction, ajouter quelques optimisations de bas niveau par-ci par-là, mais rien de bien gourmand en processeur. Autant dire que cela économise plus le processeur que si on devait compiler complètement les ''shaders'' à chaque exécution. Fait amusant, il faut savoir que le pilote peut parfois remplacer les ''shaders'' d'un jeu vidéo à la volée. Les pilotes récents embarquent en effet des ''shaders'' alternatifs pour les jeux les plus vendus et/ou les plus populaires. Lorsque vous lancez un de ces jeux vidéo et que le ''shader'' originel s'exécute, le pilote le détecte automatiquement et le remplace par la version améliorée, fournie par le pilote. Évidemment, le ''shader'' alternatif du pilote est optimisé pour le matériel adéquat. Cela permet de gagner en performance, voire en qualité d'image, sans pour autant que les concepteurs du jeu n'aient quoique ce soit à faire. Enfin, certains ''shaders'' sont fournis par le pilote pour d'autres raisons. Par exemple, les cartes graphiques récentes n'ont pas de circuits fixes pour traiter la géométrie. Autant les anciennes cartes graphiques avaient des circuits de T&L qui s'en occupaient, autant tout cela doit être émulé sur les machines récentes. Sans cette émulation, les vieux jeux vidéo conçus pour exploiter le T&L et d'autres technologies du genre ne fonctionneraient plus du tout. Émuler les circuits fixes disparus sur les cartes récentes est justement le fait de ''shaders'', présents dans le pilote de carte graphique. ===Les autres fonctions=== Le pilote a aussi bien d'autres fonctions. Par exemple, il s'occupe d'initialiser la carte graphique, de fixer la résolution, d'allouer la mémoire vidéo, de gérer le curseur de souris matériel, etc. ==Les commandes graphiques/vidéo/autres : des ordres envoyés au GPU== Tous les traitements que la carte graphique doit effectuer, qu'il s'agisse de rendu 2D, de calculs 2D, du décodage matérielle d'un flux vidéo, ou de calculs généralistes, sont envoyés par le pilote de la carte graphique, sous la forme de '''commandes'''. Ces commandes demandent à la carte graphique d'effectuer une opération 2D, ou une opération 3D, ou encore le rendu d'une vidéo. Les commandes graphiques en question varient beaucoup selon la carte graphique. Les commandes sont régulièrement revues et chaque nouvelle architecture a quelques changements par rapport aux modèles plus anciens. Des commandes peuvent apparaître, d'autres disparaître, d'autre voient leur fonctionnement légèrement altéré, etc. Mais dans les grandes lignes, on peut classer ces commandes en quelques grands types. Les commandes les plus importantes s'occupent de l'affichage 3D : afficher une image à partir de paquets de sommets, préparer le passage d'une image à une autre, changer la résolution, etc. Plus rare, d'autres commandes servent à faire du rendu 2D : afficher un polygone, tracer une ligne, coloriser une surface, etc. Sur les cartes graphiques qui peuvent accélérer le rendu des vidéos, il existe des commandes spécialisées pour l’accélération des vidéos. Pour donner quelques exemples, prenons les commandes 2D de la carte graphique AMD Radeon X1800. {|class="wikitable" |- ! Commandes 2D ! Fonction |- |PAINT |Peindre un rectangle d'une certaine couleur |- |PAINT_MULTI |Peindre des rectangles (pas les mêmes paramètres que PAINT) |- |BITBLT |Copie d'un bloc de mémoire dans un autre |- |BITBLT_MULTI |Plusieurs copies de blocs de mémoire dans d'autres |- |TRANS_BITBLT |Copie de blocs de mémoire avec un masque |- |NEXTCHAR |Afficher un caractère avec une certaine couleur |- |HOSTDATA_BLT |Écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo |- |POLYLINE |Afficher des lignes reliées entre elles |- |POLYSCANLINES |Afficher des lignes |- |PLY_NEXTSCAN |Afficher plusieurs lignes simples |- |SET_SCISSORS |Utiliser des coupes (ciseaux) |- |LOAD_PALETTE |Charger la palette pour affichage 2D |} ===Le tampon de commandes=== L'envoi des commandes à la carte graphique ne se fait pas directement. La carte graphique n'est pas toujours libre pour accepter une nouvelle commande, soit parce qu'elle est occupée par une commande précédente, soit parce qu'elle fait autre chose. Il faut alors faire patienter les données tant que la carte graphique est occupée. Les pilotes de la carte graphique vont les mettre en attente dans le '''tampon de commandes'''. Le tampon de commandes est ce qu'on appelle une file, une zone de mémoire dans laquelle on stocke des données dans l'ordre d'ajout. Si le tampon de commandes est plein, le driver n'accepte plus de demandes en provenance des applications. Un tampon de commandes plein est généralement mauvais signe : cela signifie que la carte graphique est trop lente pour traiter les demandes qui lui sont faites. Par contre, il arrive que le tampon de commandes soit vide : dans ce cas, c'est simplement que la carte graphique est trop rapide comparé au processeur, qui n'arrive alors pas à donner assez de commandes à la carte graphique pour l'occuper suffisamment. Le tampon de commande est soit une mémoire FIFO séparée, soit une portion de la mémoire vidéo. Le NV1, la toute première carte graphique NVIDIA, utilisait une mémoire FIFO intégrée à la carte graphique, séparée des autres circuits. Le processeur envoyait les commandes par rafale au GPU, à savoir qu'il envoyait plusieurs dizaines ou centaines de commandes à la suite, avant de passer à autre chose. Le GPU traitait les commandes une par une, à un rythme bien plus lent. Le processeur pouvait consulter la FIFO pour savoir s'il restait des entrées libres et combien. Le processeur savait ainsi combien d'écritures il pouvait envoyer en une fois au GPU. : Le fonctionnement de la FIFO du NV1 est décrit dans le brevet ''US5805930A : System for FIFO informing the availability of stages to store commands which include data and virtual address sent directly from application programs''. ===Le processeur de commandes=== Le '''processeur de commande''' est un circuit qui gère les commandes envoyées par le processeur. Il lit la commande la plus ancienne dans le tampon de commande, l’interprète, l’exécute, puis passe à la suivante. Le processeur de commande est un circuit assez compliqué. Sur les cartes graphiques anciennes, c'était un circuit séquentiel complexe, fabriqué à la main et était la partie la plus complexe du processeur graphique. Sur les cartes graphiques modernes, c'est un véritable microcontrôleur, avec un processeur, de la mémoire RAM, etc. Lors de l'exécution d'une commande, le processeur de commande pilote les circuits de la carte graphique. Précisément, il répartit le travail entre les différents circuits de la carte graphique et assure que l'ordre du pipeline est respecté. Le processeur de commande décide à quel processeur ou circuit doit être envoyé une commande. Pour donner un exemple, prenons la première carte graphique de NVIDIA, le NV1. Il s'agissait d'une carte multimédia qui incorporait non seulement une carte 2D/3D, mais aussi une carte son un contrôleur de disque et de quoi communiquer avec des manettes. De plus, il incorporait un contrôleur DMA pour échanger des données entre RAM système et les autres circuits. Et à tout cela, il fallait ajouter la FIFO de commandes et le processeur de commande. L'ensemble était relié par un bus interne à la carte graphique. Le processeur de commande servait de gestionnaire principal. Il envoyait des ordres internes aux circuits de rendu 3D, à sa carte son, au contrôleur DMA. Par exemple, lorsque le processeur voulait copier des données en mémoire vidéo, il envoyait une commande de copie, qui était stockée dans le tampon de commande, puis était exécutée par le processeur de commande. Le processeur de commande envoyait alors les ordres adéquats au contrôleur DMA, qui faisait la copie des données. Lors d'un rendu 3D, une commande de rendu 3D est envoyée au NV1, le processeur de commande la traite et l'envoi dans les circuits de rendu 3D. [[File:Microarchitecture du GPU NV1 de NVIDIA.png|centre|vignette|upright=2|Microarchitecture du GPU NV1 de NVIDIA]] Les GPU modernes sont plus complexes, ce qui fait que le processeur de commande a plus de travail. Parmis les nombreuses tâches qui lui sont confiées, il répartit les ''shaders'' sur les processeurs de ''shaders'', en faisant en sorte qu'ils soient utilisés le plus possible. Dans le cas le plus simple, les unités sont alimentées en vertex/pixels les unes après les autres (principe du round-robin), mais des stratégies plus optimisées sont la règle de nos jours. Cela est très important sur les cartes graphiques : répartir plusieurs commandes sur plusieurs processeurs est une tâche difficile. Un chapitre entier sera d'ailleurs dédié à ce sujet. Il envoie aussi certaines commandes aux circuits fixes, comme l’''input assembler''. Là encore, il faut en sorte que les circuits fixes soient utilisés le mieux possible. Sa tâche est compliquée par le fait que les GPU récents ont plusieurs unités de traitement des sommets et des pixels, plusieurs ROP, plusieurs unités de textures, etc. Et c'est en partie le travail du processeur de commande que de répartir les calculs sur ces différentes unités. C'est là un problème assez compliqué pour le processeur de commande et ce pour tout un tas de raisons que nous ne ferons que survoler. Les contraintes d'ordonnancement de l'API et les règles de celle-ci sont une partie de la réponse. Mais d'autres raisons sont intrinsèques au rendu 3D ou à la conception des circuits. [[File:Architecture de base d'une carte 3D - 1.png|centre|vignette|upright=2.5|Architecture de base d'une carte 3D - 1]] Le processeur de commande n'a pas qu'un rôle de répartiteur. Il connait à tout instant l'état de la carte graphique, l'état de chaque sous-circuit. L'implémentation est variable suivant le GPU. La plus simple ajoute un registre d'état à chaque circuit, qui, est consultable en temps réel par le processeur de commande. Mais il est possible d'utiliser un système d'interruptions interne à la puce, ou circuits préviennent le processeur de commande quand ils ont terminé leur travail. Grâce à cela, le processeur de commandes garde en mémoire l'état de traitement de chaque commande : est-ce qu'elle est en train de s’exécuter sur le processeur graphique, est-ce qu'elle est mise en pause, est-ce qu'elle attend une donnée en provenance de la mémoire, est-ce qu'elle est terminée, etc. ==Le fonctionnement du processeur de commandes== Le processeur de commande lit, décode et exécute des commandes. Intuitivement, on se dit qu'il procède une commande à la fois. Mais les GPU modernes sont plus intelligents et peuvent exécuter plusieurs commandes en même temps, dans des circuits séparés. De nombreuses optimisations de ce type sont utilisées pour gagner en performance. Voyons comment un processeur de commande moderne fonctionne. ===L'ordonnancement et la gestion des ressources=== Le processeur de commande doit souvent mettre en pause certains circuits du pipeline, ainsi que les circuits précédents. Par exemple, si tous les processeurs de ''vertex shader'' sont occupés, l’''input assembler'' ne peut pas charger le paquet suivant car il n'y a aucun processeur de libre pour l’accueillir. Dans ce cas, l'étape d’''input assembly'' est mise en pause en attendant qu'un processeur de ''shader'' soit libre. La même chose a lieu pour l'étape de rastérisation : si aucun processeur de ''shader'' n'est libre, elle est mise en pause. Sauf que pour la rastérisation, cela a des conséquences sur les circuits précédents la rastérisation. Si un processeur de ''shader'' veut envoyer quelque chose au rastériseur alors qu'il est en pause, il devra lui aussi attendre que le rastériseur soit libre. On a la même chose quand les ROP sont occupés : les ''pixel shader'' ou l'unité de texture doivent parfois être mis en pause, ce qui peut entrainer la mise en pause des étapes précédentes, etc. En clair : plus un étape est situé vers la fin du pipeline graphique, plus sa mise en pause a de chances de se répercuter sur les étapes précédentes et de les mettre en pause aussi. Le processeur de commande doit gérer ces situations. ===Le pipelining des commandes=== Dans les cartes graphiques les plus rudimentaires, le processeur de commande exécute les commandes dans l'ordre. Il exécute une commande çà la fois et attend qu'une commande soit terminé pour en lancer une autre. Plusieurs commandes sont accumulées dans le tampon de commande, le processeur de commande les traite de la plus ancienne vers la plus récente. Du moins, les anciennes cartes graphiques faisaient comme cela, les cartes graphiques modernes sont un peu plus complexes. Elles n'attendent pas qu'une commande soit totalement terminée avant d'en lancer une nouvelle. Les processeurs de commande actuels sont capables d’exécuter plusieurs commandes en même temps. L'intérêt est un gain en performance assez important. Pour ceux qui ont déjà eu un cours d'architecture des ordinateurs avancé, lancer plusieurs commandes en même temps permet une forme de pipeline, dont les gains sont substantiels. Par exemple, imaginez qu'une commande de rendu 3D soit bien avancée et n'utilise que les processeurs de ''shaders'' et les ROP, mais laisse les unités géométriques libres. Il est alors possible de démarrer la commande suivante en avance, afin qu'elle remplisse les unités géométriques inutilisées. On a alors deux commandes en cours de traitement : une commande qui utilise la fin du pipeline uniquement, une autre qui utilise seulement le début du pipeline graphique. Le processeur de commande gère donc plusieurs commandes simultanées, à savoir plusieurs commandes qui en sont à des étapes différentes du pipeline. On peut avoir une commande qui est en cours dans l'étage de gestion de la géométrie, une autre dans le rastériseur, et une autre dans les unités de traitement des pixels. Le fait que les étapes du pipeline graphique sont à effectuer dans un ordre bien précis permet ce genre de chose assez facilement. Une autre possibilité est de faire des rendus en parallèle. Par exemple, imaginez qu'on ait des circuits séparés pour le rendu 2D et 3D. Prenons l'exemple où le calcul d'une image finale demande de faire un rendu 3D suivi d'un rendu 2D, par exemple un jeu vidéo en 3D qui a un HUD dessiné en 2D. Dans ce cas, on peut démarrer le calcul de l'image suivante dans le pipeline 3D pendant que la précédente est dans les circuits 2D, au lieu de laisser inutilisé le pipeline 3D pendant le rendu 2D. Mais c'est là un défi compliqué à relever pour le processeur de commande, qui donne lieu à son lot de problèmes. Le problème principal est le partage de ressources entre commandes. Par exemple, on peut prendre le cas où une commande n'utilise pas beaucoup les processeurs de ''shaders''. On pourrait imaginer lancer une seconde commande en parallèle, afin que la seconde commande utiliser les processeurs de ''shaders'' inutilisés. Mais cela n'est possible que si les circuits fixes sont capables d'accepter une seconde commande. Si la première commande sature les circuits fixe, le lancement de la seconde commande sera empêché. Mais si ce n'est pas le cas, les deux commandes pourront être lancées en même temps. Pareil pour le débit mémoire, qui doit alors être partagé entre deux commandes simultanées, ce qui est à prendre en compte. ===La synchronisation de l’exécution des commandes avec le processeur=== Il arrive que le processeur doive savoir où en est le traitement des commandes, ce qui est très utile pour la gestion de la mémoire vidéo. Un premier exemple : comment éviter de saturer une carte graphique de commande, alors qu'on ne sait pas si elles traite les commandes rapidement ou non ? L'idéal est de regarder où en est la carte graphique dans l'exécution des commandes. Si elle n'en est qu'au début du tampon de commande et que celui-ci est bien remplit, alors il vaut mieux lever le pied et ne pas envoyer de nouvelles commandes. A l'inverse, si le tampon de commande est presque vide, envoyer des commandes est la meilleure idée possible. Un autre exemple un peu moins parlant est celui de la gestion de la mémoire vidéo. Rappelons qu'elle est réalisée par le pilote de la carte graphique, sur le processeur principal, qui décide d'allouer et de libérer de la mémoire vidéo. Pour donner un exemple d'utilisation, imaginez que le pilote de la carte graphique doive libérer de la mémoire pour pouvoir ajouter une nouvelle commande. Comment éviter d'enlever une texture tant que les commandes qui l'utilisent ne sont pas terminées ? Ce problème ne se limite pas aux textures, mais vaut pour tout ce qui est placé en mémoire vidéo. Il faut donc que la carte graphique trouve un moyen de prévenir le processeur que le traitement de telle commande est terminée, que telle commande en est rendue à tel ou tel point, etc. Pour cela, on a globalement deux grandes solutions. La première est celle des interruptions, abordées dans les chapitres précédents. Mais elles sont assez couteuses et ne sont utilisées que pour des évènements vraiment importants, critiques, qui demandent une réaction rapide du processeur. L'autre solution est celle du ''pooling'', où le processeur monitore la carte graphique à intervalles réguliers. Deux solutions bien connues de ceux qui ont déjà lu un cours d'architecture des ordinateurs digne de ce nom, rien de bien neuf : la carte graphique communique avec le processeur comme tout périphérique. Pour faciliter l'implémentation du ''pooling'', la carte graphique contient des registres de statut, dans le processeur de commande, qui mémorisent tout ou partie de l'état de la carte graphique. Si un problème survient, certains bits du registre de statut seront mis à 1 pour indiquer que telle erreur bien précise a eu lieu. Il existe aussi un registre de statut qui mémorise le numéro de la commande en cours, ou de la dernière commande terminée, ce qui permet de savoir où en est la carte graphique dans l'exécution des commandes. Et certaines registres de statut sont dédiés à la gestion des commandes. Ils sont totalement programmable, la carte graphique peut écrire dedans sans problème. Les cartes graphiques récentes incorporent des commandes pour modifier ces registres de statut au besoin. Elles sont appelées des '''commandes de synchronisation''' : les barrières (''fences''). Elles permettent d'écrire une valeur dans un registre de statut quand telle ou telle condition est remplie. Par exemple, si jamais une commande est terminée, on peut écrire la valeur 1 dans tel ou tel registre. La condition en question peut être assez complexe et se résumer à quelque chose du genre : "si jamais toutes les ''shaders'' ont fini de traiter tel ensemble de textures, alors écrit la valeur 1024 dans le registre de statut numéro 9". ===La synchronisation de l’exécution des commandes intra-GPU=== Lancer plusieurs commandes en parallèle dans le pipeline permet de gagner en performance.Mais cela a un gros défaut : il n'est pas garantit que les commandes se terminent dans l'ordre. Si on démarre une seconde commande après la première, il arrive que la seconde finisse avant. Pire : il n'est pas garantit qu'elles s'exécutent dans l'ordre. Dans la plupart des cas, cela ne pose pas de problèmes. Mais dans d'autres, cela donne des résultats erronés. Pour donner un exemple, utilisons les commandes de rendu 2D vues plus haut, histoire de simplifier le tout. Imaginez que vous codez un jeu vidéo et que le rendu se fait en 2D, partons sur un jeu de type FPS. Vous avez une série de commandes pour calculer l'image à rendre à l'écran, suivie par une série de commandes finales pour dessiner le HUB. Pour dessiner le HUD, vous utilisez des commandes HOSTDATA_BLT, dont le but est d'écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo. Et bien ces commandes HOSTDATA_BLT doivent démarrer une fois que le rendu de l'image est complétement terminé. Imaginez que vous dessiniez le HUD sur une portion de l'image pas encore terminée et que celui-ci est effacé par des écritures ultérieures ! Pour éviter tout problème, les GPU incorporent des commandes de synchronisation intra-GPU, destinées au processeur de commande, aussis appelées des '''commandes de sémaphore'''. Elles permettent de mettre en pause le lancement d'une nouvelle commande tant que les précédentes ne sont pas totalement ou partiellement terminées. Les plus simples empêchent le démarrage d'une commande tant que les précédentes ne sont pas terminées. D'autres permettent de démarrer une commande si et seulement si certaines commandes sont terminées. D'autres sont encore plus précises : elles empêchent le démarrage d'une nouvelle commande tant qu'une commande précédente n'a pas atteint un certain stade de son exécution. Là encore, de telles commandes sont des commandes du style "attend que le registre de statut numéro N contienne la valeur adéquate avant de poursuivre l'exécution des commandes". Les commandes en question peuvent être sur le même modèle que précédemment, à savoir des commandes qui lisent les registres de statut. Mais elles peuvent aussi se baser sur le fait que telle ou telle ressource de rendu est libre ou non. Des commandes successives se partagent souvent des données, et que de nombreuses commandes différentes peuvent s'exécuter en même temps. Or, si une commande veut modifier les données utilisées par une autre commande, il faut que l'ordre des commandes soit maintenu : la commande la plus récente ne doit pas modifier les données utilisées par une commande plus ancienne. Avec ce modèle, les sémaphores bloquent une commande tant qu'une ressource (une texture) est utilisée par une autre commande. {|class="wikitable" |- ! Commandes de synchronisation ! Fonction |- |NOP |Ne rien faire |- |WAIT_SEMAPHORE |Attendre la synchronisation avec un sémaphore |- |WAIT_MEM |Attendre que la mémoire vidéo soit disponible et inoccupée par le CPU |} ==L'arbitrage de l'accès à la carte graphique== Il n'est pas rare que plusieurs applications souhaitent accéder en même temps à la carte graphique. Imaginons que vous regardez une vidéo en ''streaming'' sur votre navigateur web, avec un programme de ''cloud computing'' de type ''Folding@Home'' qui tourne en arrière-plan, sur Windows. Le décodage de la vidéo est réalisé par la carte graphique, Windows s'occupe de l'affichage du bureau et des fenêtres, le navigateur web doit afficher tout ce qui est autour de la vidéo (la page web), le programme de ''cloud computing'' va lancer ses calculs sur la carte graphique, etc. Des situations de ce genre sont assez courantes et c'est soit le pilote qui s'en charge, soit la carte graphique elle-même. ===L'arbitrage logiciel du GPU=== L'arbitrage logiciel est la méthode la plus simple. Concrètement, c'est le système d'exploitation et/ou le pilote de la carte graphique qui gèrent l'arbitrage du GPU. Dans les deux cas, tout est fait en logiciel. Les commandes sont accumulées dans un tampon de commande, voire plusieurs, et l'OS/pilote décide quelle commande envoyer en priorité. Sur Windows, avant l'arrivée du modèle de driver dit ''Windows Display Driver Model'', de telles situations étaient gérées simplement. Les applications ajoutaient des commandes dans une file de commande unique. Les commandes étaient exécutées dans l'ordre, en mode premier entrée dans la file premier sorti/exécuté. Il n'y avait pour ainsi dire pas d'arbitrage entre les applications. Et ce n'était pas un problème car, à l'époque, les seules applications qui utilisaient le GPU étaient des jeux vidéos fonctionnant en mode plein écran. Avec le modèle de driver ''Windows Display Driver Model'' (WDDM), le GPU est maintenant arbitré, à savoir que les applications ont accès à tour de rôle au GPU, certaines ayant droit à plus de temps GPU que d'autres. Chaque programme a accès à la carte graphique durant quelques dizaines ou centaines de millisecondes, à tour de rôle. Si le programme finissait son travail en moins de temps que la durée impartie, il laissait la main au programme suivant. S’il atteignait la durée maximale allouée, il était interrompu pour laisser la place au programme suivant. Et chaque programme avait droit d'accès à la carte graphique chacun à son tour. Un tel algorithme en tourniquet est très simple, mais avait cependant quelques défauts. De nos jours, les algorithmes d'ordonnancement d'accès sont plus élaborés, bien qu'il soit difficile de trouver de la littérature ou des brevets sur le sujet. Une autre fonctionnalité de WDDM est que les applications utilisant le GPU peuvent se partager la mémoire vidéo sans se marcher dessus. Avant, toutes les applications avaient accès à toute la mémoire vidéo, bien que ce soit par l’intermédiaire de commandes spécifiques. Mais avec WDDM, chaque application dispose de sa propre portion de mémoire vidéo, à laquelle est la seule à avoir accès. Une application ne peut plus lire le contenu réel de la mémoire vidéo, et encore moins lire le contenu des autres applications. : Il s'agit d'un équivalent à l'isolation des processus pour les programmes Windows, mais appliqué à la mémoire vidéo et non la mémoire système. Et cette isolation est rendue d'autant plus simple que les GPU modernes implémentent un système de mémoire virtuelle à pagination très poussé, avec du swap en mémoire RAM système, une protection mémoire, et bien d'autres fonctionnalités. Nous en reparlerons dans les chapitres sur la mémoire vidéo. ===L'arbitrage accéléré par le GPU=== Depuis 2020, avec l'arrivée de la ''Windows 10 May 2020 update'', Windows est capable de déléguer l'arbitrage du GPU au GPU lui-même. Le GPU gère lui-même l'arbitrage, du moins en partie. En partie, car l'OS gére les priorité, à savoir quelle application a droit à plus de temps que les autres. Par contre, la gestion du ''quantum'' de temps ou les commutations de contexte (on stoppe une application pour laisser la place à une autre), est du fait du GPU lui-même. L'avantage est que cela décharge le processeur d'une tâche assez lourde en calcul, pour la déporter sur le GPU. Un autre avantage est que le GPU peut gérer plus finement les ''quantum'' de temps et la commutation de contexte. Le CPU principal gère des durées assez importantes, de l'ordre de la milliseconde. De plus, il doit communiquer avec le GPU par des mécanismes temporellement imprécis, comme des interruptions. Avec l'arbitrage accéléré par le GPU, le GPU n'a plus besoin de communiquer avec le CPU pour l'arbitrage et peut le faire plus précisément, plus immédiatement. Un gain en performance théorique est donc possible. L'arbitrage accéléré par le GPU est le fait soit du processeur de commandes, soit d'un processeur spécialisé, séparé. {{NavChapitre | book=Les cartes graphiques | prev=La hiérarchie mémoire d'un GPU | prevText=La hiérarchie mémoire d'un GPU | next=Le pipeline géométrique d'avant DirectX 10 | netxText=Le pipeline géométrique d'avant DirectX 10 }}{{autocat}} 158wrzpajbsh0h3zhjc3bv2zawutqg9 744043 744042 2025-06-03T14:26:11Z Mewtow 31375 /* Le processeur de commandes */ 744043 wikitext text/x-wiki Dans ce chapitre, nous allons parler de tous les intermédiaires qui se placent entre une application de rendu 3D et les circuits de rendu 3D proprement dit. En premier lieu, on trouve le pilote de la carte graphique, aux fonctions multiples et variées. En second lieu, nous allons parler d'un circuit de la carte graphique qui fait l'interface entre le logiciel et les circuits de rendu 3D de la carte graphique : le processeur de commandes. Ce processeur de commandes est un circuit qui sert de chef d'orchestre, qui pilote le fonctionnement global de la carte graphique. API 3D, pilote de carte graphique et processeur de commande travaillent de concert pour que l'application communique avec la carte graphique. Nous allons d'abord voir le pilote de la carte graphique, avant de voir le fonctionnement du processeur de commande. ==Le pilote de carte graphique== Le pilote de la carte graphique est un logiciel qui s'occupe de faire l'interface entre le logiciel et la carte graphique. De manière générale, les pilotes de périphérique sont des intermédiaires entre les applications/APIs et le matériel. En théorie, le système d'exploitation est censé jouer ce rôle, mais il n'est pas programmé pour être compatible avec tous les périphériques vendus sur le marché. À la place, le système d'exploitation ne gère pas directement certains périphériques, mais fournit de quoi ajouter ce qui manque. Le pilote d'un périphérique sert justement à ajouter ce qui manque : ils ajoutent au système d'exploitation de quoi reconnaître le périphérique, de quoi l'utiliser au mieux. Pour une carte graphique, il a diverses fonctions que nous allons voir ci-dessous. Avant toute chose, précisons que les systèmes d'exploitation usuels (Windows, Linux, MacOsX et autres) sont fournis avec un pilote de carte graphique générique, compatible avec la plupart des cartes graphiques existantes. Rien de magique derrière cela : toutes les cartes graphiques vendues depuis plusieurs décennies respectent des standards, comme le VGA, le VESA, et d'autres. Et le pilote de base fournit avec le système d'exploitation est justement compatible avec ces standards minimaux. Mais le pilote ne peut pas profiter des fonctionnalités qui sont au-delà de ce standard. L'accélération 3D est presque inexistante avec le pilote de base, qui ne sert qu'à faire du rendu 2D (de quoi afficher l’interface de base du système d'exploitation, comme le bureau de Windows). Et même pour du rendu 2D, la plupart des fonctionnalités de la carte graphique ne sont pas disponibles. Par exemple, certaines résolutions ne sont pas disponibles, notamment les grandes résolutions. Ou encore, les performances sont loin d'être excellentes. Si vous avez déjà utilisé un PC sans pilote de carte graphique installé, vous avez certainement remarqué qu'il était particulièrement lent. ===La gestion des interruptions=== Une fonction particulièrement importante du pilote de carte graphique est la réponse aux interruptions lancées par la carte graphique. Pour rappel, les interruptions sont une fonctionnalité qui permet à un périphérique de communiquer avec le processeur, tout en économisant le temps de calcul de ce dernier. Typiquement, lorsqu'un périphérique lance une interruption, le processeur stoppe son travail et exécute automatiquement une routine d'interruption, un petit programme qui s'occupe de gérer le périphérique, de faire ce qu'il faut, ce que l'interruption a demandé. Il y a plusieurs interruptions possibles, chacune ayant son propre numéro et sa fonction dédiée, chacune ayant sa propre routine d'interruption. Après tout, la routine qui gère un débordement de la mémoire vidéo n'est pas la même que celle qui gère un changement de fréquence du GPU ou la fin du calcul d'une image 3D. Le pilote fournit l'ensemble des routines d'interruptions nécessaires pour gérer la carte graphique. ===La compilation des ''shaders''=== Le pilote de carte graphique est aussi chargé de traduire les ''shaders'' en code machine. En soi, cette étape est assez complexe, et ressemble beaucoup à la compilation d'un programme informatique normal. Les ''shaders'' sont écrits dans un langage de programmation de haut niveau, comme le HLSL ou le GLSL, mais ce n'est pas ce code source qui est compilé par le pilote de carte graphique. À la place, les ''shaders'' sont pré-compilés vers un langage dit intermédiaire, avant d'être compilé par le pilote en code machine. Le langage intermédiaire, comme son nom l'indique, sert d'intermédiaire entre le code source écrit en HLSL/GLSL et le code machine exécuté par la carte graphique. Il ressemble à un langage assembleur, mais reste malgré tout assez générique pour ne pas être un véritable code machine. Par exemple, il y a peu de limitations quant au nombre de processeurs ou de registres. En clair, il y a deux passes de compilation : une passe de traduction du code source en langage intermédiaire, puis une passe de compilation du code intermédiaire vers le code machine. Notons que la première passe est réalisée par le programmeur des ''shaders'', non pas par l'utilisateur. Par exemple, les ''shaders'' d'un jeu vidéo sont fournis déjà pré-compilés : les fichiers du jeu ne contiennent pas le code source GLSL/HLSL, mais du code intermédiaire. L'avantage de cette méthode est que le travail du pilote est fortement simplifié. Le pilote de périphérique pourrait compiler directement du code HLSL/GLSL, mais le temps de compilation serait très long et cela aurait un impact sur les performances. Avec l'usage du langage intermédiaire, le gros du travail à été fait lors de la première passe de compilation et le pilote graphique ne fait que finir le travail. Les optimisations importantes ont déjà été réalisées lors de la première passe. Il doit bien faire la traduction, ajouter quelques optimisations de bas niveau par-ci par-là, mais rien de bien gourmand en processeur. Autant dire que cela économise plus le processeur que si on devait compiler complètement les ''shaders'' à chaque exécution. Fait amusant, il faut savoir que le pilote peut parfois remplacer les ''shaders'' d'un jeu vidéo à la volée. Les pilotes récents embarquent en effet des ''shaders'' alternatifs pour les jeux les plus vendus et/ou les plus populaires. Lorsque vous lancez un de ces jeux vidéo et que le ''shader'' originel s'exécute, le pilote le détecte automatiquement et le remplace par la version améliorée, fournie par le pilote. Évidemment, le ''shader'' alternatif du pilote est optimisé pour le matériel adéquat. Cela permet de gagner en performance, voire en qualité d'image, sans pour autant que les concepteurs du jeu n'aient quoique ce soit à faire. Enfin, certains ''shaders'' sont fournis par le pilote pour d'autres raisons. Par exemple, les cartes graphiques récentes n'ont pas de circuits fixes pour traiter la géométrie. Autant les anciennes cartes graphiques avaient des circuits de T&L qui s'en occupaient, autant tout cela doit être émulé sur les machines récentes. Sans cette émulation, les vieux jeux vidéo conçus pour exploiter le T&L et d'autres technologies du genre ne fonctionneraient plus du tout. Émuler les circuits fixes disparus sur les cartes récentes est justement le fait de ''shaders'', présents dans le pilote de carte graphique. ===Les autres fonctions=== Le pilote a aussi bien d'autres fonctions. Par exemple, il s'occupe d'initialiser la carte graphique, de fixer la résolution, d'allouer la mémoire vidéo, de gérer le curseur de souris matériel, etc. ==Les commandes graphiques/vidéo/autres : des ordres envoyés au GPU== Tous les traitements que la carte graphique doit effectuer, qu'il s'agisse de rendu 2D, de calculs 2D, du décodage matérielle d'un flux vidéo, ou de calculs généralistes, sont envoyés par le pilote de la carte graphique, sous la forme de '''commandes'''. Ces commandes demandent à la carte graphique d'effectuer une opération 2D, ou une opération 3D, ou encore le rendu d'une vidéo. Les commandes graphiques en question varient beaucoup selon la carte graphique. Les commandes sont régulièrement revues et chaque nouvelle architecture a quelques changements par rapport aux modèles plus anciens. Des commandes peuvent apparaître, d'autres disparaître, d'autre voient leur fonctionnement légèrement altéré, etc. Mais dans les grandes lignes, on peut classer ces commandes en quelques grands types. Les commandes les plus importantes s'occupent de l'affichage 3D : afficher une image à partir de paquets de sommets, préparer le passage d'une image à une autre, changer la résolution, etc. Plus rare, d'autres commandes servent à faire du rendu 2D : afficher un polygone, tracer une ligne, coloriser une surface, etc. Sur les cartes graphiques qui peuvent accélérer le rendu des vidéos, il existe des commandes spécialisées pour l’accélération des vidéos. Pour donner quelques exemples, prenons les commandes 2D de la carte graphique AMD Radeon X1800. {|class="wikitable" |- ! Commandes 2D ! Fonction |- |PAINT |Peindre un rectangle d'une certaine couleur |- |PAINT_MULTI |Peindre des rectangles (pas les mêmes paramètres que PAINT) |- |BITBLT |Copie d'un bloc de mémoire dans un autre |- |BITBLT_MULTI |Plusieurs copies de blocs de mémoire dans d'autres |- |TRANS_BITBLT |Copie de blocs de mémoire avec un masque |- |NEXTCHAR |Afficher un caractère avec une certaine couleur |- |HOSTDATA_BLT |Écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo |- |POLYLINE |Afficher des lignes reliées entre elles |- |POLYSCANLINES |Afficher des lignes |- |PLY_NEXTSCAN |Afficher plusieurs lignes simples |- |SET_SCISSORS |Utiliser des coupes (ciseaux) |- |LOAD_PALETTE |Charger la palette pour affichage 2D |} ===Le tampon de commandes=== L'envoi des commandes à la carte graphique ne se fait pas directement. La carte graphique n'est pas toujours libre pour accepter une nouvelle commande, soit parce qu'elle est occupée par une commande précédente, soit parce qu'elle fait autre chose. Il faut alors faire patienter les données tant que la carte graphique est occupée. Les pilotes de la carte graphique vont les mettre en attente dans le '''tampon de commandes'''. Le tampon de commandes est ce qu'on appelle une file, une zone de mémoire dans laquelle on stocke des données dans l'ordre d'ajout. Si le tampon de commandes est plein, le driver n'accepte plus de demandes en provenance des applications. Un tampon de commandes plein est généralement mauvais signe : cela signifie que la carte graphique est trop lente pour traiter les demandes qui lui sont faites. Par contre, il arrive que le tampon de commandes soit vide : dans ce cas, c'est simplement que la carte graphique est trop rapide comparé au processeur, qui n'arrive alors pas à donner assez de commandes à la carte graphique pour l'occuper suffisamment. Le tampon de commande est soit une mémoire FIFO séparée, soit une portion de la mémoire vidéo. Le NV1, la toute première carte graphique NVIDIA, utilisait une mémoire FIFO intégrée à la carte graphique, séparée des autres circuits. Le processeur envoyait les commandes par rafale au GPU, à savoir qu'il envoyait plusieurs dizaines ou centaines de commandes à la suite, avant de passer à autre chose. Le GPU traitait les commandes une par une, à un rythme bien plus lent. Le processeur pouvait consulter la FIFO pour savoir s'il restait des entrées libres et combien. Le processeur savait ainsi combien d'écritures il pouvait envoyer en une fois au GPU. : Le fonctionnement de la FIFO du NV1 est décrit dans le brevet ''US5805930A : System for FIFO informing the availability of stages to store commands which include data and virtual address sent directly from application programs''. ===Le processeur de commandes=== Le '''processeur de commande''' est un circuit qui gère les commandes envoyées par le processeur. Il lit la commande la plus ancienne dans le tampon de commande, l’interprète, l’exécute, puis passe à la suivante. Le processeur de commande est un circuit assez compliqué. Sur les cartes graphiques anciennes, c'était un circuit séquentiel complexe, fabriqué à la main et était la partie la plus complexe du processeur graphique. Sur les cartes graphiques modernes, c'est un véritable microcontrôleur, avec un processeur, de la mémoire RAM, etc. Lors de l'exécution d'une commande, le processeur de commande pilote les circuits de la carte graphique. Précisément, il répartit le travail entre les différents circuits de la carte graphique et assure que l'ordre du pipeline est respecté. Pour donner un exemple, prenons la première carte graphique de NVIDIA, le NV1. Il s'agissait d'une carte multimédia qui incorporait non seulement une carte 2D/3D, mais aussi une carte son un contrôleur de disque et de quoi communiquer avec des manettes. De plus, il incorporait un contrôleur DMA pour échanger des données entre RAM système et les autres circuits. Et à tout cela, il fallait ajouter la FIFO de commandes et le processeur de commande. L'ensemble était relié par un bus interne à la carte graphique. Le processeur de commande servait de gestionnaire principal. Il envoyait des ordres internes aux circuits de rendu 3D, à sa carte son, au contrôleur DMA. Par exemple, lorsque le processeur voulait copier des données en mémoire vidéo, il envoyait une commande de copie, qui était stockée dans le tampon de commande, puis était exécutée par le processeur de commande. Le processeur de commande envoyait alors les ordres adéquats au contrôleur DMA, qui faisait la copie des données. Lors d'un rendu 3D, une commande de rendu 3D est envoyée au NV1, le processeur de commande la traite et l'envoi dans les circuits de rendu 3D. [[File:Microarchitecture du GPU NV1 de NVIDIA.png|centre|vignette|upright=2|Microarchitecture du GPU NV1 de NVIDIA]] Les GPU modernes sont plus complexes, ce qui fait que le processeur de commande a plus de travail. Parmis les nombreuses tâches qui lui sont confiées, il répartit les ''shaders'' sur les processeurs de ''shaders'', en faisant en sorte qu'ils soient utilisés le plus possible. Dans le cas le plus simple, les unités sont alimentées en vertex/pixels les unes après les autres (principe du round-robin), mais des stratégies plus optimisées sont la règle de nos jours. Cela est très important sur les cartes graphiques : répartir plusieurs commandes sur plusieurs processeurs est une tâche difficile. Un chapitre entier sera d'ailleurs dédié à ce sujet. Il envoie aussi certaines commandes aux circuits fixes, comme l’''input assembler''. Là encore, il faut en sorte que les circuits fixes soient utilisés le mieux possible. Sa tâche est compliquée par le fait que les GPU récents ont plusieurs unités de traitement des sommets et des pixels, plusieurs ROP, plusieurs unités de textures, etc. Et c'est en partie le travail du processeur de commande que de répartir les calculs sur ces différentes unités. C'est là un problème assez compliqué pour le processeur de commande et ce pour tout un tas de raisons que nous ne ferons que survoler. Les contraintes d'ordonnancement de l'API et les règles de celle-ci sont une partie de la réponse. Mais d'autres raisons sont intrinsèques au rendu 3D ou à la conception des circuits. [[File:Architecture de base d'une carte 3D - 1.png|centre|vignette|upright=2.5|Architecture de base d'une carte 3D - 1]] Le processeur de commande n'a pas qu'un rôle de répartiteur. Il connait à tout instant l'état de la carte graphique, l'état de chaque sous-circuit. L'implémentation est variable suivant le GPU. La plus simple ajoute un registre d'état à chaque circuit, qui, est consultable en temps réel par le processeur de commande. Mais il est possible d'utiliser un système d'interruptions interne à la puce, ou circuits préviennent le processeur de commande quand ils ont terminé leur travail. Grâce à cela, le processeur de commandes garde en mémoire l'état de traitement de chaque commande : est-ce qu'elle est en train de s’exécuter sur le processeur graphique, est-ce qu'elle est mise en pause, est-ce qu'elle attend une donnée en provenance de la mémoire, est-ce qu'elle est terminée, etc. ==Le fonctionnement du processeur de commandes== Le processeur de commande lit, décode et exécute des commandes. Intuitivement, on se dit qu'il procède une commande à la fois. Mais les GPU modernes sont plus intelligents et peuvent exécuter plusieurs commandes en même temps, dans des circuits séparés. De nombreuses optimisations de ce type sont utilisées pour gagner en performance. Voyons comment un processeur de commande moderne fonctionne. ===L'ordonnancement et la gestion des ressources=== Le processeur de commande doit souvent mettre en pause certains circuits du pipeline, ainsi que les circuits précédents. Par exemple, si tous les processeurs de ''vertex shader'' sont occupés, l’''input assembler'' ne peut pas charger le paquet suivant car il n'y a aucun processeur de libre pour l’accueillir. Dans ce cas, l'étape d’''input assembly'' est mise en pause en attendant qu'un processeur de ''shader'' soit libre. La même chose a lieu pour l'étape de rastérisation : si aucun processeur de ''shader'' n'est libre, elle est mise en pause. Sauf que pour la rastérisation, cela a des conséquences sur les circuits précédents la rastérisation. Si un processeur de ''shader'' veut envoyer quelque chose au rastériseur alors qu'il est en pause, il devra lui aussi attendre que le rastériseur soit libre. On a la même chose quand les ROP sont occupés : les ''pixel shader'' ou l'unité de texture doivent parfois être mis en pause, ce qui peut entrainer la mise en pause des étapes précédentes, etc. En clair : plus un étape est situé vers la fin du pipeline graphique, plus sa mise en pause a de chances de se répercuter sur les étapes précédentes et de les mettre en pause aussi. Le processeur de commande doit gérer ces situations. ===Le pipelining des commandes=== Dans les cartes graphiques les plus rudimentaires, le processeur de commande exécute les commandes dans l'ordre. Il exécute une commande çà la fois et attend qu'une commande soit terminé pour en lancer une autre. Plusieurs commandes sont accumulées dans le tampon de commande, le processeur de commande les traite de la plus ancienne vers la plus récente. Du moins, les anciennes cartes graphiques faisaient comme cela, les cartes graphiques modernes sont un peu plus complexes. Elles n'attendent pas qu'une commande soit totalement terminée avant d'en lancer une nouvelle. Les processeurs de commande actuels sont capables d’exécuter plusieurs commandes en même temps. L'intérêt est un gain en performance assez important. Pour ceux qui ont déjà eu un cours d'architecture des ordinateurs avancé, lancer plusieurs commandes en même temps permet une forme de pipeline, dont les gains sont substantiels. Par exemple, imaginez qu'une commande de rendu 3D soit bien avancée et n'utilise que les processeurs de ''shaders'' et les ROP, mais laisse les unités géométriques libres. Il est alors possible de démarrer la commande suivante en avance, afin qu'elle remplisse les unités géométriques inutilisées. On a alors deux commandes en cours de traitement : une commande qui utilise la fin du pipeline uniquement, une autre qui utilise seulement le début du pipeline graphique. Le processeur de commande gère donc plusieurs commandes simultanées, à savoir plusieurs commandes qui en sont à des étapes différentes du pipeline. On peut avoir une commande qui est en cours dans l'étage de gestion de la géométrie, une autre dans le rastériseur, et une autre dans les unités de traitement des pixels. Le fait que les étapes du pipeline graphique sont à effectuer dans un ordre bien précis permet ce genre de chose assez facilement. Une autre possibilité est de faire des rendus en parallèle. Par exemple, imaginez qu'on ait des circuits séparés pour le rendu 2D et 3D. Prenons l'exemple où le calcul d'une image finale demande de faire un rendu 3D suivi d'un rendu 2D, par exemple un jeu vidéo en 3D qui a un HUD dessiné en 2D. Dans ce cas, on peut démarrer le calcul de l'image suivante dans le pipeline 3D pendant que la précédente est dans les circuits 2D, au lieu de laisser inutilisé le pipeline 3D pendant le rendu 2D. Mais c'est là un défi compliqué à relever pour le processeur de commande, qui donne lieu à son lot de problèmes. Le problème principal est le partage de ressources entre commandes. Par exemple, on peut prendre le cas où une commande n'utilise pas beaucoup les processeurs de ''shaders''. On pourrait imaginer lancer une seconde commande en parallèle, afin que la seconde commande utiliser les processeurs de ''shaders'' inutilisés. Mais cela n'est possible que si les circuits fixes sont capables d'accepter une seconde commande. Si la première commande sature les circuits fixe, le lancement de la seconde commande sera empêché. Mais si ce n'est pas le cas, les deux commandes pourront être lancées en même temps. Pareil pour le débit mémoire, qui doit alors être partagé entre deux commandes simultanées, ce qui est à prendre en compte. ===La synchronisation de l’exécution des commandes avec le processeur=== Il arrive que le processeur doive savoir où en est le traitement des commandes, ce qui est très utile pour la gestion de la mémoire vidéo. Un premier exemple : comment éviter de saturer une carte graphique de commande, alors qu'on ne sait pas si elles traite les commandes rapidement ou non ? L'idéal est de regarder où en est la carte graphique dans l'exécution des commandes. Si elle n'en est qu'au début du tampon de commande et que celui-ci est bien remplit, alors il vaut mieux lever le pied et ne pas envoyer de nouvelles commandes. A l'inverse, si le tampon de commande est presque vide, envoyer des commandes est la meilleure idée possible. Un autre exemple un peu moins parlant est celui de la gestion de la mémoire vidéo. Rappelons qu'elle est réalisée par le pilote de la carte graphique, sur le processeur principal, qui décide d'allouer et de libérer de la mémoire vidéo. Pour donner un exemple d'utilisation, imaginez que le pilote de la carte graphique doive libérer de la mémoire pour pouvoir ajouter une nouvelle commande. Comment éviter d'enlever une texture tant que les commandes qui l'utilisent ne sont pas terminées ? Ce problème ne se limite pas aux textures, mais vaut pour tout ce qui est placé en mémoire vidéo. Il faut donc que la carte graphique trouve un moyen de prévenir le processeur que le traitement de telle commande est terminée, que telle commande en est rendue à tel ou tel point, etc. Pour cela, on a globalement deux grandes solutions. La première est celle des interruptions, abordées dans les chapitres précédents. Mais elles sont assez couteuses et ne sont utilisées que pour des évènements vraiment importants, critiques, qui demandent une réaction rapide du processeur. L'autre solution est celle du ''pooling'', où le processeur monitore la carte graphique à intervalles réguliers. Deux solutions bien connues de ceux qui ont déjà lu un cours d'architecture des ordinateurs digne de ce nom, rien de bien neuf : la carte graphique communique avec le processeur comme tout périphérique. Pour faciliter l'implémentation du ''pooling'', la carte graphique contient des registres de statut, dans le processeur de commande, qui mémorisent tout ou partie de l'état de la carte graphique. Si un problème survient, certains bits du registre de statut seront mis à 1 pour indiquer que telle erreur bien précise a eu lieu. Il existe aussi un registre de statut qui mémorise le numéro de la commande en cours, ou de la dernière commande terminée, ce qui permet de savoir où en est la carte graphique dans l'exécution des commandes. Et certaines registres de statut sont dédiés à la gestion des commandes. Ils sont totalement programmable, la carte graphique peut écrire dedans sans problème. Les cartes graphiques récentes incorporent des commandes pour modifier ces registres de statut au besoin. Elles sont appelées des '''commandes de synchronisation''' : les barrières (''fences''). Elles permettent d'écrire une valeur dans un registre de statut quand telle ou telle condition est remplie. Par exemple, si jamais une commande est terminée, on peut écrire la valeur 1 dans tel ou tel registre. La condition en question peut être assez complexe et se résumer à quelque chose du genre : "si jamais toutes les ''shaders'' ont fini de traiter tel ensemble de textures, alors écrit la valeur 1024 dans le registre de statut numéro 9". ===La synchronisation de l’exécution des commandes intra-GPU=== Lancer plusieurs commandes en parallèle dans le pipeline permet de gagner en performance.Mais cela a un gros défaut : il n'est pas garantit que les commandes se terminent dans l'ordre. Si on démarre une seconde commande après la première, il arrive que la seconde finisse avant. Pire : il n'est pas garantit qu'elles s'exécutent dans l'ordre. Dans la plupart des cas, cela ne pose pas de problèmes. Mais dans d'autres, cela donne des résultats erronés. Pour donner un exemple, utilisons les commandes de rendu 2D vues plus haut, histoire de simplifier le tout. Imaginez que vous codez un jeu vidéo et que le rendu se fait en 2D, partons sur un jeu de type FPS. Vous avez une série de commandes pour calculer l'image à rendre à l'écran, suivie par une série de commandes finales pour dessiner le HUB. Pour dessiner le HUD, vous utilisez des commandes HOSTDATA_BLT, dont le but est d'écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo. Et bien ces commandes HOSTDATA_BLT doivent démarrer une fois que le rendu de l'image est complétement terminé. Imaginez que vous dessiniez le HUD sur une portion de l'image pas encore terminée et que celui-ci est effacé par des écritures ultérieures ! Pour éviter tout problème, les GPU incorporent des commandes de synchronisation intra-GPU, destinées au processeur de commande, aussis appelées des '''commandes de sémaphore'''. Elles permettent de mettre en pause le lancement d'une nouvelle commande tant que les précédentes ne sont pas totalement ou partiellement terminées. Les plus simples empêchent le démarrage d'une commande tant que les précédentes ne sont pas terminées. D'autres permettent de démarrer une commande si et seulement si certaines commandes sont terminées. D'autres sont encore plus précises : elles empêchent le démarrage d'une nouvelle commande tant qu'une commande précédente n'a pas atteint un certain stade de son exécution. Là encore, de telles commandes sont des commandes du style "attend que le registre de statut numéro N contienne la valeur adéquate avant de poursuivre l'exécution des commandes". Les commandes en question peuvent être sur le même modèle que précédemment, à savoir des commandes qui lisent les registres de statut. Mais elles peuvent aussi se baser sur le fait que telle ou telle ressource de rendu est libre ou non. Des commandes successives se partagent souvent des données, et que de nombreuses commandes différentes peuvent s'exécuter en même temps. Or, si une commande veut modifier les données utilisées par une autre commande, il faut que l'ordre des commandes soit maintenu : la commande la plus récente ne doit pas modifier les données utilisées par une commande plus ancienne. Avec ce modèle, les sémaphores bloquent une commande tant qu'une ressource (une texture) est utilisée par une autre commande. {|class="wikitable" |- ! Commandes de synchronisation ! Fonction |- |NOP |Ne rien faire |- |WAIT_SEMAPHORE |Attendre la synchronisation avec un sémaphore |- |WAIT_MEM |Attendre que la mémoire vidéo soit disponible et inoccupée par le CPU |} ==L'arbitrage de l'accès à la carte graphique== Il n'est pas rare que plusieurs applications souhaitent accéder en même temps à la carte graphique. Imaginons que vous regardez une vidéo en ''streaming'' sur votre navigateur web, avec un programme de ''cloud computing'' de type ''Folding@Home'' qui tourne en arrière-plan, sur Windows. Le décodage de la vidéo est réalisé par la carte graphique, Windows s'occupe de l'affichage du bureau et des fenêtres, le navigateur web doit afficher tout ce qui est autour de la vidéo (la page web), le programme de ''cloud computing'' va lancer ses calculs sur la carte graphique, etc. Des situations de ce genre sont assez courantes et c'est soit le pilote qui s'en charge, soit la carte graphique elle-même. ===L'arbitrage logiciel du GPU=== L'arbitrage logiciel est la méthode la plus simple. Concrètement, c'est le système d'exploitation et/ou le pilote de la carte graphique qui gèrent l'arbitrage du GPU. Dans les deux cas, tout est fait en logiciel. Les commandes sont accumulées dans un tampon de commande, voire plusieurs, et l'OS/pilote décide quelle commande envoyer en priorité. Sur Windows, avant l'arrivée du modèle de driver dit ''Windows Display Driver Model'', de telles situations étaient gérées simplement. Les applications ajoutaient des commandes dans une file de commande unique. Les commandes étaient exécutées dans l'ordre, en mode premier entrée dans la file premier sorti/exécuté. Il n'y avait pour ainsi dire pas d'arbitrage entre les applications. Et ce n'était pas un problème car, à l'époque, les seules applications qui utilisaient le GPU étaient des jeux vidéos fonctionnant en mode plein écran. Avec le modèle de driver ''Windows Display Driver Model'' (WDDM), le GPU est maintenant arbitré, à savoir que les applications ont accès à tour de rôle au GPU, certaines ayant droit à plus de temps GPU que d'autres. Chaque programme a accès à la carte graphique durant quelques dizaines ou centaines de millisecondes, à tour de rôle. Si le programme finissait son travail en moins de temps que la durée impartie, il laissait la main au programme suivant. S’il atteignait la durée maximale allouée, il était interrompu pour laisser la place au programme suivant. Et chaque programme avait droit d'accès à la carte graphique chacun à son tour. Un tel algorithme en tourniquet est très simple, mais avait cependant quelques défauts. De nos jours, les algorithmes d'ordonnancement d'accès sont plus élaborés, bien qu'il soit difficile de trouver de la littérature ou des brevets sur le sujet. Une autre fonctionnalité de WDDM est que les applications utilisant le GPU peuvent se partager la mémoire vidéo sans se marcher dessus. Avant, toutes les applications avaient accès à toute la mémoire vidéo, bien que ce soit par l’intermédiaire de commandes spécifiques. Mais avec WDDM, chaque application dispose de sa propre portion de mémoire vidéo, à laquelle est la seule à avoir accès. Une application ne peut plus lire le contenu réel de la mémoire vidéo, et encore moins lire le contenu des autres applications. : Il s'agit d'un équivalent à l'isolation des processus pour les programmes Windows, mais appliqué à la mémoire vidéo et non la mémoire système. Et cette isolation est rendue d'autant plus simple que les GPU modernes implémentent un système de mémoire virtuelle à pagination très poussé, avec du swap en mémoire RAM système, une protection mémoire, et bien d'autres fonctionnalités. Nous en reparlerons dans les chapitres sur la mémoire vidéo. ===L'arbitrage accéléré par le GPU=== Depuis 2020, avec l'arrivée de la ''Windows 10 May 2020 update'', Windows est capable de déléguer l'arbitrage du GPU au GPU lui-même. Le GPU gère lui-même l'arbitrage, du moins en partie. En partie, car l'OS gére les priorité, à savoir quelle application a droit à plus de temps que les autres. Par contre, la gestion du ''quantum'' de temps ou les commutations de contexte (on stoppe une application pour laisser la place à une autre), est du fait du GPU lui-même. L'avantage est que cela décharge le processeur d'une tâche assez lourde en calcul, pour la déporter sur le GPU. Un autre avantage est que le GPU peut gérer plus finement les ''quantum'' de temps et la commutation de contexte. Le CPU principal gère des durées assez importantes, de l'ordre de la milliseconde. De plus, il doit communiquer avec le GPU par des mécanismes temporellement imprécis, comme des interruptions. Avec l'arbitrage accéléré par le GPU, le GPU n'a plus besoin de communiquer avec le CPU pour l'arbitrage et peut le faire plus précisément, plus immédiatement. Un gain en performance théorique est donc possible. L'arbitrage accéléré par le GPU est le fait soit du processeur de commandes, soit d'un processeur spécialisé, séparé. {{NavChapitre | book=Les cartes graphiques | prev=La hiérarchie mémoire d'un GPU | prevText=La hiérarchie mémoire d'un GPU | next=Le pipeline géométrique d'avant DirectX 10 | netxText=Le pipeline géométrique d'avant DirectX 10 }}{{autocat}} h3hs943q28nttedmuxtaupa1gj1aaeo 744044 744043 2025-06-03T14:27:21Z Mewtow 31375 /* Le fonctionnement du processeur de commandes */ 744044 wikitext text/x-wiki Dans ce chapitre, nous allons parler de tous les intermédiaires qui se placent entre une application de rendu 3D et les circuits de rendu 3D proprement dit. En premier lieu, on trouve le pilote de la carte graphique, aux fonctions multiples et variées. En second lieu, nous allons parler d'un circuit de la carte graphique qui fait l'interface entre le logiciel et les circuits de rendu 3D de la carte graphique : le processeur de commandes. Ce processeur de commandes est un circuit qui sert de chef d'orchestre, qui pilote le fonctionnement global de la carte graphique. API 3D, pilote de carte graphique et processeur de commande travaillent de concert pour que l'application communique avec la carte graphique. Nous allons d'abord voir le pilote de la carte graphique, avant de voir le fonctionnement du processeur de commande. ==Le pilote de carte graphique== Le pilote de la carte graphique est un logiciel qui s'occupe de faire l'interface entre le logiciel et la carte graphique. De manière générale, les pilotes de périphérique sont des intermédiaires entre les applications/APIs et le matériel. En théorie, le système d'exploitation est censé jouer ce rôle, mais il n'est pas programmé pour être compatible avec tous les périphériques vendus sur le marché. À la place, le système d'exploitation ne gère pas directement certains périphériques, mais fournit de quoi ajouter ce qui manque. Le pilote d'un périphérique sert justement à ajouter ce qui manque : ils ajoutent au système d'exploitation de quoi reconnaître le périphérique, de quoi l'utiliser au mieux. Pour une carte graphique, il a diverses fonctions que nous allons voir ci-dessous. Avant toute chose, précisons que les systèmes d'exploitation usuels (Windows, Linux, MacOsX et autres) sont fournis avec un pilote de carte graphique générique, compatible avec la plupart des cartes graphiques existantes. Rien de magique derrière cela : toutes les cartes graphiques vendues depuis plusieurs décennies respectent des standards, comme le VGA, le VESA, et d'autres. Et le pilote de base fournit avec le système d'exploitation est justement compatible avec ces standards minimaux. Mais le pilote ne peut pas profiter des fonctionnalités qui sont au-delà de ce standard. L'accélération 3D est presque inexistante avec le pilote de base, qui ne sert qu'à faire du rendu 2D (de quoi afficher l’interface de base du système d'exploitation, comme le bureau de Windows). Et même pour du rendu 2D, la plupart des fonctionnalités de la carte graphique ne sont pas disponibles. Par exemple, certaines résolutions ne sont pas disponibles, notamment les grandes résolutions. Ou encore, les performances sont loin d'être excellentes. Si vous avez déjà utilisé un PC sans pilote de carte graphique installé, vous avez certainement remarqué qu'il était particulièrement lent. ===La gestion des interruptions=== Une fonction particulièrement importante du pilote de carte graphique est la réponse aux interruptions lancées par la carte graphique. Pour rappel, les interruptions sont une fonctionnalité qui permet à un périphérique de communiquer avec le processeur, tout en économisant le temps de calcul de ce dernier. Typiquement, lorsqu'un périphérique lance une interruption, le processeur stoppe son travail et exécute automatiquement une routine d'interruption, un petit programme qui s'occupe de gérer le périphérique, de faire ce qu'il faut, ce que l'interruption a demandé. Il y a plusieurs interruptions possibles, chacune ayant son propre numéro et sa fonction dédiée, chacune ayant sa propre routine d'interruption. Après tout, la routine qui gère un débordement de la mémoire vidéo n'est pas la même que celle qui gère un changement de fréquence du GPU ou la fin du calcul d'une image 3D. Le pilote fournit l'ensemble des routines d'interruptions nécessaires pour gérer la carte graphique. ===La compilation des ''shaders''=== Le pilote de carte graphique est aussi chargé de traduire les ''shaders'' en code machine. En soi, cette étape est assez complexe, et ressemble beaucoup à la compilation d'un programme informatique normal. Les ''shaders'' sont écrits dans un langage de programmation de haut niveau, comme le HLSL ou le GLSL, mais ce n'est pas ce code source qui est compilé par le pilote de carte graphique. À la place, les ''shaders'' sont pré-compilés vers un langage dit intermédiaire, avant d'être compilé par le pilote en code machine. Le langage intermédiaire, comme son nom l'indique, sert d'intermédiaire entre le code source écrit en HLSL/GLSL et le code machine exécuté par la carte graphique. Il ressemble à un langage assembleur, mais reste malgré tout assez générique pour ne pas être un véritable code machine. Par exemple, il y a peu de limitations quant au nombre de processeurs ou de registres. En clair, il y a deux passes de compilation : une passe de traduction du code source en langage intermédiaire, puis une passe de compilation du code intermédiaire vers le code machine. Notons que la première passe est réalisée par le programmeur des ''shaders'', non pas par l'utilisateur. Par exemple, les ''shaders'' d'un jeu vidéo sont fournis déjà pré-compilés : les fichiers du jeu ne contiennent pas le code source GLSL/HLSL, mais du code intermédiaire. L'avantage de cette méthode est que le travail du pilote est fortement simplifié. Le pilote de périphérique pourrait compiler directement du code HLSL/GLSL, mais le temps de compilation serait très long et cela aurait un impact sur les performances. Avec l'usage du langage intermédiaire, le gros du travail à été fait lors de la première passe de compilation et le pilote graphique ne fait que finir le travail. Les optimisations importantes ont déjà été réalisées lors de la première passe. Il doit bien faire la traduction, ajouter quelques optimisations de bas niveau par-ci par-là, mais rien de bien gourmand en processeur. Autant dire que cela économise plus le processeur que si on devait compiler complètement les ''shaders'' à chaque exécution. Fait amusant, il faut savoir que le pilote peut parfois remplacer les ''shaders'' d'un jeu vidéo à la volée. Les pilotes récents embarquent en effet des ''shaders'' alternatifs pour les jeux les plus vendus et/ou les plus populaires. Lorsque vous lancez un de ces jeux vidéo et que le ''shader'' originel s'exécute, le pilote le détecte automatiquement et le remplace par la version améliorée, fournie par le pilote. Évidemment, le ''shader'' alternatif du pilote est optimisé pour le matériel adéquat. Cela permet de gagner en performance, voire en qualité d'image, sans pour autant que les concepteurs du jeu n'aient quoique ce soit à faire. Enfin, certains ''shaders'' sont fournis par le pilote pour d'autres raisons. Par exemple, les cartes graphiques récentes n'ont pas de circuits fixes pour traiter la géométrie. Autant les anciennes cartes graphiques avaient des circuits de T&L qui s'en occupaient, autant tout cela doit être émulé sur les machines récentes. Sans cette émulation, les vieux jeux vidéo conçus pour exploiter le T&L et d'autres technologies du genre ne fonctionneraient plus du tout. Émuler les circuits fixes disparus sur les cartes récentes est justement le fait de ''shaders'', présents dans le pilote de carte graphique. ===Les autres fonctions=== Le pilote a aussi bien d'autres fonctions. Par exemple, il s'occupe d'initialiser la carte graphique, de fixer la résolution, d'allouer la mémoire vidéo, de gérer le curseur de souris matériel, etc. ==Les commandes graphiques/vidéo/autres : des ordres envoyés au GPU== Tous les traitements que la carte graphique doit effectuer, qu'il s'agisse de rendu 2D, de calculs 2D, du décodage matérielle d'un flux vidéo, ou de calculs généralistes, sont envoyés par le pilote de la carte graphique, sous la forme de '''commandes'''. Ces commandes demandent à la carte graphique d'effectuer une opération 2D, ou une opération 3D, ou encore le rendu d'une vidéo. Les commandes graphiques en question varient beaucoup selon la carte graphique. Les commandes sont régulièrement revues et chaque nouvelle architecture a quelques changements par rapport aux modèles plus anciens. Des commandes peuvent apparaître, d'autres disparaître, d'autre voient leur fonctionnement légèrement altéré, etc. Mais dans les grandes lignes, on peut classer ces commandes en quelques grands types. Les commandes les plus importantes s'occupent de l'affichage 3D : afficher une image à partir de paquets de sommets, préparer le passage d'une image à une autre, changer la résolution, etc. Plus rare, d'autres commandes servent à faire du rendu 2D : afficher un polygone, tracer une ligne, coloriser une surface, etc. Sur les cartes graphiques qui peuvent accélérer le rendu des vidéos, il existe des commandes spécialisées pour l’accélération des vidéos. Pour donner quelques exemples, prenons les commandes 2D de la carte graphique AMD Radeon X1800. {|class="wikitable" |- ! Commandes 2D ! Fonction |- |PAINT |Peindre un rectangle d'une certaine couleur |- |PAINT_MULTI |Peindre des rectangles (pas les mêmes paramètres que PAINT) |- |BITBLT |Copie d'un bloc de mémoire dans un autre |- |BITBLT_MULTI |Plusieurs copies de blocs de mémoire dans d'autres |- |TRANS_BITBLT |Copie de blocs de mémoire avec un masque |- |NEXTCHAR |Afficher un caractère avec une certaine couleur |- |HOSTDATA_BLT |Écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo |- |POLYLINE |Afficher des lignes reliées entre elles |- |POLYSCANLINES |Afficher des lignes |- |PLY_NEXTSCAN |Afficher plusieurs lignes simples |- |SET_SCISSORS |Utiliser des coupes (ciseaux) |- |LOAD_PALETTE |Charger la palette pour affichage 2D |} ===Le tampon de commandes=== L'envoi des commandes à la carte graphique ne se fait pas directement. La carte graphique n'est pas toujours libre pour accepter une nouvelle commande, soit parce qu'elle est occupée par une commande précédente, soit parce qu'elle fait autre chose. Il faut alors faire patienter les données tant que la carte graphique est occupée. Les pilotes de la carte graphique vont les mettre en attente dans le '''tampon de commandes'''. Le tampon de commandes est ce qu'on appelle une file, une zone de mémoire dans laquelle on stocke des données dans l'ordre d'ajout. Si le tampon de commandes est plein, le driver n'accepte plus de demandes en provenance des applications. Un tampon de commandes plein est généralement mauvais signe : cela signifie que la carte graphique est trop lente pour traiter les demandes qui lui sont faites. Par contre, il arrive que le tampon de commandes soit vide : dans ce cas, c'est simplement que la carte graphique est trop rapide comparé au processeur, qui n'arrive alors pas à donner assez de commandes à la carte graphique pour l'occuper suffisamment. Le tampon de commande est soit une mémoire FIFO séparée, soit une portion de la mémoire vidéo. Le NV1, la toute première carte graphique NVIDIA, utilisait une mémoire FIFO intégrée à la carte graphique, séparée des autres circuits. Le processeur envoyait les commandes par rafale au GPU, à savoir qu'il envoyait plusieurs dizaines ou centaines de commandes à la suite, avant de passer à autre chose. Le GPU traitait les commandes une par une, à un rythme bien plus lent. Le processeur pouvait consulter la FIFO pour savoir s'il restait des entrées libres et combien. Le processeur savait ainsi combien d'écritures il pouvait envoyer en une fois au GPU. : Le fonctionnement de la FIFO du NV1 est décrit dans le brevet ''US5805930A : System for FIFO informing the availability of stages to store commands which include data and virtual address sent directly from application programs''. ===Le processeur de commandes=== Le '''processeur de commande''' est un circuit qui gère les commandes envoyées par le processeur. Il lit la commande la plus ancienne dans le tampon de commande, l’interprète, l’exécute, puis passe à la suivante. Le processeur de commande est un circuit assez compliqué. Sur les cartes graphiques anciennes, c'était un circuit séquentiel complexe, fabriqué à la main et était la partie la plus complexe du processeur graphique. Sur les cartes graphiques modernes, c'est un véritable microcontrôleur, avec un processeur, de la mémoire RAM, etc. Lors de l'exécution d'une commande, le processeur de commande pilote les circuits de la carte graphique. Précisément, il répartit le travail entre les différents circuits de la carte graphique et assure que l'ordre du pipeline est respecté. Pour donner un exemple, prenons la première carte graphique de NVIDIA, le NV1. Il s'agissait d'une carte multimédia qui incorporait non seulement une carte 2D/3D, mais aussi une carte son un contrôleur de disque et de quoi communiquer avec des manettes. De plus, il incorporait un contrôleur DMA pour échanger des données entre RAM système et les autres circuits. Et à tout cela, il fallait ajouter la FIFO de commandes et le processeur de commande. L'ensemble était relié par un bus interne à la carte graphique. Le processeur de commande servait de gestionnaire principal. Il envoyait des ordres internes aux circuits de rendu 3D, à sa carte son, au contrôleur DMA. Par exemple, lorsque le processeur voulait copier des données en mémoire vidéo, il envoyait une commande de copie, qui était stockée dans le tampon de commande, puis était exécutée par le processeur de commande. Le processeur de commande envoyait alors les ordres adéquats au contrôleur DMA, qui faisait la copie des données. Lors d'un rendu 3D, une commande de rendu 3D est envoyée au NV1, le processeur de commande la traite et l'envoi dans les circuits de rendu 3D. [[File:Microarchitecture du GPU NV1 de NVIDIA.png|centre|vignette|upright=2|Microarchitecture du GPU NV1 de NVIDIA]] Les GPU modernes sont plus complexes, ce qui fait que le processeur de commande a plus de travail. Parmis les nombreuses tâches qui lui sont confiées, il répartit les ''shaders'' sur les processeurs de ''shaders'', en faisant en sorte qu'ils soient utilisés le plus possible. Dans le cas le plus simple, les unités sont alimentées en vertex/pixels les unes après les autres (principe du round-robin), mais des stratégies plus optimisées sont la règle de nos jours. Cela est très important sur les cartes graphiques : répartir plusieurs commandes sur plusieurs processeurs est une tâche difficile. Un chapitre entier sera d'ailleurs dédié à ce sujet. Il envoie aussi certaines commandes aux circuits fixes, comme l’''input assembler''. Là encore, il faut en sorte que les circuits fixes soient utilisés le mieux possible. Sa tâche est compliquée par le fait que les GPU récents ont plusieurs unités de traitement des sommets et des pixels, plusieurs ROP, plusieurs unités de textures, etc. Et c'est en partie le travail du processeur de commande que de répartir les calculs sur ces différentes unités. C'est là un problème assez compliqué pour le processeur de commande et ce pour tout un tas de raisons que nous ne ferons que survoler. Les contraintes d'ordonnancement de l'API et les règles de celle-ci sont une partie de la réponse. Mais d'autres raisons sont intrinsèques au rendu 3D ou à la conception des circuits. [[File:Architecture de base d'une carte 3D - 1.png|centre|vignette|upright=2.5|Architecture de base d'une carte 3D - 1]] Le processeur de commande n'a pas qu'un rôle de répartiteur. Il connait à tout instant l'état de la carte graphique, l'état de chaque sous-circuit. L'implémentation est variable suivant le GPU. La plus simple ajoute un registre d'état à chaque circuit, qui, est consultable en temps réel par le processeur de commande. Mais il est possible d'utiliser un système d'interruptions interne à la puce, ou circuits préviennent le processeur de commande quand ils ont terminé leur travail. Grâce à cela, le processeur de commandes garde en mémoire l'état de traitement de chaque commande : est-ce qu'elle est en train de s’exécuter sur le processeur graphique, est-ce qu'elle est mise en pause, est-ce qu'elle attend une donnée en provenance de la mémoire, est-ce qu'elle est terminée, etc. Pour résumer, le processeur de commande lit une commande, répartit le travail sur les différents circuits du GPU, et vérifie en permanence leur état pour déterminer si la commande est en pause, terminée, en cours d'exécution, etc. ==Le fonctionnement du processeur de commandes== Intuitivement, on se dit que le processeur de commande procède une commande à la fois. Mais les GPU modernes sont plus intelligents et peuvent exécuter plusieurs commandes en même temps, dans des circuits séparés. De nombreuses optimisations de ce type sont utilisées pour gagner en performance. Voyons comment un processeur de commande moderne fonctionne. ===L'ordonnancement et la gestion des ressources=== Le processeur de commande doit souvent mettre en pause certains circuits du pipeline, ainsi que les circuits précédents. Par exemple, si tous les processeurs de ''vertex shader'' sont occupés, l’''input assembler'' ne peut pas charger le paquet suivant car il n'y a aucun processeur de libre pour l’accueillir. Dans ce cas, l'étape d’''input assembly'' est mise en pause en attendant qu'un processeur de ''shader'' soit libre. La même chose a lieu pour l'étape de rastérisation : si aucun processeur de ''shader'' n'est libre, elle est mise en pause. Sauf que pour la rastérisation, cela a des conséquences sur les circuits précédents la rastérisation. Si un processeur de ''shader'' veut envoyer quelque chose au rastériseur alors qu'il est en pause, il devra lui aussi attendre que le rastériseur soit libre. On a la même chose quand les ROP sont occupés : les ''pixel shader'' ou l'unité de texture doivent parfois être mis en pause, ce qui peut entrainer la mise en pause des étapes précédentes, etc. En clair : plus un étape est situé vers la fin du pipeline graphique, plus sa mise en pause a de chances de se répercuter sur les étapes précédentes et de les mettre en pause aussi. Le processeur de commande doit gérer ces situations. ===Le pipelining des commandes=== Dans les cartes graphiques les plus rudimentaires, le processeur de commande exécute les commandes dans l'ordre. Il exécute une commande çà la fois et attend qu'une commande soit terminé pour en lancer une autre. Plusieurs commandes sont accumulées dans le tampon de commande, le processeur de commande les traite de la plus ancienne vers la plus récente. Du moins, les anciennes cartes graphiques faisaient comme cela, les cartes graphiques modernes sont un peu plus complexes. Elles n'attendent pas qu'une commande soit totalement terminée avant d'en lancer une nouvelle. Les processeurs de commande actuels sont capables d’exécuter plusieurs commandes en même temps. L'intérêt est un gain en performance assez important. Pour ceux qui ont déjà eu un cours d'architecture des ordinateurs avancé, lancer plusieurs commandes en même temps permet une forme de pipeline, dont les gains sont substantiels. Par exemple, imaginez qu'une commande de rendu 3D soit bien avancée et n'utilise que les processeurs de ''shaders'' et les ROP, mais laisse les unités géométriques libres. Il est alors possible de démarrer la commande suivante en avance, afin qu'elle remplisse les unités géométriques inutilisées. On a alors deux commandes en cours de traitement : une commande qui utilise la fin du pipeline uniquement, une autre qui utilise seulement le début du pipeline graphique. Le processeur de commande gère donc plusieurs commandes simultanées, à savoir plusieurs commandes qui en sont à des étapes différentes du pipeline. On peut avoir une commande qui est en cours dans l'étage de gestion de la géométrie, une autre dans le rastériseur, et une autre dans les unités de traitement des pixels. Le fait que les étapes du pipeline graphique sont à effectuer dans un ordre bien précis permet ce genre de chose assez facilement. Une autre possibilité est de faire des rendus en parallèle. Par exemple, imaginez qu'on ait des circuits séparés pour le rendu 2D et 3D. Prenons l'exemple où le calcul d'une image finale demande de faire un rendu 3D suivi d'un rendu 2D, par exemple un jeu vidéo en 3D qui a un HUD dessiné en 2D. Dans ce cas, on peut démarrer le calcul de l'image suivante dans le pipeline 3D pendant que la précédente est dans les circuits 2D, au lieu de laisser inutilisé le pipeline 3D pendant le rendu 2D. Mais c'est là un défi compliqué à relever pour le processeur de commande, qui donne lieu à son lot de problèmes. Le problème principal est le partage de ressources entre commandes. Par exemple, on peut prendre le cas où une commande n'utilise pas beaucoup les processeurs de ''shaders''. On pourrait imaginer lancer une seconde commande en parallèle, afin que la seconde commande utiliser les processeurs de ''shaders'' inutilisés. Mais cela n'est possible que si les circuits fixes sont capables d'accepter une seconde commande. Si la première commande sature les circuits fixe, le lancement de la seconde commande sera empêché. Mais si ce n'est pas le cas, les deux commandes pourront être lancées en même temps. Pareil pour le débit mémoire, qui doit alors être partagé entre deux commandes simultanées, ce qui est à prendre en compte. ===La synchronisation de l’exécution des commandes avec le processeur=== Il arrive que le processeur doive savoir où en est le traitement des commandes, ce qui est très utile pour la gestion de la mémoire vidéo. Un premier exemple : comment éviter de saturer une carte graphique de commande, alors qu'on ne sait pas si elles traite les commandes rapidement ou non ? L'idéal est de regarder où en est la carte graphique dans l'exécution des commandes. Si elle n'en est qu'au début du tampon de commande et que celui-ci est bien remplit, alors il vaut mieux lever le pied et ne pas envoyer de nouvelles commandes. A l'inverse, si le tampon de commande est presque vide, envoyer des commandes est la meilleure idée possible. Un autre exemple un peu moins parlant est celui de la gestion de la mémoire vidéo. Rappelons qu'elle est réalisée par le pilote de la carte graphique, sur le processeur principal, qui décide d'allouer et de libérer de la mémoire vidéo. Pour donner un exemple d'utilisation, imaginez que le pilote de la carte graphique doive libérer de la mémoire pour pouvoir ajouter une nouvelle commande. Comment éviter d'enlever une texture tant que les commandes qui l'utilisent ne sont pas terminées ? Ce problème ne se limite pas aux textures, mais vaut pour tout ce qui est placé en mémoire vidéo. Il faut donc que la carte graphique trouve un moyen de prévenir le processeur que le traitement de telle commande est terminée, que telle commande en est rendue à tel ou tel point, etc. Pour cela, on a globalement deux grandes solutions. La première est celle des interruptions, abordées dans les chapitres précédents. Mais elles sont assez couteuses et ne sont utilisées que pour des évènements vraiment importants, critiques, qui demandent une réaction rapide du processeur. L'autre solution est celle du ''pooling'', où le processeur monitore la carte graphique à intervalles réguliers. Deux solutions bien connues de ceux qui ont déjà lu un cours d'architecture des ordinateurs digne de ce nom, rien de bien neuf : la carte graphique communique avec le processeur comme tout périphérique. Pour faciliter l'implémentation du ''pooling'', la carte graphique contient des registres de statut, dans le processeur de commande, qui mémorisent tout ou partie de l'état de la carte graphique. Si un problème survient, certains bits du registre de statut seront mis à 1 pour indiquer que telle erreur bien précise a eu lieu. Il existe aussi un registre de statut qui mémorise le numéro de la commande en cours, ou de la dernière commande terminée, ce qui permet de savoir où en est la carte graphique dans l'exécution des commandes. Et certaines registres de statut sont dédiés à la gestion des commandes. Ils sont totalement programmable, la carte graphique peut écrire dedans sans problème. Les cartes graphiques récentes incorporent des commandes pour modifier ces registres de statut au besoin. Elles sont appelées des '''commandes de synchronisation''' : les barrières (''fences''). Elles permettent d'écrire une valeur dans un registre de statut quand telle ou telle condition est remplie. Par exemple, si jamais une commande est terminée, on peut écrire la valeur 1 dans tel ou tel registre. La condition en question peut être assez complexe et se résumer à quelque chose du genre : "si jamais toutes les ''shaders'' ont fini de traiter tel ensemble de textures, alors écrit la valeur 1024 dans le registre de statut numéro 9". ===La synchronisation de l’exécution des commandes intra-GPU=== Lancer plusieurs commandes en parallèle dans le pipeline permet de gagner en performance.Mais cela a un gros défaut : il n'est pas garantit que les commandes se terminent dans l'ordre. Si on démarre une seconde commande après la première, il arrive que la seconde finisse avant. Pire : il n'est pas garantit qu'elles s'exécutent dans l'ordre. Dans la plupart des cas, cela ne pose pas de problèmes. Mais dans d'autres, cela donne des résultats erronés. Pour donner un exemple, utilisons les commandes de rendu 2D vues plus haut, histoire de simplifier le tout. Imaginez que vous codez un jeu vidéo et que le rendu se fait en 2D, partons sur un jeu de type FPS. Vous avez une série de commandes pour calculer l'image à rendre à l'écran, suivie par une série de commandes finales pour dessiner le HUB. Pour dessiner le HUD, vous utilisez des commandes HOSTDATA_BLT, dont le but est d'écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo. Et bien ces commandes HOSTDATA_BLT doivent démarrer une fois que le rendu de l'image est complétement terminé. Imaginez que vous dessiniez le HUD sur une portion de l'image pas encore terminée et que celui-ci est effacé par des écritures ultérieures ! Pour éviter tout problème, les GPU incorporent des commandes de synchronisation intra-GPU, destinées au processeur de commande, aussis appelées des '''commandes de sémaphore'''. Elles permettent de mettre en pause le lancement d'une nouvelle commande tant que les précédentes ne sont pas totalement ou partiellement terminées. Les plus simples empêchent le démarrage d'une commande tant que les précédentes ne sont pas terminées. D'autres permettent de démarrer une commande si et seulement si certaines commandes sont terminées. D'autres sont encore plus précises : elles empêchent le démarrage d'une nouvelle commande tant qu'une commande précédente n'a pas atteint un certain stade de son exécution. Là encore, de telles commandes sont des commandes du style "attend que le registre de statut numéro N contienne la valeur adéquate avant de poursuivre l'exécution des commandes". Les commandes en question peuvent être sur le même modèle que précédemment, à savoir des commandes qui lisent les registres de statut. Mais elles peuvent aussi se baser sur le fait que telle ou telle ressource de rendu est libre ou non. Des commandes successives se partagent souvent des données, et que de nombreuses commandes différentes peuvent s'exécuter en même temps. Or, si une commande veut modifier les données utilisées par une autre commande, il faut que l'ordre des commandes soit maintenu : la commande la plus récente ne doit pas modifier les données utilisées par une commande plus ancienne. Avec ce modèle, les sémaphores bloquent une commande tant qu'une ressource (une texture) est utilisée par une autre commande. {|class="wikitable" |- ! Commandes de synchronisation ! Fonction |- |NOP |Ne rien faire |- |WAIT_SEMAPHORE |Attendre la synchronisation avec un sémaphore |- |WAIT_MEM |Attendre que la mémoire vidéo soit disponible et inoccupée par le CPU |} ==L'arbitrage de l'accès à la carte graphique== Il n'est pas rare que plusieurs applications souhaitent accéder en même temps à la carte graphique. Imaginons que vous regardez une vidéo en ''streaming'' sur votre navigateur web, avec un programme de ''cloud computing'' de type ''Folding@Home'' qui tourne en arrière-plan, sur Windows. Le décodage de la vidéo est réalisé par la carte graphique, Windows s'occupe de l'affichage du bureau et des fenêtres, le navigateur web doit afficher tout ce qui est autour de la vidéo (la page web), le programme de ''cloud computing'' va lancer ses calculs sur la carte graphique, etc. Des situations de ce genre sont assez courantes et c'est soit le pilote qui s'en charge, soit la carte graphique elle-même. ===L'arbitrage logiciel du GPU=== L'arbitrage logiciel est la méthode la plus simple. Concrètement, c'est le système d'exploitation et/ou le pilote de la carte graphique qui gèrent l'arbitrage du GPU. Dans les deux cas, tout est fait en logiciel. Les commandes sont accumulées dans un tampon de commande, voire plusieurs, et l'OS/pilote décide quelle commande envoyer en priorité. Sur Windows, avant l'arrivée du modèle de driver dit ''Windows Display Driver Model'', de telles situations étaient gérées simplement. Les applications ajoutaient des commandes dans une file de commande unique. Les commandes étaient exécutées dans l'ordre, en mode premier entrée dans la file premier sorti/exécuté. Il n'y avait pour ainsi dire pas d'arbitrage entre les applications. Et ce n'était pas un problème car, à l'époque, les seules applications qui utilisaient le GPU étaient des jeux vidéos fonctionnant en mode plein écran. Avec le modèle de driver ''Windows Display Driver Model'' (WDDM), le GPU est maintenant arbitré, à savoir que les applications ont accès à tour de rôle au GPU, certaines ayant droit à plus de temps GPU que d'autres. Chaque programme a accès à la carte graphique durant quelques dizaines ou centaines de millisecondes, à tour de rôle. Si le programme finissait son travail en moins de temps que la durée impartie, il laissait la main au programme suivant. S’il atteignait la durée maximale allouée, il était interrompu pour laisser la place au programme suivant. Et chaque programme avait droit d'accès à la carte graphique chacun à son tour. Un tel algorithme en tourniquet est très simple, mais avait cependant quelques défauts. De nos jours, les algorithmes d'ordonnancement d'accès sont plus élaborés, bien qu'il soit difficile de trouver de la littérature ou des brevets sur le sujet. Une autre fonctionnalité de WDDM est que les applications utilisant le GPU peuvent se partager la mémoire vidéo sans se marcher dessus. Avant, toutes les applications avaient accès à toute la mémoire vidéo, bien que ce soit par l’intermédiaire de commandes spécifiques. Mais avec WDDM, chaque application dispose de sa propre portion de mémoire vidéo, à laquelle est la seule à avoir accès. Une application ne peut plus lire le contenu réel de la mémoire vidéo, et encore moins lire le contenu des autres applications. : Il s'agit d'un équivalent à l'isolation des processus pour les programmes Windows, mais appliqué à la mémoire vidéo et non la mémoire système. Et cette isolation est rendue d'autant plus simple que les GPU modernes implémentent un système de mémoire virtuelle à pagination très poussé, avec du swap en mémoire RAM système, une protection mémoire, et bien d'autres fonctionnalités. Nous en reparlerons dans les chapitres sur la mémoire vidéo. ===L'arbitrage accéléré par le GPU=== Depuis 2020, avec l'arrivée de la ''Windows 10 May 2020 update'', Windows est capable de déléguer l'arbitrage du GPU au GPU lui-même. Le GPU gère lui-même l'arbitrage, du moins en partie. En partie, car l'OS gére les priorité, à savoir quelle application a droit à plus de temps que les autres. Par contre, la gestion du ''quantum'' de temps ou les commutations de contexte (on stoppe une application pour laisser la place à une autre), est du fait du GPU lui-même. L'avantage est que cela décharge le processeur d'une tâche assez lourde en calcul, pour la déporter sur le GPU. Un autre avantage est que le GPU peut gérer plus finement les ''quantum'' de temps et la commutation de contexte. Le CPU principal gère des durées assez importantes, de l'ordre de la milliseconde. De plus, il doit communiquer avec le GPU par des mécanismes temporellement imprécis, comme des interruptions. Avec l'arbitrage accéléré par le GPU, le GPU n'a plus besoin de communiquer avec le CPU pour l'arbitrage et peut le faire plus précisément, plus immédiatement. Un gain en performance théorique est donc possible. L'arbitrage accéléré par le GPU est le fait soit du processeur de commandes, soit d'un processeur spécialisé, séparé. {{NavChapitre | book=Les cartes graphiques | prev=La hiérarchie mémoire d'un GPU | prevText=La hiérarchie mémoire d'un GPU | next=Le pipeline géométrique d'avant DirectX 10 | netxText=Le pipeline géométrique d'avant DirectX 10 }}{{autocat}} 2r4tr591ub3qntygyo65rlq7o47fec8 744055 744044 2025-06-03T17:00:38Z Mewtow 31375 /* L'arbitrage accéléré par le GPU */ 744055 wikitext text/x-wiki Dans ce chapitre, nous allons parler de tous les intermédiaires qui se placent entre une application de rendu 3D et les circuits de rendu 3D proprement dit. En premier lieu, on trouve le pilote de la carte graphique, aux fonctions multiples et variées. En second lieu, nous allons parler d'un circuit de la carte graphique qui fait l'interface entre le logiciel et les circuits de rendu 3D de la carte graphique : le processeur de commandes. Ce processeur de commandes est un circuit qui sert de chef d'orchestre, qui pilote le fonctionnement global de la carte graphique. API 3D, pilote de carte graphique et processeur de commande travaillent de concert pour que l'application communique avec la carte graphique. Nous allons d'abord voir le pilote de la carte graphique, avant de voir le fonctionnement du processeur de commande. ==Le pilote de carte graphique== Le pilote de la carte graphique est un logiciel qui s'occupe de faire l'interface entre le logiciel et la carte graphique. De manière générale, les pilotes de périphérique sont des intermédiaires entre les applications/APIs et le matériel. En théorie, le système d'exploitation est censé jouer ce rôle, mais il n'est pas programmé pour être compatible avec tous les périphériques vendus sur le marché. À la place, le système d'exploitation ne gère pas directement certains périphériques, mais fournit de quoi ajouter ce qui manque. Le pilote d'un périphérique sert justement à ajouter ce qui manque : ils ajoutent au système d'exploitation de quoi reconnaître le périphérique, de quoi l'utiliser au mieux. Pour une carte graphique, il a diverses fonctions que nous allons voir ci-dessous. Avant toute chose, précisons que les systèmes d'exploitation usuels (Windows, Linux, MacOsX et autres) sont fournis avec un pilote de carte graphique générique, compatible avec la plupart des cartes graphiques existantes. Rien de magique derrière cela : toutes les cartes graphiques vendues depuis plusieurs décennies respectent des standards, comme le VGA, le VESA, et d'autres. Et le pilote de base fournit avec le système d'exploitation est justement compatible avec ces standards minimaux. Mais le pilote ne peut pas profiter des fonctionnalités qui sont au-delà de ce standard. L'accélération 3D est presque inexistante avec le pilote de base, qui ne sert qu'à faire du rendu 2D (de quoi afficher l’interface de base du système d'exploitation, comme le bureau de Windows). Et même pour du rendu 2D, la plupart des fonctionnalités de la carte graphique ne sont pas disponibles. Par exemple, certaines résolutions ne sont pas disponibles, notamment les grandes résolutions. Ou encore, les performances sont loin d'être excellentes. Si vous avez déjà utilisé un PC sans pilote de carte graphique installé, vous avez certainement remarqué qu'il était particulièrement lent. ===La gestion des interruptions=== Une fonction particulièrement importante du pilote de carte graphique est la réponse aux interruptions lancées par la carte graphique. Pour rappel, les interruptions sont une fonctionnalité qui permet à un périphérique de communiquer avec le processeur, tout en économisant le temps de calcul de ce dernier. Typiquement, lorsqu'un périphérique lance une interruption, le processeur stoppe son travail et exécute automatiquement une routine d'interruption, un petit programme qui s'occupe de gérer le périphérique, de faire ce qu'il faut, ce que l'interruption a demandé. Il y a plusieurs interruptions possibles, chacune ayant son propre numéro et sa fonction dédiée, chacune ayant sa propre routine d'interruption. Après tout, la routine qui gère un débordement de la mémoire vidéo n'est pas la même que celle qui gère un changement de fréquence du GPU ou la fin du calcul d'une image 3D. Le pilote fournit l'ensemble des routines d'interruptions nécessaires pour gérer la carte graphique. ===La compilation des ''shaders''=== Le pilote de carte graphique est aussi chargé de traduire les ''shaders'' en code machine. En soi, cette étape est assez complexe, et ressemble beaucoup à la compilation d'un programme informatique normal. Les ''shaders'' sont écrits dans un langage de programmation de haut niveau, comme le HLSL ou le GLSL, mais ce n'est pas ce code source qui est compilé par le pilote de carte graphique. À la place, les ''shaders'' sont pré-compilés vers un langage dit intermédiaire, avant d'être compilé par le pilote en code machine. Le langage intermédiaire, comme son nom l'indique, sert d'intermédiaire entre le code source écrit en HLSL/GLSL et le code machine exécuté par la carte graphique. Il ressemble à un langage assembleur, mais reste malgré tout assez générique pour ne pas être un véritable code machine. Par exemple, il y a peu de limitations quant au nombre de processeurs ou de registres. En clair, il y a deux passes de compilation : une passe de traduction du code source en langage intermédiaire, puis une passe de compilation du code intermédiaire vers le code machine. Notons que la première passe est réalisée par le programmeur des ''shaders'', non pas par l'utilisateur. Par exemple, les ''shaders'' d'un jeu vidéo sont fournis déjà pré-compilés : les fichiers du jeu ne contiennent pas le code source GLSL/HLSL, mais du code intermédiaire. L'avantage de cette méthode est que le travail du pilote est fortement simplifié. Le pilote de périphérique pourrait compiler directement du code HLSL/GLSL, mais le temps de compilation serait très long et cela aurait un impact sur les performances. Avec l'usage du langage intermédiaire, le gros du travail à été fait lors de la première passe de compilation et le pilote graphique ne fait que finir le travail. Les optimisations importantes ont déjà été réalisées lors de la première passe. Il doit bien faire la traduction, ajouter quelques optimisations de bas niveau par-ci par-là, mais rien de bien gourmand en processeur. Autant dire que cela économise plus le processeur que si on devait compiler complètement les ''shaders'' à chaque exécution. Fait amusant, il faut savoir que le pilote peut parfois remplacer les ''shaders'' d'un jeu vidéo à la volée. Les pilotes récents embarquent en effet des ''shaders'' alternatifs pour les jeux les plus vendus et/ou les plus populaires. Lorsque vous lancez un de ces jeux vidéo et que le ''shader'' originel s'exécute, le pilote le détecte automatiquement et le remplace par la version améliorée, fournie par le pilote. Évidemment, le ''shader'' alternatif du pilote est optimisé pour le matériel adéquat. Cela permet de gagner en performance, voire en qualité d'image, sans pour autant que les concepteurs du jeu n'aient quoique ce soit à faire. Enfin, certains ''shaders'' sont fournis par le pilote pour d'autres raisons. Par exemple, les cartes graphiques récentes n'ont pas de circuits fixes pour traiter la géométrie. Autant les anciennes cartes graphiques avaient des circuits de T&L qui s'en occupaient, autant tout cela doit être émulé sur les machines récentes. Sans cette émulation, les vieux jeux vidéo conçus pour exploiter le T&L et d'autres technologies du genre ne fonctionneraient plus du tout. Émuler les circuits fixes disparus sur les cartes récentes est justement le fait de ''shaders'', présents dans le pilote de carte graphique. ===Les autres fonctions=== Le pilote a aussi bien d'autres fonctions. Par exemple, il s'occupe d'initialiser la carte graphique, de fixer la résolution, d'allouer la mémoire vidéo, de gérer le curseur de souris matériel, etc. ==Les commandes graphiques/vidéo/autres : des ordres envoyés au GPU== Tous les traitements que la carte graphique doit effectuer, qu'il s'agisse de rendu 2D, de calculs 2D, du décodage matérielle d'un flux vidéo, ou de calculs généralistes, sont envoyés par le pilote de la carte graphique, sous la forme de '''commandes'''. Ces commandes demandent à la carte graphique d'effectuer une opération 2D, ou une opération 3D, ou encore le rendu d'une vidéo. Les commandes graphiques en question varient beaucoup selon la carte graphique. Les commandes sont régulièrement revues et chaque nouvelle architecture a quelques changements par rapport aux modèles plus anciens. Des commandes peuvent apparaître, d'autres disparaître, d'autre voient leur fonctionnement légèrement altéré, etc. Mais dans les grandes lignes, on peut classer ces commandes en quelques grands types. Les commandes les plus importantes s'occupent de l'affichage 3D : afficher une image à partir de paquets de sommets, préparer le passage d'une image à une autre, changer la résolution, etc. Plus rare, d'autres commandes servent à faire du rendu 2D : afficher un polygone, tracer une ligne, coloriser une surface, etc. Sur les cartes graphiques qui peuvent accélérer le rendu des vidéos, il existe des commandes spécialisées pour l’accélération des vidéos. Pour donner quelques exemples, prenons les commandes 2D de la carte graphique AMD Radeon X1800. {|class="wikitable" |- ! Commandes 2D ! Fonction |- |PAINT |Peindre un rectangle d'une certaine couleur |- |PAINT_MULTI |Peindre des rectangles (pas les mêmes paramètres que PAINT) |- |BITBLT |Copie d'un bloc de mémoire dans un autre |- |BITBLT_MULTI |Plusieurs copies de blocs de mémoire dans d'autres |- |TRANS_BITBLT |Copie de blocs de mémoire avec un masque |- |NEXTCHAR |Afficher un caractère avec une certaine couleur |- |HOSTDATA_BLT |Écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo |- |POLYLINE |Afficher des lignes reliées entre elles |- |POLYSCANLINES |Afficher des lignes |- |PLY_NEXTSCAN |Afficher plusieurs lignes simples |- |SET_SCISSORS |Utiliser des coupes (ciseaux) |- |LOAD_PALETTE |Charger la palette pour affichage 2D |} ===Le tampon de commandes=== L'envoi des commandes à la carte graphique ne se fait pas directement. La carte graphique n'est pas toujours libre pour accepter une nouvelle commande, soit parce qu'elle est occupée par une commande précédente, soit parce qu'elle fait autre chose. Il faut alors faire patienter les données tant que la carte graphique est occupée. Les pilotes de la carte graphique vont les mettre en attente dans le '''tampon de commandes'''. Le tampon de commandes est ce qu'on appelle une file, une zone de mémoire dans laquelle on stocke des données dans l'ordre d'ajout. Si le tampon de commandes est plein, le driver n'accepte plus de demandes en provenance des applications. Un tampon de commandes plein est généralement mauvais signe : cela signifie que la carte graphique est trop lente pour traiter les demandes qui lui sont faites. Par contre, il arrive que le tampon de commandes soit vide : dans ce cas, c'est simplement que la carte graphique est trop rapide comparé au processeur, qui n'arrive alors pas à donner assez de commandes à la carte graphique pour l'occuper suffisamment. Le tampon de commande est soit une mémoire FIFO séparée, soit une portion de la mémoire vidéo. Le NV1, la toute première carte graphique NVIDIA, utilisait une mémoire FIFO intégrée à la carte graphique, séparée des autres circuits. Le processeur envoyait les commandes par rafale au GPU, à savoir qu'il envoyait plusieurs dizaines ou centaines de commandes à la suite, avant de passer à autre chose. Le GPU traitait les commandes une par une, à un rythme bien plus lent. Le processeur pouvait consulter la FIFO pour savoir s'il restait des entrées libres et combien. Le processeur savait ainsi combien d'écritures il pouvait envoyer en une fois au GPU. : Le fonctionnement de la FIFO du NV1 est décrit dans le brevet ''US5805930A : System for FIFO informing the availability of stages to store commands which include data and virtual address sent directly from application programs''. ===Le processeur de commandes=== Le '''processeur de commande''' est un circuit qui gère les commandes envoyées par le processeur. Il lit la commande la plus ancienne dans le tampon de commande, l’interprète, l’exécute, puis passe à la suivante. Le processeur de commande est un circuit assez compliqué. Sur les cartes graphiques anciennes, c'était un circuit séquentiel complexe, fabriqué à la main et était la partie la plus complexe du processeur graphique. Sur les cartes graphiques modernes, c'est un véritable microcontrôleur, avec un processeur, de la mémoire RAM, etc. Lors de l'exécution d'une commande, le processeur de commande pilote les circuits de la carte graphique. Précisément, il répartit le travail entre les différents circuits de la carte graphique et assure que l'ordre du pipeline est respecté. Pour donner un exemple, prenons la première carte graphique de NVIDIA, le NV1. Il s'agissait d'une carte multimédia qui incorporait non seulement une carte 2D/3D, mais aussi une carte son un contrôleur de disque et de quoi communiquer avec des manettes. De plus, il incorporait un contrôleur DMA pour échanger des données entre RAM système et les autres circuits. Et à tout cela, il fallait ajouter la FIFO de commandes et le processeur de commande. L'ensemble était relié par un bus interne à la carte graphique. Le processeur de commande servait de gestionnaire principal. Il envoyait des ordres internes aux circuits de rendu 3D, à sa carte son, au contrôleur DMA. Par exemple, lorsque le processeur voulait copier des données en mémoire vidéo, il envoyait une commande de copie, qui était stockée dans le tampon de commande, puis était exécutée par le processeur de commande. Le processeur de commande envoyait alors les ordres adéquats au contrôleur DMA, qui faisait la copie des données. Lors d'un rendu 3D, une commande de rendu 3D est envoyée au NV1, le processeur de commande la traite et l'envoi dans les circuits de rendu 3D. [[File:Microarchitecture du GPU NV1 de NVIDIA.png|centre|vignette|upright=2|Microarchitecture du GPU NV1 de NVIDIA]] Les GPU modernes sont plus complexes, ce qui fait que le processeur de commande a plus de travail. Parmis les nombreuses tâches qui lui sont confiées, il répartit les ''shaders'' sur les processeurs de ''shaders'', en faisant en sorte qu'ils soient utilisés le plus possible. Dans le cas le plus simple, les unités sont alimentées en vertex/pixels les unes après les autres (principe du round-robin), mais des stratégies plus optimisées sont la règle de nos jours. Cela est très important sur les cartes graphiques : répartir plusieurs commandes sur plusieurs processeurs est une tâche difficile. Un chapitre entier sera d'ailleurs dédié à ce sujet. Il envoie aussi certaines commandes aux circuits fixes, comme l’''input assembler''. Là encore, il faut en sorte que les circuits fixes soient utilisés le mieux possible. Sa tâche est compliquée par le fait que les GPU récents ont plusieurs unités de traitement des sommets et des pixels, plusieurs ROP, plusieurs unités de textures, etc. Et c'est en partie le travail du processeur de commande que de répartir les calculs sur ces différentes unités. C'est là un problème assez compliqué pour le processeur de commande et ce pour tout un tas de raisons que nous ne ferons que survoler. Les contraintes d'ordonnancement de l'API et les règles de celle-ci sont une partie de la réponse. Mais d'autres raisons sont intrinsèques au rendu 3D ou à la conception des circuits. [[File:Architecture de base d'une carte 3D - 1.png|centre|vignette|upright=2.5|Architecture de base d'une carte 3D - 1]] Le processeur de commande n'a pas qu'un rôle de répartiteur. Il connait à tout instant l'état de la carte graphique, l'état de chaque sous-circuit. L'implémentation est variable suivant le GPU. La plus simple ajoute un registre d'état à chaque circuit, qui, est consultable en temps réel par le processeur de commande. Mais il est possible d'utiliser un système d'interruptions interne à la puce, ou circuits préviennent le processeur de commande quand ils ont terminé leur travail. Grâce à cela, le processeur de commandes garde en mémoire l'état de traitement de chaque commande : est-ce qu'elle est en train de s’exécuter sur le processeur graphique, est-ce qu'elle est mise en pause, est-ce qu'elle attend une donnée en provenance de la mémoire, est-ce qu'elle est terminée, etc. Pour résumer, le processeur de commande lit une commande, répartit le travail sur les différents circuits du GPU, et vérifie en permanence leur état pour déterminer si la commande est en pause, terminée, en cours d'exécution, etc. ==Le fonctionnement du processeur de commandes== Intuitivement, on se dit que le processeur de commande procède une commande à la fois. Mais les GPU modernes sont plus intelligents et peuvent exécuter plusieurs commandes en même temps, dans des circuits séparés. De nombreuses optimisations de ce type sont utilisées pour gagner en performance. Voyons comment un processeur de commande moderne fonctionne. ===L'ordonnancement et la gestion des ressources=== Le processeur de commande doit souvent mettre en pause certains circuits du pipeline, ainsi que les circuits précédents. Par exemple, si tous les processeurs de ''vertex shader'' sont occupés, l’''input assembler'' ne peut pas charger le paquet suivant car il n'y a aucun processeur de libre pour l’accueillir. Dans ce cas, l'étape d’''input assembly'' est mise en pause en attendant qu'un processeur de ''shader'' soit libre. La même chose a lieu pour l'étape de rastérisation : si aucun processeur de ''shader'' n'est libre, elle est mise en pause. Sauf que pour la rastérisation, cela a des conséquences sur les circuits précédents la rastérisation. Si un processeur de ''shader'' veut envoyer quelque chose au rastériseur alors qu'il est en pause, il devra lui aussi attendre que le rastériseur soit libre. On a la même chose quand les ROP sont occupés : les ''pixel shader'' ou l'unité de texture doivent parfois être mis en pause, ce qui peut entrainer la mise en pause des étapes précédentes, etc. En clair : plus un étape est situé vers la fin du pipeline graphique, plus sa mise en pause a de chances de se répercuter sur les étapes précédentes et de les mettre en pause aussi. Le processeur de commande doit gérer ces situations. ===Le pipelining des commandes=== Dans les cartes graphiques les plus rudimentaires, le processeur de commande exécute les commandes dans l'ordre. Il exécute une commande çà la fois et attend qu'une commande soit terminé pour en lancer une autre. Plusieurs commandes sont accumulées dans le tampon de commande, le processeur de commande les traite de la plus ancienne vers la plus récente. Du moins, les anciennes cartes graphiques faisaient comme cela, les cartes graphiques modernes sont un peu plus complexes. Elles n'attendent pas qu'une commande soit totalement terminée avant d'en lancer une nouvelle. Les processeurs de commande actuels sont capables d’exécuter plusieurs commandes en même temps. L'intérêt est un gain en performance assez important. Pour ceux qui ont déjà eu un cours d'architecture des ordinateurs avancé, lancer plusieurs commandes en même temps permet une forme de pipeline, dont les gains sont substantiels. Par exemple, imaginez qu'une commande de rendu 3D soit bien avancée et n'utilise que les processeurs de ''shaders'' et les ROP, mais laisse les unités géométriques libres. Il est alors possible de démarrer la commande suivante en avance, afin qu'elle remplisse les unités géométriques inutilisées. On a alors deux commandes en cours de traitement : une commande qui utilise la fin du pipeline uniquement, une autre qui utilise seulement le début du pipeline graphique. Le processeur de commande gère donc plusieurs commandes simultanées, à savoir plusieurs commandes qui en sont à des étapes différentes du pipeline. On peut avoir une commande qui est en cours dans l'étage de gestion de la géométrie, une autre dans le rastériseur, et une autre dans les unités de traitement des pixels. Le fait que les étapes du pipeline graphique sont à effectuer dans un ordre bien précis permet ce genre de chose assez facilement. Une autre possibilité est de faire des rendus en parallèle. Par exemple, imaginez qu'on ait des circuits séparés pour le rendu 2D et 3D. Prenons l'exemple où le calcul d'une image finale demande de faire un rendu 3D suivi d'un rendu 2D, par exemple un jeu vidéo en 3D qui a un HUD dessiné en 2D. Dans ce cas, on peut démarrer le calcul de l'image suivante dans le pipeline 3D pendant que la précédente est dans les circuits 2D, au lieu de laisser inutilisé le pipeline 3D pendant le rendu 2D. Mais c'est là un défi compliqué à relever pour le processeur de commande, qui donne lieu à son lot de problèmes. Le problème principal est le partage de ressources entre commandes. Par exemple, on peut prendre le cas où une commande n'utilise pas beaucoup les processeurs de ''shaders''. On pourrait imaginer lancer une seconde commande en parallèle, afin que la seconde commande utiliser les processeurs de ''shaders'' inutilisés. Mais cela n'est possible que si les circuits fixes sont capables d'accepter une seconde commande. Si la première commande sature les circuits fixe, le lancement de la seconde commande sera empêché. Mais si ce n'est pas le cas, les deux commandes pourront être lancées en même temps. Pareil pour le débit mémoire, qui doit alors être partagé entre deux commandes simultanées, ce qui est à prendre en compte. ===La synchronisation de l’exécution des commandes avec le processeur=== Il arrive que le processeur doive savoir où en est le traitement des commandes, ce qui est très utile pour la gestion de la mémoire vidéo. Un premier exemple : comment éviter de saturer une carte graphique de commande, alors qu'on ne sait pas si elles traite les commandes rapidement ou non ? L'idéal est de regarder où en est la carte graphique dans l'exécution des commandes. Si elle n'en est qu'au début du tampon de commande et que celui-ci est bien remplit, alors il vaut mieux lever le pied et ne pas envoyer de nouvelles commandes. A l'inverse, si le tampon de commande est presque vide, envoyer des commandes est la meilleure idée possible. Un autre exemple un peu moins parlant est celui de la gestion de la mémoire vidéo. Rappelons qu'elle est réalisée par le pilote de la carte graphique, sur le processeur principal, qui décide d'allouer et de libérer de la mémoire vidéo. Pour donner un exemple d'utilisation, imaginez que le pilote de la carte graphique doive libérer de la mémoire pour pouvoir ajouter une nouvelle commande. Comment éviter d'enlever une texture tant que les commandes qui l'utilisent ne sont pas terminées ? Ce problème ne se limite pas aux textures, mais vaut pour tout ce qui est placé en mémoire vidéo. Il faut donc que la carte graphique trouve un moyen de prévenir le processeur que le traitement de telle commande est terminée, que telle commande en est rendue à tel ou tel point, etc. Pour cela, on a globalement deux grandes solutions. La première est celle des interruptions, abordées dans les chapitres précédents. Mais elles sont assez couteuses et ne sont utilisées que pour des évènements vraiment importants, critiques, qui demandent une réaction rapide du processeur. L'autre solution est celle du ''pooling'', où le processeur monitore la carte graphique à intervalles réguliers. Deux solutions bien connues de ceux qui ont déjà lu un cours d'architecture des ordinateurs digne de ce nom, rien de bien neuf : la carte graphique communique avec le processeur comme tout périphérique. Pour faciliter l'implémentation du ''pooling'', la carte graphique contient des registres de statut, dans le processeur de commande, qui mémorisent tout ou partie de l'état de la carte graphique. Si un problème survient, certains bits du registre de statut seront mis à 1 pour indiquer que telle erreur bien précise a eu lieu. Il existe aussi un registre de statut qui mémorise le numéro de la commande en cours, ou de la dernière commande terminée, ce qui permet de savoir où en est la carte graphique dans l'exécution des commandes. Et certaines registres de statut sont dédiés à la gestion des commandes. Ils sont totalement programmable, la carte graphique peut écrire dedans sans problème. Les cartes graphiques récentes incorporent des commandes pour modifier ces registres de statut au besoin. Elles sont appelées des '''commandes de synchronisation''' : les barrières (''fences''). Elles permettent d'écrire une valeur dans un registre de statut quand telle ou telle condition est remplie. Par exemple, si jamais une commande est terminée, on peut écrire la valeur 1 dans tel ou tel registre. La condition en question peut être assez complexe et se résumer à quelque chose du genre : "si jamais toutes les ''shaders'' ont fini de traiter tel ensemble de textures, alors écrit la valeur 1024 dans le registre de statut numéro 9". ===La synchronisation de l’exécution des commandes intra-GPU=== Lancer plusieurs commandes en parallèle dans le pipeline permet de gagner en performance.Mais cela a un gros défaut : il n'est pas garantit que les commandes se terminent dans l'ordre. Si on démarre une seconde commande après la première, il arrive que la seconde finisse avant. Pire : il n'est pas garantit qu'elles s'exécutent dans l'ordre. Dans la plupart des cas, cela ne pose pas de problèmes. Mais dans d'autres, cela donne des résultats erronés. Pour donner un exemple, utilisons les commandes de rendu 2D vues plus haut, histoire de simplifier le tout. Imaginez que vous codez un jeu vidéo et que le rendu se fait en 2D, partons sur un jeu de type FPS. Vous avez une série de commandes pour calculer l'image à rendre à l'écran, suivie par une série de commandes finales pour dessiner le HUB. Pour dessiner le HUD, vous utilisez des commandes HOSTDATA_BLT, dont le but est d'écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo. Et bien ces commandes HOSTDATA_BLT doivent démarrer une fois que le rendu de l'image est complétement terminé. Imaginez que vous dessiniez le HUD sur une portion de l'image pas encore terminée et que celui-ci est effacé par des écritures ultérieures ! Pour éviter tout problème, les GPU incorporent des commandes de synchronisation intra-GPU, destinées au processeur de commande, aussis appelées des '''commandes de sémaphore'''. Elles permettent de mettre en pause le lancement d'une nouvelle commande tant que les précédentes ne sont pas totalement ou partiellement terminées. Les plus simples empêchent le démarrage d'une commande tant que les précédentes ne sont pas terminées. D'autres permettent de démarrer une commande si et seulement si certaines commandes sont terminées. D'autres sont encore plus précises : elles empêchent le démarrage d'une nouvelle commande tant qu'une commande précédente n'a pas atteint un certain stade de son exécution. Là encore, de telles commandes sont des commandes du style "attend que le registre de statut numéro N contienne la valeur adéquate avant de poursuivre l'exécution des commandes". Les commandes en question peuvent être sur le même modèle que précédemment, à savoir des commandes qui lisent les registres de statut. Mais elles peuvent aussi se baser sur le fait que telle ou telle ressource de rendu est libre ou non. Des commandes successives se partagent souvent des données, et que de nombreuses commandes différentes peuvent s'exécuter en même temps. Or, si une commande veut modifier les données utilisées par une autre commande, il faut que l'ordre des commandes soit maintenu : la commande la plus récente ne doit pas modifier les données utilisées par une commande plus ancienne. Avec ce modèle, les sémaphores bloquent une commande tant qu'une ressource (une texture) est utilisée par une autre commande. {|class="wikitable" |- ! Commandes de synchronisation ! Fonction |- |NOP |Ne rien faire |- |WAIT_SEMAPHORE |Attendre la synchronisation avec un sémaphore |- |WAIT_MEM |Attendre que la mémoire vidéo soit disponible et inoccupée par le CPU |} ==L'arbitrage de l'accès à la carte graphique== Il n'est pas rare que plusieurs applications souhaitent accéder en même temps à la carte graphique. Imaginons que vous regardez une vidéo en ''streaming'' sur votre navigateur web, avec un programme de ''cloud computing'' de type ''Folding@Home'' qui tourne en arrière-plan, sur Windows. Le décodage de la vidéo est réalisé par la carte graphique, Windows s'occupe de l'affichage du bureau et des fenêtres, le navigateur web doit afficher tout ce qui est autour de la vidéo (la page web), le programme de ''cloud computing'' va lancer ses calculs sur la carte graphique, etc. Des situations de ce genre sont assez courantes et c'est soit le pilote qui s'en charge, soit la carte graphique elle-même. ===L'arbitrage logiciel du GPU=== L'arbitrage logiciel est la méthode la plus simple. Concrètement, c'est le système d'exploitation et/ou le pilote de la carte graphique qui gèrent l'arbitrage du GPU. Dans les deux cas, tout est fait en logiciel. Les commandes sont accumulées dans un tampon de commande, voire plusieurs, et l'OS/pilote décide quelle commande envoyer en priorité. Sur Windows, avant l'arrivée du modèle de driver dit ''Windows Display Driver Model'', de telles situations étaient gérées simplement. Les applications ajoutaient des commandes dans une file de commande unique. Les commandes étaient exécutées dans l'ordre, en mode premier entrée dans la file premier sorti/exécuté. Il n'y avait pour ainsi dire pas d'arbitrage entre les applications. Et ce n'était pas un problème car, à l'époque, les seules applications qui utilisaient le GPU étaient des jeux vidéos fonctionnant en mode plein écran. Avec le modèle de driver ''Windows Display Driver Model'' (WDDM), le GPU est maintenant arbitré, à savoir que les applications ont accès à tour de rôle au GPU, certaines ayant droit à plus de temps GPU que d'autres. Chaque programme a accès à la carte graphique durant quelques dizaines ou centaines de millisecondes, à tour de rôle. Si le programme finissait son travail en moins de temps que la durée impartie, il laissait la main au programme suivant. S’il atteignait la durée maximale allouée, il était interrompu pour laisser la place au programme suivant. Et chaque programme avait droit d'accès à la carte graphique chacun à son tour. Un tel algorithme en tourniquet est très simple, mais avait cependant quelques défauts. De nos jours, les algorithmes d'ordonnancement d'accès sont plus élaborés, bien qu'il soit difficile de trouver de la littérature ou des brevets sur le sujet. Une autre fonctionnalité de WDDM est que les applications utilisant le GPU peuvent se partager la mémoire vidéo sans se marcher dessus. Avant, toutes les applications avaient accès à toute la mémoire vidéo, bien que ce soit par l’intermédiaire de commandes spécifiques. Mais avec WDDM, chaque application dispose de sa propre portion de mémoire vidéo, à laquelle est la seule à avoir accès. Une application ne peut plus lire le contenu réel de la mémoire vidéo, et encore moins lire le contenu des autres applications. : Il s'agit d'un équivalent à l'isolation des processus pour les programmes Windows, mais appliqué à la mémoire vidéo et non la mémoire système. Et cette isolation est rendue d'autant plus simple que les GPU modernes implémentent un système de mémoire virtuelle à pagination très poussé, avec du swap en mémoire RAM système, une protection mémoire, et bien d'autres fonctionnalités. Nous en reparlerons dans les chapitres sur la mémoire vidéo. ===L'arbitrage accéléré par le GPU=== Depuis 2020, avec l'arrivée de la ''Windows 10 May 2020 update'', Windows est capable de déléguer l'arbitrage du GPU au GPU lui-même. Le GPU gère lui-même l'arbitrage, du moins en partie. En partie, car l'OS gère les priorité, à savoir quelle application a droit à plus de temps que les autres. Par contre, la gestion du ''quantum'' de temps ou les commutations de contexte (on stoppe une application pour laisser la place à une autre), est du fait du GPU lui-même. L'avantage est que cela décharge le processeur d'une tâche assez lourde en calcul, pour la déporter sur le GPU. Un autre avantage est que le GPU peut gérer plus finement les ''quantum'' de temps et la commutation de contexte. Le CPU principal gère des durées assez importantes, de l'ordre de la milliseconde. De plus, il doit communiquer avec le GPU par des mécanismes temporellement imprécis, comme des interruptions. Avec l'arbitrage accéléré par le GPU, le GPU n'a plus besoin de communiquer avec le CPU pour l'arbitrage et peut le faire plus précisément, plus immédiatement. Un gain en performance théorique est donc possible. L'arbitrage accéléré par le GPU est le fait soit du processeur de commandes, soit d'un processeur spécialisé, séparé. {{NavChapitre | book=Les cartes graphiques | prev=La hiérarchie mémoire d'un GPU | prevText=La hiérarchie mémoire d'un GPU | next=Le pipeline géométrique d'avant DirectX 10 | netxText=Le pipeline géométrique d'avant DirectX 10 }}{{autocat}} 8bw2xskv9g4ddqpbcwswdw44f5a4jsy 744056 744055 2025-06-03T17:10:57Z Mewtow 31375 /* L'arbitrage de l'accès à la carte graphique */ 744056 wikitext text/x-wiki Dans ce chapitre, nous allons parler de tous les intermédiaires qui se placent entre une application de rendu 3D et les circuits de rendu 3D proprement dit. En premier lieu, on trouve le pilote de la carte graphique, aux fonctions multiples et variées. En second lieu, nous allons parler d'un circuit de la carte graphique qui fait l'interface entre le logiciel et les circuits de rendu 3D de la carte graphique : le processeur de commandes. Ce processeur de commandes est un circuit qui sert de chef d'orchestre, qui pilote le fonctionnement global de la carte graphique. API 3D, pilote de carte graphique et processeur de commande travaillent de concert pour que l'application communique avec la carte graphique. Nous allons d'abord voir le pilote de la carte graphique, avant de voir le fonctionnement du processeur de commande. ==Le pilote de carte graphique== Le pilote de la carte graphique est un logiciel qui s'occupe de faire l'interface entre le logiciel et la carte graphique. De manière générale, les pilotes de périphérique sont des intermédiaires entre les applications/APIs et le matériel. En théorie, le système d'exploitation est censé jouer ce rôle, mais il n'est pas programmé pour être compatible avec tous les périphériques vendus sur le marché. À la place, le système d'exploitation ne gère pas directement certains périphériques, mais fournit de quoi ajouter ce qui manque. Le pilote d'un périphérique sert justement à ajouter ce qui manque : ils ajoutent au système d'exploitation de quoi reconnaître le périphérique, de quoi l'utiliser au mieux. Pour une carte graphique, il a diverses fonctions que nous allons voir ci-dessous. Avant toute chose, précisons que les systèmes d'exploitation usuels (Windows, Linux, MacOsX et autres) sont fournis avec un pilote de carte graphique générique, compatible avec la plupart des cartes graphiques existantes. Rien de magique derrière cela : toutes les cartes graphiques vendues depuis plusieurs décennies respectent des standards, comme le VGA, le VESA, et d'autres. Et le pilote de base fournit avec le système d'exploitation est justement compatible avec ces standards minimaux. Mais le pilote ne peut pas profiter des fonctionnalités qui sont au-delà de ce standard. L'accélération 3D est presque inexistante avec le pilote de base, qui ne sert qu'à faire du rendu 2D (de quoi afficher l’interface de base du système d'exploitation, comme le bureau de Windows). Et même pour du rendu 2D, la plupart des fonctionnalités de la carte graphique ne sont pas disponibles. Par exemple, certaines résolutions ne sont pas disponibles, notamment les grandes résolutions. Ou encore, les performances sont loin d'être excellentes. Si vous avez déjà utilisé un PC sans pilote de carte graphique installé, vous avez certainement remarqué qu'il était particulièrement lent. ===La gestion des interruptions=== Une fonction particulièrement importante du pilote de carte graphique est la réponse aux interruptions lancées par la carte graphique. Pour rappel, les interruptions sont une fonctionnalité qui permet à un périphérique de communiquer avec le processeur, tout en économisant le temps de calcul de ce dernier. Typiquement, lorsqu'un périphérique lance une interruption, le processeur stoppe son travail et exécute automatiquement une routine d'interruption, un petit programme qui s'occupe de gérer le périphérique, de faire ce qu'il faut, ce que l'interruption a demandé. Il y a plusieurs interruptions possibles, chacune ayant son propre numéro et sa fonction dédiée, chacune ayant sa propre routine d'interruption. Après tout, la routine qui gère un débordement de la mémoire vidéo n'est pas la même que celle qui gère un changement de fréquence du GPU ou la fin du calcul d'une image 3D. Le pilote fournit l'ensemble des routines d'interruptions nécessaires pour gérer la carte graphique. ===La compilation des ''shaders''=== Le pilote de carte graphique est aussi chargé de traduire les ''shaders'' en code machine. En soi, cette étape est assez complexe, et ressemble beaucoup à la compilation d'un programme informatique normal. Les ''shaders'' sont écrits dans un langage de programmation de haut niveau, comme le HLSL ou le GLSL, mais ce n'est pas ce code source qui est compilé par le pilote de carte graphique. À la place, les ''shaders'' sont pré-compilés vers un langage dit intermédiaire, avant d'être compilé par le pilote en code machine. Le langage intermédiaire, comme son nom l'indique, sert d'intermédiaire entre le code source écrit en HLSL/GLSL et le code machine exécuté par la carte graphique. Il ressemble à un langage assembleur, mais reste malgré tout assez générique pour ne pas être un véritable code machine. Par exemple, il y a peu de limitations quant au nombre de processeurs ou de registres. En clair, il y a deux passes de compilation : une passe de traduction du code source en langage intermédiaire, puis une passe de compilation du code intermédiaire vers le code machine. Notons que la première passe est réalisée par le programmeur des ''shaders'', non pas par l'utilisateur. Par exemple, les ''shaders'' d'un jeu vidéo sont fournis déjà pré-compilés : les fichiers du jeu ne contiennent pas le code source GLSL/HLSL, mais du code intermédiaire. L'avantage de cette méthode est que le travail du pilote est fortement simplifié. Le pilote de périphérique pourrait compiler directement du code HLSL/GLSL, mais le temps de compilation serait très long et cela aurait un impact sur les performances. Avec l'usage du langage intermédiaire, le gros du travail à été fait lors de la première passe de compilation et le pilote graphique ne fait que finir le travail. Les optimisations importantes ont déjà été réalisées lors de la première passe. Il doit bien faire la traduction, ajouter quelques optimisations de bas niveau par-ci par-là, mais rien de bien gourmand en processeur. Autant dire que cela économise plus le processeur que si on devait compiler complètement les ''shaders'' à chaque exécution. Fait amusant, il faut savoir que le pilote peut parfois remplacer les ''shaders'' d'un jeu vidéo à la volée. Les pilotes récents embarquent en effet des ''shaders'' alternatifs pour les jeux les plus vendus et/ou les plus populaires. Lorsque vous lancez un de ces jeux vidéo et que le ''shader'' originel s'exécute, le pilote le détecte automatiquement et le remplace par la version améliorée, fournie par le pilote. Évidemment, le ''shader'' alternatif du pilote est optimisé pour le matériel adéquat. Cela permet de gagner en performance, voire en qualité d'image, sans pour autant que les concepteurs du jeu n'aient quoique ce soit à faire. Enfin, certains ''shaders'' sont fournis par le pilote pour d'autres raisons. Par exemple, les cartes graphiques récentes n'ont pas de circuits fixes pour traiter la géométrie. Autant les anciennes cartes graphiques avaient des circuits de T&L qui s'en occupaient, autant tout cela doit être émulé sur les machines récentes. Sans cette émulation, les vieux jeux vidéo conçus pour exploiter le T&L et d'autres technologies du genre ne fonctionneraient plus du tout. Émuler les circuits fixes disparus sur les cartes récentes est justement le fait de ''shaders'', présents dans le pilote de carte graphique. ===Les autres fonctions=== Le pilote a aussi bien d'autres fonctions. Par exemple, il s'occupe d'initialiser la carte graphique, de fixer la résolution, d'allouer la mémoire vidéo, de gérer le curseur de souris matériel, etc. ==Les commandes graphiques/vidéo/autres : des ordres envoyés au GPU== Tous les traitements que la carte graphique doit effectuer, qu'il s'agisse de rendu 2D, de calculs 2D, du décodage matérielle d'un flux vidéo, ou de calculs généralistes, sont envoyés par le pilote de la carte graphique, sous la forme de '''commandes'''. Ces commandes demandent à la carte graphique d'effectuer une opération 2D, ou une opération 3D, ou encore le rendu d'une vidéo. Les commandes graphiques en question varient beaucoup selon la carte graphique. Les commandes sont régulièrement revues et chaque nouvelle architecture a quelques changements par rapport aux modèles plus anciens. Des commandes peuvent apparaître, d'autres disparaître, d'autre voient leur fonctionnement légèrement altéré, etc. Mais dans les grandes lignes, on peut classer ces commandes en quelques grands types. Les commandes les plus importantes s'occupent de l'affichage 3D : afficher une image à partir de paquets de sommets, préparer le passage d'une image à une autre, changer la résolution, etc. Plus rare, d'autres commandes servent à faire du rendu 2D : afficher un polygone, tracer une ligne, coloriser une surface, etc. Sur les cartes graphiques qui peuvent accélérer le rendu des vidéos, il existe des commandes spécialisées pour l’accélération des vidéos. Pour donner quelques exemples, prenons les commandes 2D de la carte graphique AMD Radeon X1800. {|class="wikitable" |- ! Commandes 2D ! Fonction |- |PAINT |Peindre un rectangle d'une certaine couleur |- |PAINT_MULTI |Peindre des rectangles (pas les mêmes paramètres que PAINT) |- |BITBLT |Copie d'un bloc de mémoire dans un autre |- |BITBLT_MULTI |Plusieurs copies de blocs de mémoire dans d'autres |- |TRANS_BITBLT |Copie de blocs de mémoire avec un masque |- |NEXTCHAR |Afficher un caractère avec une certaine couleur |- |HOSTDATA_BLT |Écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo |- |POLYLINE |Afficher des lignes reliées entre elles |- |POLYSCANLINES |Afficher des lignes |- |PLY_NEXTSCAN |Afficher plusieurs lignes simples |- |SET_SCISSORS |Utiliser des coupes (ciseaux) |- |LOAD_PALETTE |Charger la palette pour affichage 2D |} ===Le tampon de commandes=== L'envoi des commandes à la carte graphique ne se fait pas directement. La carte graphique n'est pas toujours libre pour accepter une nouvelle commande, soit parce qu'elle est occupée par une commande précédente, soit parce qu'elle fait autre chose. Il faut alors faire patienter les données tant que la carte graphique est occupée. Les pilotes de la carte graphique vont les mettre en attente dans le '''tampon de commandes'''. Le tampon de commandes est ce qu'on appelle une file, une zone de mémoire dans laquelle on stocke des données dans l'ordre d'ajout. Si le tampon de commandes est plein, le driver n'accepte plus de demandes en provenance des applications. Un tampon de commandes plein est généralement mauvais signe : cela signifie que la carte graphique est trop lente pour traiter les demandes qui lui sont faites. Par contre, il arrive que le tampon de commandes soit vide : dans ce cas, c'est simplement que la carte graphique est trop rapide comparé au processeur, qui n'arrive alors pas à donner assez de commandes à la carte graphique pour l'occuper suffisamment. Le tampon de commande est soit une mémoire FIFO séparée, soit une portion de la mémoire vidéo. Le NV1, la toute première carte graphique NVIDIA, utilisait une mémoire FIFO intégrée à la carte graphique, séparée des autres circuits. Le processeur envoyait les commandes par rafale au GPU, à savoir qu'il envoyait plusieurs dizaines ou centaines de commandes à la suite, avant de passer à autre chose. Le GPU traitait les commandes une par une, à un rythme bien plus lent. Le processeur pouvait consulter la FIFO pour savoir s'il restait des entrées libres et combien. Le processeur savait ainsi combien d'écritures il pouvait envoyer en une fois au GPU. : Le fonctionnement de la FIFO du NV1 est décrit dans le brevet ''US5805930A : System for FIFO informing the availability of stages to store commands which include data and virtual address sent directly from application programs''. ===Le processeur de commandes=== Le '''processeur de commande''' est un circuit qui gère les commandes envoyées par le processeur. Il lit la commande la plus ancienne dans le tampon de commande, l’interprète, l’exécute, puis passe à la suivante. Le processeur de commande est un circuit assez compliqué. Sur les cartes graphiques anciennes, c'était un circuit séquentiel complexe, fabriqué à la main et était la partie la plus complexe du processeur graphique. Sur les cartes graphiques modernes, c'est un véritable microcontrôleur, avec un processeur, de la mémoire RAM, etc. Lors de l'exécution d'une commande, le processeur de commande pilote les circuits de la carte graphique. Précisément, il répartit le travail entre les différents circuits de la carte graphique et assure que l'ordre du pipeline est respecté. Pour donner un exemple, prenons la première carte graphique de NVIDIA, le NV1. Il s'agissait d'une carte multimédia qui incorporait non seulement une carte 2D/3D, mais aussi une carte son un contrôleur de disque et de quoi communiquer avec des manettes. De plus, il incorporait un contrôleur DMA pour échanger des données entre RAM système et les autres circuits. Et à tout cela, il fallait ajouter la FIFO de commandes et le processeur de commande. L'ensemble était relié par un bus interne à la carte graphique. Le processeur de commande servait de gestionnaire principal. Il envoyait des ordres internes aux circuits de rendu 3D, à sa carte son, au contrôleur DMA. Par exemple, lorsque le processeur voulait copier des données en mémoire vidéo, il envoyait une commande de copie, qui était stockée dans le tampon de commande, puis était exécutée par le processeur de commande. Le processeur de commande envoyait alors les ordres adéquats au contrôleur DMA, qui faisait la copie des données. Lors d'un rendu 3D, une commande de rendu 3D est envoyée au NV1, le processeur de commande la traite et l'envoi dans les circuits de rendu 3D. [[File:Microarchitecture du GPU NV1 de NVIDIA.png|centre|vignette|upright=2|Microarchitecture du GPU NV1 de NVIDIA]] Les GPU modernes sont plus complexes, ce qui fait que le processeur de commande a plus de travail. Parmis les nombreuses tâches qui lui sont confiées, il répartit les ''shaders'' sur les processeurs de ''shaders'', en faisant en sorte qu'ils soient utilisés le plus possible. Dans le cas le plus simple, les unités sont alimentées en vertex/pixels les unes après les autres (principe du round-robin), mais des stratégies plus optimisées sont la règle de nos jours. Cela est très important sur les cartes graphiques : répartir plusieurs commandes sur plusieurs processeurs est une tâche difficile. Un chapitre entier sera d'ailleurs dédié à ce sujet. Il envoie aussi certaines commandes aux circuits fixes, comme l’''input assembler''. Là encore, il faut en sorte que les circuits fixes soient utilisés le mieux possible. Sa tâche est compliquée par le fait que les GPU récents ont plusieurs unités de traitement des sommets et des pixels, plusieurs ROP, plusieurs unités de textures, etc. Et c'est en partie le travail du processeur de commande que de répartir les calculs sur ces différentes unités. C'est là un problème assez compliqué pour le processeur de commande et ce pour tout un tas de raisons que nous ne ferons que survoler. Les contraintes d'ordonnancement de l'API et les règles de celle-ci sont une partie de la réponse. Mais d'autres raisons sont intrinsèques au rendu 3D ou à la conception des circuits. [[File:Architecture de base d'une carte 3D - 1.png|centre|vignette|upright=2.5|Architecture de base d'une carte 3D - 1]] Le processeur de commande n'a pas qu'un rôle de répartiteur. Il connait à tout instant l'état de la carte graphique, l'état de chaque sous-circuit. L'implémentation est variable suivant le GPU. La plus simple ajoute un registre d'état à chaque circuit, qui, est consultable en temps réel par le processeur de commande. Mais il est possible d'utiliser un système d'interruptions interne à la puce, ou circuits préviennent le processeur de commande quand ils ont terminé leur travail. Grâce à cela, le processeur de commandes garde en mémoire l'état de traitement de chaque commande : est-ce qu'elle est en train de s’exécuter sur le processeur graphique, est-ce qu'elle est mise en pause, est-ce qu'elle attend une donnée en provenance de la mémoire, est-ce qu'elle est terminée, etc. Pour résumer, le processeur de commande lit une commande, répartit le travail sur les différents circuits du GPU, et vérifie en permanence leur état pour déterminer si la commande est en pause, terminée, en cours d'exécution, etc. ==Le fonctionnement du processeur de commandes== Intuitivement, on se dit que le processeur de commande procède une commande à la fois. Mais les GPU modernes sont plus intelligents et peuvent exécuter plusieurs commandes en même temps, dans des circuits séparés. De nombreuses optimisations de ce type sont utilisées pour gagner en performance. Voyons comment un processeur de commande moderne fonctionne. ===L'ordonnancement et la gestion des ressources=== Le processeur de commande doit souvent mettre en pause certains circuits du pipeline, ainsi que les circuits précédents. Par exemple, si tous les processeurs de ''vertex shader'' sont occupés, l’''input assembler'' ne peut pas charger le paquet suivant car il n'y a aucun processeur de libre pour l’accueillir. Dans ce cas, l'étape d’''input assembly'' est mise en pause en attendant qu'un processeur de ''shader'' soit libre. La même chose a lieu pour l'étape de rastérisation : si aucun processeur de ''shader'' n'est libre, elle est mise en pause. Sauf que pour la rastérisation, cela a des conséquences sur les circuits précédents la rastérisation. Si un processeur de ''shader'' veut envoyer quelque chose au rastériseur alors qu'il est en pause, il devra lui aussi attendre que le rastériseur soit libre. On a la même chose quand les ROP sont occupés : les ''pixel shader'' ou l'unité de texture doivent parfois être mis en pause, ce qui peut entrainer la mise en pause des étapes précédentes, etc. En clair : plus un étape est situé vers la fin du pipeline graphique, plus sa mise en pause a de chances de se répercuter sur les étapes précédentes et de les mettre en pause aussi. Le processeur de commande doit gérer ces situations. ===Le pipelining des commandes=== Dans les cartes graphiques les plus rudimentaires, le processeur de commande exécute les commandes dans l'ordre. Il exécute une commande çà la fois et attend qu'une commande soit terminé pour en lancer une autre. Plusieurs commandes sont accumulées dans le tampon de commande, le processeur de commande les traite de la plus ancienne vers la plus récente. Du moins, les anciennes cartes graphiques faisaient comme cela, les cartes graphiques modernes sont un peu plus complexes. Elles n'attendent pas qu'une commande soit totalement terminée avant d'en lancer une nouvelle. Les processeurs de commande actuels sont capables d’exécuter plusieurs commandes en même temps. L'intérêt est un gain en performance assez important. Pour ceux qui ont déjà eu un cours d'architecture des ordinateurs avancé, lancer plusieurs commandes en même temps permet une forme de pipeline, dont les gains sont substantiels. Par exemple, imaginez qu'une commande de rendu 3D soit bien avancée et n'utilise que les processeurs de ''shaders'' et les ROP, mais laisse les unités géométriques libres. Il est alors possible de démarrer la commande suivante en avance, afin qu'elle remplisse les unités géométriques inutilisées. On a alors deux commandes en cours de traitement : une commande qui utilise la fin du pipeline uniquement, une autre qui utilise seulement le début du pipeline graphique. Le processeur de commande gère donc plusieurs commandes simultanées, à savoir plusieurs commandes qui en sont à des étapes différentes du pipeline. On peut avoir une commande qui est en cours dans l'étage de gestion de la géométrie, une autre dans le rastériseur, et une autre dans les unités de traitement des pixels. Le fait que les étapes du pipeline graphique sont à effectuer dans un ordre bien précis permet ce genre de chose assez facilement. Une autre possibilité est de faire des rendus en parallèle. Par exemple, imaginez qu'on ait des circuits séparés pour le rendu 2D et 3D. Prenons l'exemple où le calcul d'une image finale demande de faire un rendu 3D suivi d'un rendu 2D, par exemple un jeu vidéo en 3D qui a un HUD dessiné en 2D. Dans ce cas, on peut démarrer le calcul de l'image suivante dans le pipeline 3D pendant que la précédente est dans les circuits 2D, au lieu de laisser inutilisé le pipeline 3D pendant le rendu 2D. Mais c'est là un défi compliqué à relever pour le processeur de commande, qui donne lieu à son lot de problèmes. Le problème principal est le partage de ressources entre commandes. Par exemple, on peut prendre le cas où une commande n'utilise pas beaucoup les processeurs de ''shaders''. On pourrait imaginer lancer une seconde commande en parallèle, afin que la seconde commande utiliser les processeurs de ''shaders'' inutilisés. Mais cela n'est possible que si les circuits fixes sont capables d'accepter une seconde commande. Si la première commande sature les circuits fixe, le lancement de la seconde commande sera empêché. Mais si ce n'est pas le cas, les deux commandes pourront être lancées en même temps. Pareil pour le débit mémoire, qui doit alors être partagé entre deux commandes simultanées, ce qui est à prendre en compte. ===La synchronisation de l’exécution des commandes avec le processeur=== Il arrive que le processeur doive savoir où en est le traitement des commandes, ce qui est très utile pour la gestion de la mémoire vidéo. Un premier exemple : comment éviter de saturer une carte graphique de commande, alors qu'on ne sait pas si elles traite les commandes rapidement ou non ? L'idéal est de regarder où en est la carte graphique dans l'exécution des commandes. Si elle n'en est qu'au début du tampon de commande et que celui-ci est bien remplit, alors il vaut mieux lever le pied et ne pas envoyer de nouvelles commandes. A l'inverse, si le tampon de commande est presque vide, envoyer des commandes est la meilleure idée possible. Un autre exemple un peu moins parlant est celui de la gestion de la mémoire vidéo. Rappelons qu'elle est réalisée par le pilote de la carte graphique, sur le processeur principal, qui décide d'allouer et de libérer de la mémoire vidéo. Pour donner un exemple d'utilisation, imaginez que le pilote de la carte graphique doive libérer de la mémoire pour pouvoir ajouter une nouvelle commande. Comment éviter d'enlever une texture tant que les commandes qui l'utilisent ne sont pas terminées ? Ce problème ne se limite pas aux textures, mais vaut pour tout ce qui est placé en mémoire vidéo. Il faut donc que la carte graphique trouve un moyen de prévenir le processeur que le traitement de telle commande est terminée, que telle commande en est rendue à tel ou tel point, etc. Pour cela, on a globalement deux grandes solutions. La première est celle des interruptions, abordées dans les chapitres précédents. Mais elles sont assez couteuses et ne sont utilisées que pour des évènements vraiment importants, critiques, qui demandent une réaction rapide du processeur. L'autre solution est celle du ''pooling'', où le processeur monitore la carte graphique à intervalles réguliers. Deux solutions bien connues de ceux qui ont déjà lu un cours d'architecture des ordinateurs digne de ce nom, rien de bien neuf : la carte graphique communique avec le processeur comme tout périphérique. Pour faciliter l'implémentation du ''pooling'', la carte graphique contient des registres de statut, dans le processeur de commande, qui mémorisent tout ou partie de l'état de la carte graphique. Si un problème survient, certains bits du registre de statut seront mis à 1 pour indiquer que telle erreur bien précise a eu lieu. Il existe aussi un registre de statut qui mémorise le numéro de la commande en cours, ou de la dernière commande terminée, ce qui permet de savoir où en est la carte graphique dans l'exécution des commandes. Et certaines registres de statut sont dédiés à la gestion des commandes. Ils sont totalement programmable, la carte graphique peut écrire dedans sans problème. Les cartes graphiques récentes incorporent des commandes pour modifier ces registres de statut au besoin. Elles sont appelées des '''commandes de synchronisation''' : les barrières (''fences''). Elles permettent d'écrire une valeur dans un registre de statut quand telle ou telle condition est remplie. Par exemple, si jamais une commande est terminée, on peut écrire la valeur 1 dans tel ou tel registre. La condition en question peut être assez complexe et se résumer à quelque chose du genre : "si jamais toutes les ''shaders'' ont fini de traiter tel ensemble de textures, alors écrit la valeur 1024 dans le registre de statut numéro 9". ===La synchronisation de l’exécution des commandes intra-GPU=== Lancer plusieurs commandes en parallèle dans le pipeline permet de gagner en performance.Mais cela a un gros défaut : il n'est pas garantit que les commandes se terminent dans l'ordre. Si on démarre une seconde commande après la première, il arrive que la seconde finisse avant. Pire : il n'est pas garantit qu'elles s'exécutent dans l'ordre. Dans la plupart des cas, cela ne pose pas de problèmes. Mais dans d'autres, cela donne des résultats erronés. Pour donner un exemple, utilisons les commandes de rendu 2D vues plus haut, histoire de simplifier le tout. Imaginez que vous codez un jeu vidéo et que le rendu se fait en 2D, partons sur un jeu de type FPS. Vous avez une série de commandes pour calculer l'image à rendre à l'écran, suivie par une série de commandes finales pour dessiner le HUB. Pour dessiner le HUD, vous utilisez des commandes HOSTDATA_BLT, dont le but est d'écrire une chaîne de caractères à l'écran ou copier une série d'image bitmap dans la mémoire vidéo. Et bien ces commandes HOSTDATA_BLT doivent démarrer une fois que le rendu de l'image est complétement terminé. Imaginez que vous dessiniez le HUD sur une portion de l'image pas encore terminée et que celui-ci est effacé par des écritures ultérieures ! Pour éviter tout problème, les GPU incorporent des commandes de synchronisation intra-GPU, destinées au processeur de commande, aussis appelées des '''commandes de sémaphore'''. Elles permettent de mettre en pause le lancement d'une nouvelle commande tant que les précédentes ne sont pas totalement ou partiellement terminées. Les plus simples empêchent le démarrage d'une commande tant que les précédentes ne sont pas terminées. D'autres permettent de démarrer une commande si et seulement si certaines commandes sont terminées. D'autres sont encore plus précises : elles empêchent le démarrage d'une nouvelle commande tant qu'une commande précédente n'a pas atteint un certain stade de son exécution. Là encore, de telles commandes sont des commandes du style "attend que le registre de statut numéro N contienne la valeur adéquate avant de poursuivre l'exécution des commandes". Les commandes en question peuvent être sur le même modèle que précédemment, à savoir des commandes qui lisent les registres de statut. Mais elles peuvent aussi se baser sur le fait que telle ou telle ressource de rendu est libre ou non. Des commandes successives se partagent souvent des données, et que de nombreuses commandes différentes peuvent s'exécuter en même temps. Or, si une commande veut modifier les données utilisées par une autre commande, il faut que l'ordre des commandes soit maintenu : la commande la plus récente ne doit pas modifier les données utilisées par une commande plus ancienne. Avec ce modèle, les sémaphores bloquent une commande tant qu'une ressource (une texture) est utilisée par une autre commande. {|class="wikitable" |- ! Commandes de synchronisation ! Fonction |- |NOP |Ne rien faire |- |WAIT_SEMAPHORE |Attendre la synchronisation avec un sémaphore |- |WAIT_MEM |Attendre que la mémoire vidéo soit disponible et inoccupée par le CPU |} ==L'arbitrage de l'accès à la carte graphique== Il n'est pas rare que plusieurs applications souhaitent accéder en même temps à la carte graphique. Imaginons que vous regardez une vidéo en ''streaming'' sur votre navigateur web, avec un programme de ''cloud computing'' de type ''Folding@Home'' qui tourne en arrière-plan, sur Windows. Le décodage de la vidéo est réalisé par la carte graphique, Windows s'occupe de l'affichage du bureau et des fenêtres, le navigateur web doit afficher tout ce qui est autour de la vidéo (la page web), le programme de ''cloud computing'' va lancer ses calculs sur la carte graphique, etc. Des situations de ce genre sont assez courantes et c'est soit le pilote qui s'en charge, soit la carte graphique elle-même. ===L'arbitrage logiciel du GPU=== L'arbitrage logiciel est la méthode la plus simple. Concrètement, c'est le système d'exploitation et/ou le pilote de la carte graphique qui gèrent l'arbitrage du GPU. Dans les deux cas, tout est fait en logiciel. Les commandes sont accumulées dans un tampon de commande, voire plusieurs, et l'OS/pilote décide quelle commande envoyer en priorité. Sur Windows, avant l'arrivée du modèle de driver dit ''Windows Display Driver Model'', de telles situations étaient gérées simplement. Les applications ajoutaient des commandes dans une file de commande unique. Les commandes étaient exécutées dans l'ordre, en mode premier entrée dans la file premier sorti/exécuté. Il n'y avait pour ainsi dire pas d'arbitrage entre les applications. Et ce n'était pas un problème car, à l'époque, les seules applications qui utilisaient le GPU étaient des jeux vidéos fonctionnant en mode plein écran. Avec le modèle de driver ''Windows Display Driver Model'' (WDDM), le GPU est maintenant arbitré, à savoir que les applications ont accès à tour de rôle au GPU, certaines ayant droit à plus de temps GPU que d'autres. Chaque programme a accès à la carte graphique durant quelques dizaines ou centaines de millisecondes, à tour de rôle. Si le programme finissait son travail en moins de temps que la durée impartie, il laissait la main au programme suivant. S’il atteignait la durée maximale allouée, il était interrompu pour laisser la place au programme suivant. Et chaque programme avait droit d'accès à la carte graphique chacun à son tour. Un tel algorithme en tourniquet est très simple, mais avait cependant quelques défauts. De nos jours, les algorithmes d'ordonnancement d'accès sont plus élaborés, bien qu'il soit difficile de trouver de la littérature ou des brevets sur le sujet. Une autre fonctionnalité de WDDM est que les applications utilisant le GPU peuvent se partager la mémoire vidéo sans se marcher dessus. Avant, toutes les applications avaient accès à toute la mémoire vidéo, bien que ce soit par l’intermédiaire de commandes spécifiques. Mais avec WDDM, chaque application dispose de sa propre portion de mémoire vidéo, à laquelle est la seule à avoir accès. Une application ne peut plus lire le contenu réel de la mémoire vidéo, et encore moins lire le contenu des autres applications. : Il s'agit d'un équivalent à l'isolation des processus pour les programmes Windows, mais appliqué à la mémoire vidéo et non la mémoire système. Et cette isolation est rendue d'autant plus simple que les GPU modernes implémentent un système de mémoire virtuelle à pagination très poussé, avec du swap en mémoire RAM système, une protection mémoire, et bien d'autres fonctionnalités. Nous en reparlerons dans les chapitres sur la mémoire vidéo. ===L'arbitrage accéléré par le GPU=== Depuis 2020, avec l'arrivée de la ''Windows 10 May 2020 update'', Windows est capable de déléguer l'arbitrage du GPU au GPU lui-même. Le GPU gère lui-même l'arbitrage, du moins en partie. En partie, car l'OS gère les priorité, à savoir quelle application a droit à plus de temps que les autres. Par contre, la gestion du ''quantum'' de temps ou les commutations de contexte (on stoppe une application pour laisser la place à une autre), est du fait du GPU lui-même. L'avantage est que cela décharge le processeur d'une tâche assez lourde en calcul, pour la déporter sur le GPU. Un autre avantage est que le GPU peut gérer plus finement les ''quantum'' de temps et la commutation de contexte. Le CPU principal gère des durées assez importantes, de l'ordre de la milliseconde. De plus, il doit communiquer avec le GPU par des mécanismes temporellement imprécis, comme des interruptions. Avec l'arbitrage accéléré par le GPU, le GPU n'a plus besoin de communiquer avec le CPU pour l'arbitrage et peut le faire plus précisément, plus immédiatement. Un gain en performance théorique est donc possible. L'arbitrage accéléré par le GPU est le fait soit du processeur de commandes, soit d'un processeur spécialisé, séparé. ===L'exemple du NV1=== La carte NVIDIA NV1 avait diverses optimisations pour supporter plusieurs applications à la fois. L'une d'entre elle est le support de plusieurs tampons de commande. La carte graphique gérait en tout 128 tampons de commandes, chacun contenant 32 commandes consécutives. Le tout permettait à 128 logiciels différents d'avoir chacun son propre tampon de commande. L'implémentation du NV1 utilisait en réalité une FIFO unique, dans une mémoire RAM unique, qui était segmentée en 128 sous-FIFOs. Mais il est techniquement possible d'utiliser plusieurs FIFOs séparées connectées à un multiplexeur en sortie et un démultiplexeur en entrée. Le NV1 utilisait des adresses de 23 bits, ce qui fait 8 méga-octets de RAM. Les 8 méga-octets étaient découpées en 128 blocs de mémoire consécutifs, chacun étant associé à une application et faisant 64 kilo-octets. Les adresses de 23 bits étaient donc découpées en une portion de 7 bit pour identifier le logiciel qui envoie la commande, et une portion de 16 bits pour identifier la position des données dans le bloc de RAM. Une entrée dans la FIFO du NV1 faisait 48 bits, contenant une donnée de 32 bits et les 16 bits de l'adresse. {{NavChapitre | book=Les cartes graphiques | prev=La hiérarchie mémoire d'un GPU | prevText=La hiérarchie mémoire d'un GPU | next=Le pipeline géométrique d'avant DirectX 10 | netxText=Le pipeline géométrique d'avant DirectX 10 }}{{autocat}} hgza7ynnnsy1rde0qmd3o85i3p9zfw3 Neurosciences/Le métabolisme cérébral 0 70529 744030 743943 2025-06-03T13:18:31Z Mewtow 31375 /* Le fer */ 744030 wikitext text/x-wiki Le cerveau est un organe qui consomme beaucoup d'énergie : près de 20% de la consommation énergétique du corps est de son fait, alors qu'il ne représente que 2 % de sa masse. Il faut dire que faire fonctionner les neurones demande de l'énergie, d'autant plus que ceux-ci sont actifs. Générer des potentiels d'action demande une certaine énergie, produire des neurotransmetteurs aussi, sans compter l'action des pompes et canaux ioniques de la membrane. Le cerveau utilise la majeure partie de son énergie pour faire fonctionner ses pompes et canaux ioniques, principalement les pompes. Celles-ci vont, pour rappel, pomper certains ions en dehors de la cellule, contre leur gradient de concentration. Cela demande naturellement de l'énergie, pour contrer l'effet de la concentration plus importante dans le milieu extérieur. Chaque pompe va ainsi utiliser une ou plusieurs molécules d'ATP pour faire sortir un ion. Cela ne parait n'être pas grand-chose, mais cela compte pour 50% du métabolisme de base du cerveau ! ==Le métabolisme énergétique du cerveau== Le cerveau est un organe qui consomme beaucoup d'énergie. On estime qu'il est responsable, à lui seul d'environ 25 % de la consommation énergétique du corps. La valeur exacte varie beaucoup selon beaucoup de paramètres. Par exemple, on sait que la consommation énergétique du cerveau dépend de sa température. On estime qu'une réduction de 1°C réduit la consommation énergétique cérébrale de 6 à 5 %. Cela a d'ailleurs des applications thérapeutiques, dans les cas d'AVC, d'arrêt cardiaque ou d'autres situations similaires où le cerveau manque d'oxygène. Dans ces situations, on refroidit le cerveau pour ralentir son métabolisme. Cela réduit l'apparition de lésions cérébrales, causées par un métabolisme anormal lié au manque d'oxygène. Quoi qu’il en soit, le métabolisme cérébral dépend de bien d'autres paramètres, et il serait inutile d'en faire une liste exhaustive. ===Les sources d'énergie du cerveau=== Les neurones sont comme toutes les cellules : ils consomment des nutriments pour fabriquer de l'énergie, qu'ils emmagasinent sous forme d'ATP dans la cellule. En temps normal, ces nutriments sont des sucres, mais le cerveau peut aussi bruler des dérivés de la désagrégation des graisses ou des protéines si le sucre vient à manquer. Cette combustion des nutriments, implique toute une série de réactions chimiques très compliquées. Ceux qui s'y connaissent en biologie devraient connaitre les notions de fermentation ou de respiration cellulaires, voire le cycle de Krebs. Nous n'allons pas revenir sur ces notions fondamentales de la biologie, mais nous allons remarquer que la combustion des nutriments peut se faire soit en présence d'oxygène, soit sans. Quand les nutriments sont brulés en présence d'oxygène, les réactions chimiques sont des réactions dites de ''respiration cellulaire''. Dans le cas contraire, ce sont des réactions de ''fermentation''. Les neurones sont capables à la fois de respiration cellulaire que de fermentation. Vu que les neurones consomment beaucoup d'énergie, le processus principal est la respiration, ce qui fait que le cerveau a besoin d'oxygène pour fonctionner. Pour résumer, le cerveau a principalement besoin de sucres et d'oxygène, mais il peut consommer des graisses en cas de manque. ====Le glucose et l'oxygène==== En temps normal, le cerveau consomme du sucre par respiration cellulaire, la fermentation étant minimale. Le sucre le plus utilisé par le cerveau est le glucose, du moins en temps normal, mais des molécules similaires au glucose peuvent être utilisées en lieu de place de celui-ci : c'est le cas pour le pyruvate, le mannose et le lactate. Les expériences qui ont montré cela sont assez simples à expliquer. Elles se bornent à comparer la composition du sang entre les artères qui alimentent le cerveau et les veines qui en sortent. Ces mesures montrent alors que le sang est identique entre l'entrée et la sortie, si ce n'est que sa teneur en glucose et en oxygène est plus basse dans les veines que dans les artères, sans compter que sa teneur en dioxyde de carbone augmente. Les mesures précédentes traduisent le fait que le cerveau utilise ce qu'on appelle la respiration cellulaire aérobie pour produire son énergie : il consomme de l'oxygène et du glucose et produit de l'énergie et du dioxyde de carbone. Cependant, ces mesures montrent que tout l'oxygène n'est pas converti de cette manière. Si tout le glucose était utilisé ainsi, 100 grammes de cerveau devraient consommer 26 millimoles de glucose par minutes. Or, la valeur mesurée est de 31 millimoles par minutes. Il y a donc une petite différence de 4,4 millimoles par minutes, qui est utilisée autrement. Dans le détail, on verra que ce glucose est transformé et stocké dans les astrocytes et les neurones, il est mis en réserve. ====Les lipides et acides gras==== Outre le glucose, les protéines et des dérivés de la désagrégation des graisses peuvent être consommés par le cerveau pour produire de l'énergie. Encore une fois, cette production s'effectue par le biais de la respiration cellulaire aérobie et le cerveau n'est pas le seul à pouvoir faire cela (tous les tissus peuvent brûler des protéines ou des lipides dans le cycle de Krebs). Par contre, le métabolisme cérébral des graisses est différent du métabolisme des autres tissus. En effet, le cerveau ne peut pas bruler les acides gras pour produire de l'énergie, contrairement aux autres tissus. La raison est que les acides gras ne peuvent pas traverser la barrière hémato-encéphalique. En revanche, le cerveau peut bruler les '''corps cétoniques''', des dérivés de la désagrégation des graisses qui peuvent traverser la barrière hémato-encéphalique et alimenter le cerveau en énergie. Parmi les corps cétoniques, deux alimentent le cerveau et le cœur en énergie : l'acétylacétate et le β-D-hydroxybutyrate. Cependant, la production de corps cétoniques n'arrive que dans des conditions très particulières. Il faut que le corps manque de sucres (glucose) au point que le foie en est réduit à bruler des graisses. Le métabolisme des lipides et acides gras donne alors naissance à des corps cétoniques, par un processus dit de cétogenèse. Par exemple, cela arrive en cas de diabète ou de jeûne : l'alimentation en sucre étant alors inadéquate, le cerveau doit utiliser d'autres voies que la consommation de glucose. Un autre exemple est celui des nouveaux-nés allaités, dont l'alimentation est très riche en lipides et en acides gras. Dans tous les exemples précédents, les réactions chimiques utilisées pour produire de l'énergie à partir de lipides ou de protéines sont les mêmes : les voies métaboliques des nouveaux-nés sont réactivées en cas de jeûne ou de diabète. ===L'hypoxie cérébrale=== Quand l'oxygène vient à manquer, on fait face à une situation d'''hypoxie cérébrale''. Une telle situation arrive notamment lors d'un AVC ou d'un arrêt cardiaque, quand le cerveau n'est plus irrigué par le sang. L'oxygène n'est plus apporté au cerveau, qui réagit pour faire face à la pénurie. Le cerveau a beau avoir une grosse consommation énergétique, il a des réserves très faibles en nutriments. Ce qui fait que l'hypoxie commence à causer des problèmes en quelques minutes, voire quelques secondes. Il se produit alors une cascade de réactions chimiques, qui endommage les neurones et entraine leur mort. Cette cascade se produit en deux étapes : une première étape liée à la carence en oxygène, une autre quand le sang revient dans le cerveau et où l'oxygène revient. Ces deux étapes laissent des dommages cérébraux massifs, qu'il s'agisse du manque d'oxygène ou des dommages de la seconde étape, appelés dommages de re-perfusion. ====La cascade ischémique==== La première étape est une série de réactions chimiques qui s'appelle la '''cascade ischémique''', qui fait suite à un manque d'oxygène. Pour faire simple, le cerveau réagit en passant à des réactions de fermentation pour consommer les sucres. Mais l'usage de la fermentation pose divers problèmes. En premier lieu, elle ne fournit pas assez d'énergie pour les pompes et canaux ioniques. L'équilibre ionique du cerveau est alors perturbé, avec une accumulation d'ions dans ou en dehors des neurones. En second lieu, la fermentation produit des déchets qui sont toxiques pour les neurones. Or, ceux-ci peuvent entrainer des dommages s'ils ne sont pas évacués du cerveau. La majorité des dommages provient, de manière indirecte, du déséquilibre ionique, qui intoxique les neurones de l'intérieur. Le dysfonctionnement principal est l'arrêt de certaines pompes ioniques, notamment des pompes au potassium, au calcium et au sodium. Cela mène à une ''accumulation de sodium et de calcium dans les neurones''. En premier lieu, le calcium va s'accumuler dans les neurones. Or, le calcium est toxique pour les cellules, ce qui peut forcer l'apoptose des cellules (leur suicide). De plus, ce calcium favorise la libération des neurotransmetteurs, dont le glutamate. Or, le glutamate fait rentrer encore plus de calcium via les récepteurs NMDA et AMPA. Rappelons que c'est pour cela que le glutamate a des propriétés excitotxiques, à savoir qu'il peut exciter les neurones à l'excès, jusqu’à en devenir toxique. Les effets excitotoxiques du glutamate proviennent de là, et ceux-ci s'expriment avec force lors de l'ischémie, bien plus que dans des conditions normales. Limiter les dégâts de la cascade ischémique demande d'agir vite afin de stopper celle-ci avant qu'un trop grand nombre de neurones soient morts. Une autre possibilité serait d'atténuer l'excitotoxicité du glutamate, en utilisant des antagonistes des récepteurs NMDA et AMPA. Mais cette stratégie n'a pas donné de bons résultats dans les études réalisées à l'heure actuelle (mi-2017). Un autre défaut est que le sodium s'accumule dans les neurones, ce qui en perturbe l'équilibre hydroélectrique (pour les connaisseurs, l'équilibre osmotique). Les raisons à cela sont multiples. Déjà, les pompes ioniques calcium-sodium vont tenter d'évacuer le calcium dans les neurones, mais cela fait rentrer du sodium. De plus, certaines pompes ioniques potassium-sodium vont dysfonctionner, en raison du manque d'ATP, ce qui réduit l'élimination de sodium intraneuronale. Tout cela fait que les neurones tendent à accumuler beaucoup d'ions sodium dans leur cytoplasme. Sans rentrer dans les détails, cela a une conséquence : de l'eau s'accumule dans les neurones, qui gonflent. Il se produit alors un œdème cérébral, qui fait gonfler le cerveau et le compresse sur le crâne. Cette pression entraine des lésions assez graves, si elle est assez intense. Mais nous en reparlerons dans le chapitre sur la pression intracrânienne, qui parlera des œdèmes cérébraux en général. Enfin, la fermentation produit des déchets métaboliques, les deux principaux étant : le lactate et des ions hydrogène. Les deux sont toxiques pour les neurones, quand ils sont en excès, ce qui est le cas lors d'une hypoxie cérébrale. L'accumulation de lactate est moins problématique que l'accumulation des ions hydrogène. Cette dernière fait que le pH diminue, entraînant une acidose métabolique, perturbant les réactions chimiques cérébrales. [[File:Cascade ischémique 02.svg|centre|vignette|upright=3.0|Description simplifiée de la cascade ischémique.]] ==Les interactions neurones-astrocytes== Les molécules dissoutes dans le sang doivent traverser la barrière hémato-encéphalique pour arriver aux neurones. Leur passage à travers celle-ci fait intervenir des molécules appelées ''transporteurs''. Pour rappel, ce sont des "récepteurs" qui permettent à une molécule de passer d'un côté à l'autre d'une membrane cellulaire. Ici, la molécule en question est une molécule sanguine et les membranes sont celles de la barrière hémato-encéphalique. Les transporteurs sont spécialisés, dans le sens où ils ne laissent passer que quelques molécules bien précises et pas les autres. Par exemple, les transporteurs pour le glucose permettent uniquement le passage du glucose, mais pas des autres molécules. Quoi qu’il en soit, les molécules sanguines traversent la barrière hémato-encéphalique, du moins pour celles qui ont un transporteur adapté, mais elles n'arrivent pas directement dans les neurones ou dans le fluide entre les neurones. Rappelons que la barrière hémato-encéphalique est composée de deux couches : un vaisseau sanguin, entouré par des astrocytes. Les transporteurs localisés à la surface des vaisseaux sanguins cérébraux permettent aux molécules de passer dans les astrocytes, qui se chargent ensuite de les redistribuer aux neurones par divers mécanismes. Pour résumer, les molécules traversent la barrière hémato-encéphalique, se retrouvent dans les astrocytes, puis sont transférées aux neurones à la demande. Autant dire que les interactions entre neurones et astrocytes sont très importantes pour le métabolisme cérébral. Rappelons que les astrocytes n'ont pas beaucoup de transporteurs différents, les principaux étant les transporteurs pour le glucose. L'absence de transporteurs pour de nombreuses molécules/ions empêche la majorité des ions et molécules de traverser les astrocytes et d'atteindre le cerveau. C'est pour cela que la barrière hémato-encéphalique est aussi sélective. ===Le métabolisme du glucose=== Les astrocytes ont un rôle très important dans le métabolisme énergétique des neurones. Pour simplifier, les astrocytes servent de réservoir d'énergie à disposition des neurones : ils captent le glucose sanguin, le mettent en réserve, et le distribuent aux neurones à la demande. Ils servent donc de réservoir d'énergie, dans lequel les neurones alentours peuvent puiser s'ils en ont besoin. À noter que les astrocytes stockent l'énergie non pas sous la forme de glucose, mais dans des molécules de glycogène et de lactate. Rappelons que le glycogène est synthétisé à partir du glucose. Le glycogène se fabrique en liant plusieurs molécules de glucose entre elles, d'une manière extrêmement compacte. C'est la forme sous laquelle les sucres sont stockés dans la plupart des cellules, cette molécule contenant une grande quantité d'énergie dans un volume très petit. Les astrocytes en concentrent de grandes quantités pour répondre aux besoins métaboliques des neurones, ainsi que pour leur fonctionnement. Si le besoin s'en fait sentir, les liaisons de la molécule de glycogène sont brisées par des enzymes, ce qui libère de nombreuses molécules de glucose, de lactate, ou d'autres formes de sucres. Le transfert du glucose des astrocytes aux neurones peut se faire de diverses manières, mais il se fait principalement sous la forme de lactate. Les astrocytes libèrent du lactate dans le milieu extracellulaire, qui est capté par les neurones. Ce lactate est produit dans les astrocytes par dégradation du glucose et est destiné non au stockage, mais à la consommation immédiate. Dans le détail, le glucose est dégradé en pyruvate, qui est lui-même transformé en lactate. Le lactate est alors envoyé aux neurones, qui synthétisent du pyruvate avec, pyruvate qui est utilisé par la respiration aérobie (cycle de Krebs). On peut préciser que la libération du lactate par les astrocytes est couplée aux besoins des neurones par divers mécanismes. Ce qui veut dire que les astrocytes détectent que les neurones ont besoin d'énergie, et libèrent du lactate selon quand les besoins s'en font sentir. Le premier est que les neurones ont surtout besoin d'énergie, et donc de sucres, après avoir émis des potentiels d'action. Or, les astrocytes mesurent en permanence la quantité de neurotransmetteurs dans le milieu extra-cellulaire : plus il y en a, plus les neurones ont dépensés d'énergie pour les émettre et plus ils ont besoin d'énergie. Pour être plus précis, ils mesurent la quantité de glutamate, non de tous les neurotransmetteurs. Pour résumer, la liaison du glutamate sur les récepteurs astrocytaires va stimuler la libération du lactate dans le milieu extra-cellulaire, qui est ensuite assimilé par les neurones. Évidemment, le métabolisme du glucose implique l'existence de transporteurs du glucose à la surface des astrocytes et des neurones. Dans l'ensemble des tissus, il existe quatorze transporteurs du glucose différents, qui n'ont pas la même composition chimique et sont de forme différente. Ils sont appelés GLUT-1, GLUT-2, GLUT-3, ..., GLUT-14, GLUT étant l'abréviation de ''GLUcose-Transporter''. Ils ne sont pas spécifiques du glucose, mais peuvent aussi servir de transporteurs à d'autres "sucres". Par exemple, le GLUT-5 sert de transporteur pour le glucose, mais aussi le fructose. D'autres servent de transporteur pour l'urate, le myoinositol et quelques autres molécules. Toujours est-il que l'on peut classer ces transporteurs du glucose en trois grandes catégories, mais seuls ceux de la première sont présents dans le cerveau, à savoir les récepteurs de GLUT-1 à GLUT-4 et le GLUT-14. Le transporteur GLUT1 est surtout présent dans la membrane des astrocytes, de même que le transporteur GLUT2. Le premier est présent dans tous les astrocytes cérébraux, alors que GLUT2 est présent dans certaines astrocytes, localisés dans des aires cérébrales bien précises (hypothalamus et tronc cérébral). Le transporteur GLUT3 est la chasse gardée des neurones. ===Le métabolisme du cholestérol=== Le cholestérol est un lipide intervenant dans de nombreuses fonctions métaboliques du corps, et joue notamment un rôle dans le fonctionnement du cerveau. Il s'agit en effet d'un des composants principaux de la myéline qui entoure les axones (la gaine de myéline). Sachant que plus de la moitié du cerveau est composée de substance blanche, donc de myéline, il n'est pas étonnant que le cerveau soit l'organe le plus riche de tous en cholestérol. Certaines études estiment que près de 20% du cholestérol total est localisé dans le cerveau. De plus, le cholestérol est un composant de la membrane des neurones et des cellules gliales. Plus les axones et dendrites d'un neurone se développent, plus ceux-ci doivent fabriquer de membrane cellulaire pour donner naissance aux axones et dendrites. Pour résumer, les besoins en cholestérol augmentent avec l'apparition de nouvelles synapses et dendrites. La quantité de cholestérol cérébral reste approximativement constante au cours du temps. Ce n'est que lors de myélinisation du système nerveux que le cholestérol est fortement synthétisé. Lors de ces périodes, la formation des gaines de myéline augmente les besoins en cholestérol, qui ne peuvent être assouvis que par une synthèse importante. Les périodes de développement des synapses/neurones entrainent une forte consommation en cholestérol, les besoins étant alors fortement augmentés. En-dehors de ces périodes où les besoins sont augmentés, la synthèse de cholestérol cérébral est contrebalancée par sa consommation et son élimination. Le métabolisme cérébral du cholestérol est illustré dans le schéma ci-dessous, que je vous invite à regarder avant de lire ce qui va suivre. [[File:Cerebrosterol.jpg|centre|vignette|upright=2|Métabolisme cérébral du cholestérol.]] Le cholestérol sanguin n'est pas la source de cholestérol cérébral, vu que le cholestérol sanguin ne traverse pas la barrière hémato-encéphalique. Le cholestérol cérébral est synthétisé par les astrocytes, encore eux, sous la forme d'apolipoprotéines (ApoE). Ces apolipoprotéines sont synthétisées sous une forme immature, avant d'être finalisées par l'action de protéines membranaires de type ABCA. Elles sont ensuite absorbées par les neurones et sont transformées en cholestérol à l'intérieur des neurones, via l'action d'une enzyme. Le cholestérol des neurones va ensuite être utilisé par le neurone. Il servira notamment dans la fabrication de la membrane du neurone. Rappelons que le neurone ne produit pas sa gaine de myéline, mais que ce sont les oligodendrocytes qui le font, ce qui fait que le choléstérol capté par les neurones ne sert pas à fabriquer la gaine de myéline. Mais l'utilisation principale du cholestérol intra-neuronal est de loin la formation de protéines appelées bêta-amyloides, présentes à la surface des cellules. On peut signaler que cette protéine est impliquée dans la maladie d'Alzheimer, bien que l'on sache mal comment... Rappelons que le cholestérol cérébral est aussi impliqué dans la fabrication de neurostéroïdes, des stéroïdes qui modulent l'action du GABA et du glutamate. Leur fabrication demande une conversion du cholestérol en prégnénolone, qui est elle-même transformée en divers stéroïdes, puis en neurostéroïdes. La conversion du cholestérol en prégnénolone est effectuée par l'enzyme CYP450scc et a lieu dans les mitochondries. Pour cela, le cholestérol est capté un transporteur qui capte le cholestérol cytoplasmique et le fait rentrer dans les mitochondries, à l'intérieur desquelles il s'effectue la transformation. Il arrive que le cerveau produise un peu plus de cholestérol que demandé. Dans ce cas, le cholestérol produit en excès (non-utilisé par le cerveau) est soit stocké, soit éliminépar diverses voies métaboliques. Seul 1% du cholestérol cérébral est stocké dans les neurones et astrocytes. Il y prend alors la forme de gouttelettes de graisses de petite taille. Ce stockage demande que le cholestérol subisse des modifications chimiques, induites par une enzyme appelée cholesterol acyltransferase 1 (ACAT1/SOAT1). Les neurones qui contiennent l'enzyme CYP46 peuvent dégrader le cholestérol en excès en une molécule appelée cérébrostérol. Appellation bien plus facile à retenir que le nom scientifique du cérébrostérol, à savoir : 24S-hydroxycholestérol. Ce cérébrostérol est émis dans le milieu-extracellulaire où il est soit éliminé, soit recyclé par les astrocytes. Le cérébrostérol peut traverser la barrière hémato-encéphalique, ce qui lui permet d'être éliminé dans la circulation sanguine. Plus de 2/3 du cérébrostérol est éliminé, le reste étant capté par les astrocytes et recyclé en ApoE. ===Le métabolisme des neurotransmetteurs=== Les astrocytes ne vont pas seulement fournir des nutriments aux neurones : ils vont aussi jouer un grand rôle dans le recyclage de certains neurotransmetteurs, comme le GABA, le glutamate, la glycine, et autres. Dans les faits, ces neurotransmetteurs sont produits à partir respectivement de sérine (glycine) et de glutamine (glutamate et GABA). Prenons le cas de la sérine et de la glycine comme premier exemple. La sérine est produite dans les astrocytes à partir du glucose, avant d'être envoyé aux neurones. Les neurones vont alors synthétiser de la glycine à partir de cette sérine et l'utiliser comme neurotransmetteur. Après utilisation, la glycine est recapturée par les astrocytes et est alors dégradée en sérine. Et un nouveau cycle recommence : la sérine synthétisée peut alors être utilisée renvoyée aux neurones, et ainsi de suite. Il en est de même pour le glutamate et le GABA. Ces deux neurotransmetteurs sont recapturés par les astrocytes, qui les dégradent en glutamine. Cette glutamine est alors renvoyée aux neurones, qui pourront re-synthétiser du glutamate et/ou du GABA et les utiliser comme neurotransmetteurs. Il faut noter que le glutamate peut aussi être synthétisé par les astrocytes et les neurones non pas à partir de glutamine, mais à partir d'une molécule produite par le cycle de Krebs (respiration aérobie). [[File:Major metabolic fluxes in neuron-astrocyte coupling for resting conditions.png|centre|vignette|upright=3.0|Major metabolic fluxes (μmol/g tissue/min) in neuron-astrocyte coupling for resting conditions. The fluxes were calculated with the objective of maximizing the glutamate/glutamine/GABA cycle fluxes between the two cell types with subsequent minimization of Euclidean norm of fluxes, using the uptake rates given in Table 1 as constraints. Thick arrows show uptake and release reactions. Dashed arrows indicate shuttling of metabolites between the two cell types. Only key pathway fluxes are represented here for simplicity. The flux distributions for all the reactions listed in Additional File 1 are given in Additional File 4:Supplementary Table 3. (Description is figure caption from original article).]] ==Les vitamines et le cerveau== Dans les sections précédentes du chapitre, nous avons surtout parlé de l'alimentation en énergie du cerveau. Mais il ne faut pas oublier que de nombreuses réactions chimiques permettent d'utiliser cette énergie et de la stocker. De plus, certaines réactions métaboliques permettent de synthétiser des neurotransmetteurs, de façonner la paroi des neurones, de contrôler les différences de concentrations en ions dans le neurone, et ainsi de suite. Ces réactions font naturellement appel à de nombreuses enzymes et autres protéines, la plupart étant synthétisées à partir des nutriments, mais aussi à partir de vitamines. Le cerveau est de loin un des plus gros consommateur de vitamines du corps. D'ailleurs, il faut signaler que le cerveau est naturellement riche en vitamines, celui-ci ayant des réserves assez importantes. C'est notamment le cas pour les vitamines B, qui sont séquestrées dans le cerveau. Aussi, il n'est pas étonnant que leur teneur cérébrale soit largement supérieure à leur concentration sanguine. Par exemple, la concentration en vitamine B9 est près de 4 fois supérieure à la concentration sanguine, de même que la concentration en vitamine B5 et B8 est près de 50 fois plus importante dans le cerveau que dans le sang. Grâce à cela, le cerveau peut survivre à une déficience assez légère et/ou temporaire en vitamines. Cependant, cela n’empêche pas des déficiences en vitamines dans des situations extrêmes, comme un alcoolisme chronique ou un jeune prolongé. Ces déficiences peuvent avoir des conséquences neuropsychiatriques assez importantes, comme nous allons le voir maintenant. Dans ce qui va suivre, nous allons étudier les quatre vitamines les plus importantes pour le cerveau, à savoir les vitamines B1, B6, B9 et B12. ===Les vitamines B9 et B12=== Les vitamines B9 et B12 fonctionnent en tandem dans le corps, un manque de vitamine B12 pouvant être masqué par une complémentation de B9 et réciproquement. Ces cas sont cependant rares, vu que la carence en vitamine B12 ou B9 est exceptionnelle de nos jours. Elle ne touche que les végétariens qui ne se complémentent pas en vitamine B12 (et encore, après quelques mois ou années de ce régime sans complémentation) ou les personnes ayant des problèmes d'absorption des vitamines (anémie de Biermer, usage d'antiacides prolongé, problèmes intestinaux…). La récupération est souvent totale après complémentation en B12 ou B9, mais quelques patients peuvent avoir des séquelles s'ils ne sont pas pris en charge rapidement. La vitamine B9, aussi appelée acide folique, a un métabolisme assez compliqué et est impliquée dans la réplication de l'ADN ou le métabolisme de certains acides aminés. La voie métabolique qui nous intéresse est cependant assez simple : l'acide folique est absorbé par les intestins, puis est transformé par le foie en acide lévoméfolique (5-méthyl-THF), la forme de vitamine B9 qui est absorbée par le cerveau. Ce métabolite peut traverser la barrière hémato-encéphalique en passant à travers un récepteur spécifique : le récepteur folate-alpha. Des déficits au niveau de ce récepteur peuvent entraîner une '''déficience cérébrale en folate''' dans laquelle seul le cerveau subit un déficit en B9, alors que le reste du corps a une alimentation vitaminique normale. Les symptômes sont une hypotonie, des crises épileptiques et un retard mental/psychomoteur. Sa cause principale est une maladie génétique très rare, liée à une mutation du gène FOLR1, le gène qui code pour le récepteur cérébral du folate. Une autre cause est la présence dans le sang d'anticorps qui visent ce récepteur, ce qui est une maladie auto-immune extrêmement rare. La carence en vitamine B12 entraîne un '''syndrome neuro-anémique''', dont le nom traduit ses symptômes : une anémie et des symptômes neuropsychiatriques variés. Pour ce qui est des manifestations psychiatriques, les symptômes vont de symptômes mineurs (troubles du sommeil, dépression) à des symptômes plus graves pouvant aller jusqu’à la démence ou des crises psychotiques. Le symptôme neurologique le plus grave est une démyélinisation du système nerveux dont les symptômes sont semblables à la sclérose en plaque, qui peut toucher la moelle épinière, les nerfs et/ou le cerveau. L'atteinte des nerfs périphériques fait que ceux-ci perdent leur gaine de myéline, donnant des polynévrites assez marquées. L'atteinte médullaire touche essentiellement le faisceau pyramidal ainsi que les cordons antérieurs (système des colonnes dorsales). L’atteinte du faisceau pyramidal et des nerfs moteurs se traduit par l'apparition de troubles moteurs tels qu’une paralysie, une spasticité, un défaut de coordination motrice ou autre. L'atteinte des nerfs sensitifs et des colonnes dorsales médullaires est la cause de troubles sensitifs variés : douleurs dans les extrémités, picotements, sensations de décharges électriques, et cætera. ===La vitamine B6=== Nous avons vu il y a quelques chapitres que la vitamine B6 est primordiale dans la synthèse de la sérotonine et de la dopamine, du GABA et de la mélatonine. Pour rappel, la vitamine B6 est une coenzyme associée à plusieurs enzymes. Elle active l'enzyme ''dopa-décarboxylase'', qui dégrade le 5-HT est transformé en sérotonine et la L-DOPA en dopamine. C'est aussi la coenzyme de la GAD, qui dégrade le glutamate en GABA. La vitamine B6 existe sous plusieurs formes différentes, mais seules trois d'entre elles entrent dans le cerveau : le pyridoxal, la pyridoxine et la pyridoxamine. Ce sont des formes inactives, qui demandent à être phosphatées pour devenir des formes actives de la vitamine B6, à savoir du phosphate de pyridoxal, du phosphate de pyridoxine ou du phosphate de pyridoxamine. Dans le cerveau, les formes inactives de B6 sont transformées en phosphate de pyridoxal par deux enzymes : la PK et la PNPO (''Pyridoxine 5'-phosphate oxidase''). Le phosphate de pyridoxal intervient ensuite dans la dégradation de la lysine et de la proline (deux acides aminés), via deux voies métaboliques différentes dans laquelle de nombreuses enzymes interviennent. Dans ce réseau métabolique, divers troubles peuvent survenir. La plus fréquente, la ''carence en vitamine B6'' perturbe le fonctionnement global du cerveau. Une déficience en vitamine B6 entraine donc une baisse de production des neurotransmetteurs cités plus haut, qui touche préférentiellement la synthèse du GABA et de la sérotonine. La baisse de GABA induite se traduit par une hausse de l'activité électrique des neurones, avec deux conséquences principales : un mauvais sommeil et, plus rarement, des crises épileptiques. La baisse de sérotonine et de dopamine se manifeste quant à elle par un état anxio-dépressif et une hausse de l'impulsivité et de la nervosité. La déficience peut aussi se manifester dans le système nerveux périphérique par une inflammation généralisée des nerfs (une polynévrite). À l'inverse, une surdose de vitamine B6 n'entraine pas de symptômes clairs, tant que la surdose n'est pas prolongée. Cependant, une complémentation en B6 prolongée durant plusieurs mois peut engendrer des névrites totalement réversibles avec l'arrêt de la supplémentation. L''''épilepsie sensible au phosphate de pyridoxal''' est une maladie génétique à transmission autosomique dominante. Elle est causée par une ''déficience en PNPO'', qui touche la synthèse du phosphate de pyrixodal à partir des formes inactives de B6. Avec cette maladie, l'enzyme PNPO n'est pas synthétisée, ce qui fait que la vitamine B6 n'agit plus du tout dans le cerveau. Cela entraine une carence massive en B6 active dans le cerveau. En conséquence, la synthèse des neurotransmetteurs est perturbée et le métabolisme neuronal des acides aminés est perturbé. Le résultat est une encéphalopathie épileptique néonatale, qui survient dès les premières heures de vie du bébé atteint. Elle ne réagit pas aux traitements habituels et n'est soignée que par un traitement à base de phosphate de pyridoxine/pyridoxal. D'autres symptômes peuvent survenir, comme une hypotonie, des troubles respiratoires, des mouvements anormaux, etc. Similaire à la maladie précédente, l''''épilepsie pyridoxine-dépendante''' est un ensemble de maladies génétiques caractérisées par une encéphalopathie néonatale similaire à la maladie précédente. Les crises épileptiques sont de type myocloniques, avec un tracé typique sur l'EEG. La seule différence est que la maladie est sensible à un traitement à base de pyridoxine, une forme inactive de la B6, là où la précédente a besoin de la forme active de la B6. L'identification de cette maladie est souvent difficile à faire et le diagnostic se fait après administration de vitamine B6 ou un diagnostic génétique. Elle se manifeste très tôt : dans les premiers jours ou mois de vie pour les formes précoces, vers 1 à 3 ans pour les formes tardives. Ce syndrome touche entre une naissance sur 500 000 et une naissance sur 400 000. Ses causes sont nombreuses et de nombreux mutations génétiques peuvent la causer. Dans les grandes lignes, il existe deux sous-syndromes principaux : une forme précoce qui apparait dans les premières heures de vie, et une forme tardive qui apparait vers 1 à 3 ans. * La forme précoce exprime une épilepsie prénatale dès 20 semaines de gestation. L'épilepsie se manifeste rapidement et toutes les formes de crises épileptiques peuvent survenir : myoclonies, absences, crises toniques, toniques-cloniques. Elle est souvent secondée par de l'irritabilité et une réaction excessive aux stimuli, ainsi que par des malformations cérébrales diverses (hydrocéphalie, malformations du corps calleux, ...). On peut observer des troubles métaboliques généraux, des troubles respiratoires, et bien d'autres symptômes divers. Sans traitements, la maladie entraine un retard mental et divers déficits neurologique et développementaux. La forme précoce la plus fréquente est causée par une mutation qui perturbe la synthèse de l'antiquitine, une enzyme de la voie de dégradation de la lysine. * Par contraste, la forme tardive apparait avant 3 ans et répond initialement aux médicaments anti-épileptiques, avant que ces traitements cessent de faire effet. L'épilepsie est isolée, avec peu d'autres symptômes neurologiques et une absence de malformations cérébrales. ===La vitamine B1=== La vitamine B1, aussi appelée thiamine, est une vitamine du fameux cycle de Krebs (une série de réactions chimiques qui fournit de l'énergie aux cellules vivantes). Une carence en vitamine B1 entraine une pénurie d'énergie et d'ATP dans les cellules, qui se mettent à dysfonctionner et parfois à mourir. Le système nerveux étant un tissu très gourmand d'un point de vue métabolique, toute carence en vitamine B1 retenti en premier lieu sur le fonctionnement cérébral. Autant dire qu'elle est extrêmement importante pour le système nerveux, des carences pouvant être tout aussi graves que les carences en vitamines B12 ou B6. La carence en thiamine cause un stress métabolique aux neurones, qui cause des dysfonctionnements divers des potentiels d'action, mais qui peut aussi entrainer souvent la mort du neurone par apoptose. De plus, la carence va aussi modifier la recapture du glutamate, entrainant l'apparition d'une excitotoxicité (le glutamate excite les neurones à mort). Beaucoup de neurones dysfonctionnent, quand ils ne meurent rapidement, ce qui cause l'apparition d'une maladie : l''''encéphalopathie de Wernicke'''. Ses symptômes sont souvent assez clairs, 80% des cas manifestant la triade : défaut de coordination des mouvements (ataxie), paralysie des yeux (ophtalmoplégie) et confusion (delirium). D'autres symptômes peuvent se faire jour, comme une profonde amnésie, une perte de la mémoire à court-terme, une psychose, ou des troubles végétatifs. L'origine de ces symptômes est liée à diverses atteintes du thalamus, de l'hypothalamus et du tronc cérébral. Par exemple, la paralysie oculaire provient d'une atteinte des noyaux des nerfs crâniens oculomoteurs. L"amnésie est quant à elle liée à une atteinte des corps mamillaires de l'hypothalamus. Une carence prolongée en B1 s'observe surtout chez les alcooliques, l'alcool stoppant l'absorption intestinale de la B1. Chez certains patients, l'encéphalopathie de Wernicke évolue vers des troubles cognitifs permanents. La démence qui en résulte est appelée le '''syndrome de Korsakoff''', du nom de son découvreur. Son symptôme principal est une amnésie assez particulière. Nous allons devoir parler rapidement de l'amnésie, chose qui sera détaillé dans le chapitre sur la mémoire. L'amnésie du syndrome de Krosakoff est une perte de la mémoire à court-terme, avec une incapacité à mémoriser de nouveaux souvenirs ou de nouvelles connaissances. Les savoirs et souvenirs déjà acquis sont relativement préservés, bien que quelques déficits peuvent se voir. L'amnésie porte donc essentiellement sur les acquisitions qui suivent le traumatisme, cette forme d'amnésie étant appelée amnésie antérograde. L'amnésie qui touche les souvenirs d'avant l'apparition du syndrome est appelée amnésie rétrograde. L'amnésie du syndrome de Korsakoff est essentiellement antérograde, bien qu'une faible amnésie rétrograde soit possible. Si amnésie rétrograde il y a, celle-ci ne touche généralement que les souvenirs et savoirs récents, qui datent de quelques mois, années ou décennies avant le syndrome. Outre l'amnésie, divers troubles cognitifs peuvent se manifester, que ce soit des troubles du langage (aphasie), des troubles de la reconnaissance des objets et de la catégorisation (agnosie) ou des troubles intellectuels. ==Les minéraux et le cerveau== Outre les vitamines, les mal-nommés « minéraux » sont d'une importance capitale pour le fonctionnement normal du cerveau. Les « minéraux » les plus importants sont de loin les ions Calcium, Potassium et Sodium, sans lesquels il ne peut y avoir de potentiels d'action. Leur rôle a déjà été abordé dans le chapitre sur potentiel d'action et nous n'en reparlerons pas ici. Les autres ions que nous allons aborder sont le magnésium, le cuivre, le fer et quelques autres. Vous remarquerez qu'il s'agit d'ions métalliques, à quelques exceptions près. Tous les ions ont une concentration particulièrement bien régulée, le cerveau disposant de toute une machinerie chimique pour régler leur concentration. Il faut dire que ces ions deviennent toxiques quand ils sont en grandes quantités. C'est notamment le cas des ions métalliques, qui sont impliqués dans des réactions d’oxydoréduction qui créent des molécules « poisons » (des radicaux libres). En temps normal, les produits nocifs de ces réactions sont éliminés ou dégradés par la machinerie cellulaire du cerveau, mais ces processus sont dépassés quand la concentration en ions métalliques devient trop importante. De même, une déficience est nuisible pour les neurones, ces ions servant dans de nombreuses réactions chimiques importantes pour le fonctionnement des neurones. La concentration en ions du cerveau est sévèrement contrôlée par divers mécanismes, dans lesquels la barrière hémato-encéphalique joue un rôle crucial. Elle protège le cerveau des variations de concentration ionique du sang. Par exemple, prenons le cas où la concentration en sodium du sang augmente, suite à la consommation d'un aliment particulier, d'une réponse hormonale, ou d'un supplément alimentaire. Le cerveau ne va pas être impacté par cette variation, et en sera isolé : la concentration ionique intracérébrale restera la même. C'est grâce à la barrière hémato-encéphalique, qui isole le cerveau des vaisseaux sanguins. L'absorption d'ions dans le cerveau, ou leur excrétion, est réalisée par des canaux ioniques et/ou des transporteurs, qui se trouvent à la surface de la barrière hématoencéphalique. Elles vont se lier aux minéraux ou aux vitamines à absorber et vont les rapatrier dans les astrocytes pour l'absorption. Une partie des ions est perdue dans le liquide céphalorachidien, et est emportée avec lui lors de son excrétion dans le sang. ===Le magnésium=== L'ion magnésium a aussi été vu dans le chapitre sur les récepteurs synaptiques et la plasticité synaptique. Nous avons vu que les récepteurs NMDA du glutamate sont bloqués par un ion magnésium, qui bouche le canal ionique. Du moins, c'est le cas tant que le potentiel du neurone reste inférieur à -60 mV. Si la tension dépasse ce seuil, l'ion Magnésium est éjecté et le canal ionique s'ouvre, excitant le neurone. On devine donc qu'un manque en magnésium se traduit par une hyper-excitabilité neuronale, alors qu'un excès de Magnésium entraine une hypo-excitabilité neuronale. Dans les deux cas, l'atteinte neuronale est diffuse, mais ciblée sur les neurones sensibles au glutamate. * La déficience en magnésium entraine des symptômes neurologiques qui vont d'une simple asthénie et/ou une faiblesse musculaire, à des symptômes plus sérieux comme des convulsions et plus rarement un coma. * Pour un excès en magnésium, les symptômes neurologiques sont frustres pour les faibles hypermagnésémies, mais bien plus lourds dans les cas graves. À faible dose en excès, le magnésium entraine une simple léthargie et/ou asthénie. Pour un excès assez fort, elle surtout des symptômes neuromusculaires. Il a, à hautes doses, un effet sur la jonction neuromusculaire similaire à celui du curare. En clair, elle cause une décontraction musculaire, une diminution des réflexes, des paralysies (notamment respiratoires). Dans certains cas extrêmes, on observe une dilatation pupillaire liée à un blocage du système nerveux sympathique. ===Le cuivre=== Le cuivre traverse la barrière hémato-encéphalique par le biais de deux transporteurs nommés CRT1 et APH7A, et s'accumule dans le cerveau. S'il y a trop de cuivre dans le cerveau, l'excès de cuivre est éliminé dans le liquide cérébrospinal, puis dans le sang, via l'action des mêmes transporteurs. [[File:Metabolisme cerebral du cuivre.png|centre|vignette|upright=2.5|Métabolisme cérébral du cuivre]] Les mêmes transporteurs sont présents à la surface des neurones et des cellules gliales, ce qui leur permet d'absorber du cuivre s'il en ont besoin. Le cuivre n'a pas de rôle physiologique clair au niveau du cerveau, au moment où j'écris ces lignes. Tout ce que l'on sait est que des excès ou des carences entrainent de nombreux symptômes au niveau du foie, du cerveau et d'autres tissus/organes. Chez certaines personnes, les transporteurs du cuivre dysfonctionnent, ce qui fait que le cuivre ne rentre pas, ou au contraire s'accumule, dans les tissus. La '''maladie de Menkes''' est causée par un dysfonctionnement du transporteur ATP7A, qui entraine une déficience en cuivre, qui touche notamment le cerveau. Une des conséquences est que le cuivre ne traverse plus la barrière hémato-encéphalique. Les neurones privés de cuivre meurent rapidement, la myéline ne se forme pas autour des axones. Les patients montrent un manque de tonus musculaire (hypotonie), de l'épilepsie et des symptômes neurologiques variés. On observe aussi un visage déformé, caractéristique de la maladie, une perte des cheveux, et quelques autres symptômes. Il s'agit d'une maladie grave qui apparait quelques mois après la naissance. Les enfants touchés ne dépassent pas l'âge de 3-5 ans. Les maladies liées à l'accumulation de cuivre dans le cerveau se manifestent (entre autres) par des symptômes neurologiques assez francs. Le cuivre s'accumule de préférence dans les ganglions de la base, qui sont les premiers touchés par un excès de cuivre, ce qui entraine des symptômes caractéristiques : parkinsonisme, mouvements involontaires anormaux (chorée, tics, dyskinésies, autres), troubles psychiatriques variés, atteinte cognitive. <noinclude>[[File:Kayser-Fleischer ring.jpg|vignette|Anneau de Kayser-Fleischer, caractéristique de la maladie de Wilson.]]</noinclude> La '''maladie de Wilson''' est une maladie (en fait, un ensemble de maladies génétiques) qui entraine une accumulation de cuivre dans l'organisme. Les organes les plus touchés sont le foie et le cerveau. Seuls une moitié des patients manifestent ces symptômes neuropsychiatriques. Les autres symptômes sont des problèmes de foie et aux yeux, parfois au cœur et aux reins. Les patients ont presque tous des troubles au foie, notamment une cirrhose, qui peuvent cependant passer inaperçus quand leurs symptômes sont frustres (ictère, fatigue, saignements, hypertension dans la veine porte, ...). Chez certains patients, on observe un anneau brun sur le pourtour des iris et des yeux, quasi-pathognomonique de la maladie. Au niveau cérébral, l'accumulation de cuivre est toxique pour les neurones, qui meurent progressivement. Les symptômes de la maladie traduisent une atteinte des ganglions de la base, qui sont les aires cérébrales les plus touchées par l'accumulation de cuivre. * Les symptômes neurologiques sont des problèmes d'équilibre (ataxie), un parkinsonisme, des troubles du tonus musculaire (dystonie). Par contre, les troubles sensoriels sont très rares, au point que leur présence signifie pour le médecin qu'il vaut mieux chercher un autre diagnostic. Plus rarement, une épilepsie peut survenir, mais ce n'est pas un symptôme diagnostic. * Les symptômes psychiatriques sont assez variés, mais sont essentiellement des troubles du comportement : désinhibition, irritabilité extrême, impulsivité, etc. On observe aussi fréquemment des troubles l'humeur (dépression), de l'anxiété. On observe plus rarement une psychose (syndrome regroupant hallucinations, délires, désorganisation de la pensée et troubles du comportement). Il arrive que les patients subissent des troubles cognitifs/intellectuels, qui miment une démence : pertes de mémoire, des troubles de l'idéation (pensée ralentie), et autres. ===Le fer=== Le fer est utilisé par tous les tissus et toutes les cellules du corps humain. Il est présent dans l'hémoglobine des globules rouge, la molécule qui fixe l'oxygène et le CO2 sanguin. Les autres cellules en ont besoin pour fabriquer de l'énergie sous forme d'ATP. Pour être précis, il sert pour la respiration cellulaire, au niveau de la chaine de transport d'électrons des mitochondries (ce détail aura son importance pour l'ataxie de Friedrich). Et cela vaut aussi pour les neurones et cellules gliales. De plus, les neurones ont besoin de fer pour fabriquer certains neurotransmetteurs. Toutes les monoamines sont synthétisées par des enzymes dont le fer est une co-enzyme. Dans le sang, le fer se lie à une molécule de transport appelée la '''transferrine'''. Elle capture le fer libre, le transporte dans le sang et le relâche au niveau des tissus qui en ont besoin. La transferrine est tellement efficace qu'il n'y a presque pas d'ions Fer isolés, dissous dans le sang. Pour rentrer dans le cerveau, la transferrine doit traverser la barrière-hématoencéphalique. Nous en avions déjà parlé dans le chapitre sur la barrière hémato-encéphalique, aussi nous ne reviendrons pas dessus. Toujours est-il que le fer rentre dans le cerveau sous trois formes : du fer lié à de la transferrine, des ions <math>Fe^{2+}</math> et des ions <math>Fe^{3+}</math>. Une fois dans le cerveau, une partie du <math>Fe^{2+}</math> est immédiatement oxydé en <math>Fe^{3+}</math> par diverses enzymes appelés des ferroxydases (l'''Hephaestine'' étant la plus connue). Le fer <math>Fe^{3+}</math> ne tarde pas à se lier à de la transferrine intra-cérébrale. Car oui, il y a de la transferrine dans le cerveau. Une partie provient de la transferrine sanguine, une autre partie est produite localement dans les plexus choroïdes. Précisons que la transferrine sanguine est saturée à seulement 30% de sa capacité de transport maximale, la transferrine cérébrale atteint presque 100%. Il s'agit pourtant de la même molécule, mais les différences chimiques entre le sang et le tissu cérébral font que... Une conséquence est la transferrine ne peut pas servir de tampon en cas d'excès en fer cérébral, vu qu'elle est déjà chargée au maximum, ce qui rend les neurones très sensibles à une surcharge en fer. La répartition du Fer n'est pas uniforme dans le cerveau. Premièrement, le fer s'accumule de préférence dans les cellules gliales plutôt que dans les neurones, avec une préférence pour les oligodendrocytes que les astrocytes. Comparé aux neurones, il y a environ 5 fois plus de fer dans les oligodendrocytes et 3 fois plus dans les astrocytes. La raison est que la synthèse de la myéline, réalisée par les oligodendrocytes, demande pas mal de fer. Au-delà de ces différences cellulaires, il y a une répartition inégale au niveau anatomique. Le fer s'accumule préférentiellement dans les ganglions de la base et la substance noire (la ''substantia nigra pars compacta'', pour être précis). Et cela explique pourquoi certaines maladies entrainant un excès de fer dans le cerveau se traduisent par des syndromes parkinsonien, comme on va le voir à l'instant. Les neurones ne peuvent pas faire de stocks de fer, car ils ne produisent pas de ferritine, une enzyme qui peut faire des réserves de fer. Par contre, les cellules gliales en sont capables. Elles produisent de la ferritine, ce qui leur permet de faire des réserves de fer. De même, la barrière hémato-encéphalique peut émettre des molécules de ferritine, qui sont captées par les oligodendrocytes. Ils peuvent ainsi internaliser la ferritine produite par la BHE si besoin. Les oligodendrocytes ont des stocks de ferritine plus important que ceux des astrocytes, vu qu'ils ont des besoins en fer plus important (métabvolisme + fabrication myéline). Les astrocytes peuvent absorber le fer de deux manières. La première absorbe les ions <math>Fe^{2+}</math> via un canal ionique/transporteur nommé le DMT1. La seconde absorbe la transferrine cérébrale de la même manière que le fait la barrière hémato-encéphalique. La transferrine est absorbée, le fer s'en détache, puis est convertit en ion <math>Fe^{2+}</math>. Les astrocytes peuvent ensuite éliminer le fer en excès via un transporteur nommé la ferroportine. Les neurones font la même chose que les astrocytes, avec les mêmes canaux ioniques, les mêmes enzymes, la ferroportine en cas d'excès, etc. La régulation du taux de fer sanguin est en partie le fait des astrocytes. Ils produisent une hormone appelée l'hepcidine, qui régule le taux de fer sanguin. L'hepcidine agit notamment sur la ferroportine, une molécule de transport du fer, qui permet au fer de rentrer dans le cerveau. L'hepcidine bloque ce transporteur, sans compter qu'il détruit les transporteurs "en trop" en les internalisant dans les cellules de la barrière hémato-encéphalique. [[File:Iron BBB.jpg|centre|vignette|upright=2.5|Les différentes voies de traversée de la barrière hémato-encéphalique pour le fer. Le transport vésiculaire normal est illustré sur la cellule de droite, la voie utilisant la ferroportine est illustré sur la cellule du milieu.]] Quelques rares maladies génétiques entrainent une accumulation de fer dans le cerveau. Elles sont regroupées sous le nom de '''''Neurodegeneration with brain iron accumulation''''', abrévié NBIA. L'accumulation touche en priorité les ganglions de la base et se traduit donc par un syndrome parkinsonien ou d'autres mouvements anormaux (chorée, dystonies), parfois couplés à un déclin intellectuel/cognitif. Les médecins ont identifié une petite dizaine de sous-types de NBIA, chacun se distinguant des autres par le gène muté et les mécanismes de l'accumulation du fer. {|class="wikitable" |- !Type de NBIA !Gène muté |- !Neurodégénération associée à la panthotenate-kinase (PKAN) |PANK2 |- !Neurodégénération associée à PLA2G6 (PLAN) |PLA2G6 |- !Neurodegeneration associée aux protéines de la membrane mitochondriale (MPAN) |C19orf12 |- !Neurodégénération associée à la protéine Beta-Propeller (BPAN) |WDR45 |- !FAHN |FA2H |- !Syndrome de Kufor-Rakeb |ATP13A2 |- !Neuroferritinopathy |FTL |- !Acéruloplasminémie |CP |- !Syndrome de Woodhouse-Sakati |DCAF17 |- !CoPAN |COASY |} : Pour ceux qui veulent en savoir plus sur les NBIA, je conseille la lecture de ce lien : [https://www.nbiadisorders.org/about-nbia/overview-of-nbia-disorders NBIA disorders association] Mais il existe des maladies qui sont causées non pas par une accumulation de Fer dans le cerveau, mais par des dysfonctionnements plus compliqués à expliquer. L''''ataxie de Friedreich''' est une de ces maladies. Cette maladie est causée par une mutation qui perturbe la fabrication d'une enzyme, la frataxine. Le métabolisme intracellulaire du Fer est perturbé, et plus précisément le métabolisme mitochondrial. Le résultat est que les cellules des tissus fortement consommateurs d'ATP meurent rapidement, les neurones ne faisant pas exception. De plus, la gaine de myéline des neurones se dégrade et finit par disparaitre, sans être remplacée. La maladie démarre aux alentours de l'adolescence et se manifeste principalement par des problèmes d'équilibre et de coordination des mouvements (une ataxie, qui donne son nom à la maladie). Par la suite, on observe des troubles neurologiques moteurs et sensoriels, assez divers, d'apparition progressive. Certains sont causés par une atteinte du cervelet (troubles de l’articulation, des mouvements oculaires), d'autres par une atteinte faisceau pyramidal (paralysie, faiblesse musculaire), et/ou par une atteinte de la moelle épinière. Typiquement, le patient a du mal à marcher, perd facilement l'équilibre, a du mal à coordonner ses mouvements. Puis, le patient perd progressivement l'usage de ses bras et de ses jambes, il ressent une faiblesse musculaire envahissante. Parfois, il a du mal à articuler, ses mouvements oculaires sont erratiques. Quand sa moelle épinière et atteinte, sa sensibilité corporelle se dégrade, son sens du toucher et sa proprioception disparaissent. Beaucoup plus rarement, les nerfs optiques et auditifs se démyélinisent, causant perte d'acuité visuelle ou auditive, cécité, surdité, etc. Précisons pour finir que la maladie ne touche pas que le cerveau, mais cause aussi des atteintes cardiaques (très fréquentes), une scoliose ou d'autres déformations osseuses, et parfois un diabète (10-20% des patients). <noinclude> {{NavChapitre | book=Neurosciences | prev=La barrière hémato-encéphalique | prevText=La barrière hémato-encéphalique | next=La pression intracrânienne | nextText=La pression intracrânienne }}{{autocat}} </noinclude> nfmew6j7v43fv7bh3yghcl982g6yrg2 Fonctionnement d'un ordinateur/Introduction 0 71086 744100 743981 2025-06-04T20:28:46Z Mewtow 31375 /* Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières */ 744100 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières=== La '''première génération d'ordinateur''' est celle des ordinateurs datant d'avant l'invention du transistor. Ils étaient conçus avec des tubes à vide ou des relais, des composants électroniques assez rudimentaires. Les ordinateurs de première génération étaient très simples, ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, ils n'avaient pas assez de relais ou de tubes à vides à disposition pour cela. Le tout premier ordinateur est le Z1, un modèle unique inventé par Konrad Suze entre 1936 et 1938. Le processeur du Z1 gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis). Les nombres en question étaient encodés sur 22 bits, ce dont les informaticiens n'ont plus l'habitude. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:CartePerforée.jpg|centre|vignette|upright=2|Carte Perforée.]] [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> jh2bob1simzeqtrl9eepd1sf47kwlad 744101 744100 2025-06-04T20:37:27Z Mewtow 31375 /* Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières */ 744101 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Le ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Après sa destruction dans un bombardement lors de la seconde guerre mondiale, le Z1 a été remplacé par un modèle dit Z2, lui-même suivi par le Z3, qui n'étaient que des améliorations du Z1. Tous étaient des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques (des relais) et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les ordinateur qui ont suivi, avant les années 50, étaient tous de ce type. En 1944, le Harvard Mark I a été mis en service, suivi par le Z4 l'année suivante. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] ===Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''première génération d'ordinateur''' est celle des ordinateurs datant d'avant l'invention du transistor. Ils étaient conçus avec des tubes à vide ou des relais, des composants électroniques assez rudimentaires. Les ordinateurs de première génération étaient très simples, ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, ils n'avaient pas assez de relais ou de tubes à vides à disposition pour cela. La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 0x87lmmo49lp19392ti0gjo536gqnf5 744102 744101 2025-06-04T20:37:56Z Mewtow 31375 /* Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières */ 744102 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Le ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Après sa destruction dans un bombardement lors de la seconde guerre mondiale, le Z1 a été remplacé par un modèle dit Z2, lui-même suivi par le Z3, qui n'étaient que des améliorations du Z1. Tous étaient des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques (des relais) et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les ordinateur qui ont suivi, avant les années 50, étaient tous de ce type. En 1944, le Harvard Mark I a été mis en service, suivi par le Z4 l'année suivante. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] ===Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''première génération d'ordinateur''' est celle située entre les premiers ordinateurs électro-mécaniques et les ordinateurs datant d'avant l'invention du transistor. Ils étaient conçus avec des tubes à vide ou des relais, des composants électroniques assez rudimentaires. Les ordinateurs de première génération étaient très simples, ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, ils n'avaient pas assez de relais ou de tubes à vides à disposition pour cela. La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 1ok14p5hrxzjt46knoaqm0a8r9oq8wc 744103 744102 2025-06-04T20:42:32Z Mewtow 31375 /* Le ordinateurs électro-mécaniques : les premiers ordinateurs */ 744103 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Le ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Après sa destruction dans un bombardement lors de la seconde guerre mondiale, le Z1 a été remplacé par un modèle dit Z2, lui-même suivi par le Z3, qui n'étaient que des améliorations du Z1. Tous étaient des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques (des relais) et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les ordinateur qui ont suivi, avant 1944, étaient tous de ce type. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] ===Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''première génération d'ordinateur''' est celle située entre les premiers ordinateurs électro-mécaniques et les ordinateurs datant d'avant l'invention du transistor. Ils étaient conçus avec des tubes à vide ou des relais, des composants électroniques assez rudimentaires. Les ordinateurs de première génération étaient très simples, ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, ils n'avaient pas assez de relais ou de tubes à vides à disposition pour cela. La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 3gd1ujny5bzik8cjjx66800t174pmbt 744104 744103 2025-06-04T20:50:11Z Mewtow 31375 /* Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières */ 744104 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Le ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Après sa destruction dans un bombardement lors de la seconde guerre mondiale, le Z1 a été remplacé par un modèle dit Z2, lui-même suivi par le Z3, qui n'étaient que des améliorations du Z1. Tous étaient des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques (des relais) et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les ordinateur qui ont suivi, avant 1944, étaient tous de ce type. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] ===Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières=== A partir de 1944, de nombreux ordinateurs plus puissants ont été mis sur le marché. Des grandes noms de l'histoire de l'informatique date de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, suivi par le Z4 l'année suivante. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Mais c'est l'arrivée de l'ENIAC en 1945 qui a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, et a trait aux programmes qui peuvent être écrit pour un ordinateur. Nous ne la détaillerons pas ici. La seconde innovation est que le programme n'était plus mémorisé sur des cartes perforée, mais dans une mémoire électronique dans l'ordinateur lui-même. En clair, l'ENIAC était le premier '''''Stored-program computer''''', ordinateur à programme enregistré en français. Enfin, l'ENIAC était composé non pas de relais et l'élèments mécaniques, mais uniquement de tubes à vides, des composants électroniques assez rudimentaires plus ou moins équivalents aux transistors modernes. [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] Les ordinateurs qui ont suivi l'ENIAC sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les ordinateurs de première génération étaient très simples, ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, ils n'avaient pas assez de relais ou de tubes à vides à disposition pour cela. La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 36aktwmhiv8hi8qy5hs007nuy7zd6iw 744105 744104 2025-06-04T20:50:37Z Mewtow 31375 /* Le ordinateurs électro-mécaniques : les premiers ordinateurs */ 744105 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Après sa destruction dans un bombardement lors de la seconde guerre mondiale, le Z1 a été remplacé par un modèle dit Z2, lui-même suivi par le Z3, qui n'étaient que des améliorations du Z1. Tous étaient des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques (des relais) et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les ordinateur qui ont suivi, avant 1944, étaient tous de ce type. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] ===Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières=== A partir de 1944, de nombreux ordinateurs plus puissants ont été mis sur le marché. Des grandes noms de l'histoire de l'informatique date de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, suivi par le Z4 l'année suivante. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Mais c'est l'arrivée de l'ENIAC en 1945 qui a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, et a trait aux programmes qui peuvent être écrit pour un ordinateur. Nous ne la détaillerons pas ici. La seconde innovation est que le programme n'était plus mémorisé sur des cartes perforée, mais dans une mémoire électronique dans l'ordinateur lui-même. En clair, l'ENIAC était le premier '''''Stored-program computer''''', ordinateur à programme enregistré en français. Enfin, l'ENIAC était composé non pas de relais et l'élèments mécaniques, mais uniquement de tubes à vides, des composants électroniques assez rudimentaires plus ou moins équivalents aux transistors modernes. [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] Les ordinateurs qui ont suivi l'ENIAC sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les ordinateurs de première génération étaient très simples, ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, ils n'avaient pas assez de relais ou de tubes à vides à disposition pour cela. La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 73yof63znezra7jthlx96bha2p2m7p4 744106 744105 2025-06-04T20:55:41Z Mewtow 31375 /* Les ordinateurs électro-mécaniques : les premiers ordinateurs */ 744106 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Ils étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques (des relais) et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières=== A partir de 1944, de nombreux ordinateurs plus puissants ont été mis sur le marché. Des grandes noms de l'histoire de l'informatique date de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, suivi par le Z4 l'année suivante. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Mais c'est l'arrivée de l'ENIAC en 1945 qui a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, et a trait aux programmes qui peuvent être écrit pour un ordinateur. Nous ne la détaillerons pas ici. La seconde innovation est que le programme n'était plus mémorisé sur des cartes perforée, mais dans une mémoire électronique dans l'ordinateur lui-même. En clair, l'ENIAC était le premier '''''Stored-program computer''''', ordinateur à programme enregistré en français. Enfin, l'ENIAC était composé non pas de relais et l'élèments mécaniques, mais uniquement de tubes à vides, des composants électroniques assez rudimentaires plus ou moins équivalents aux transistors modernes. [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] Les ordinateurs qui ont suivi l'ENIAC sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les ordinateurs de première génération étaient très simples, ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, ils n'avaient pas assez de relais ou de tubes à vides à disposition pour cela. La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> les8yl97rp9nuyzoaqmw4im1d52tj33 744107 744106 2025-06-04T20:58:33Z Mewtow 31375 /* Les ordinateurs électro-mécaniques : les premiers ordinateurs */ 744107 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Ils étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques (des relais) et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières=== A partir de 1944, de nombreux ordinateurs plus puissants ont été mis sur le marché. Des grandes noms de l'histoire de l'informatique date de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, suivi par le Z4 l'année suivante. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Mais c'est l'arrivée de l'ENIAC en 1945 qui a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, et a trait aux programmes qui peuvent être écrit pour un ordinateur. Nous ne la détaillerons pas ici. La seconde innovation est que le programme n'était plus mémorisé sur des cartes perforée, mais dans une mémoire électronique dans l'ordinateur lui-même. En clair, l'ENIAC était le premier '''''Stored-program computer''''', ordinateur à programme enregistré en français. Enfin, l'ENIAC était composé non pas de relais et l'élèments mécaniques, mais uniquement de tubes à vides, des composants électroniques assez rudimentaires plus ou moins équivalents aux transistors modernes. [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] Les ordinateurs qui ont suivi l'ENIAC sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les ordinateurs de première génération étaient très simples, ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, ils n'avaient pas assez de relais ou de tubes à vides à disposition pour cela. La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> lmwjkd1q4pppdzdk0m6zctoz0f2d7br 744108 744107 2025-06-04T21:04:48Z Mewtow 31375 /* Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières */ 744108 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Ils étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques (des relais) et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières=== A partir de 1944, de nombreux ordinateurs plus puissants ont été mis sur le marché. Des grandes noms de l'histoire de l'informatique date de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, suivi par le Z4 l'année suivante. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Mais c'est l'arrivée de l'ENIAC en 1945 qui a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, et a trait aux programmes qui peuvent être écrit pour un ordinateur. Nous ne la détaillerons pas ici. La seconde innovation est que l'ENIAC était composé non pas de relais et d'éléments mécaniques, mais uniquement de tubes à vides, des composants électroniques assez rudimentaires plus ou moins équivalents aux transistors modernes. Le ''Manchester Baby'' a introduit une innovation extrêmement importante, au point où on considère que c'est le premier ordinateur à avoir tous les critères nécessaires pour être appelé un ordinateur. Son innovation est que le programme n'était plus mémorisé sur des cartes perforée, mais dans une mémoire électronique dans l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''''Stored-program computer''''', ordinateur à programme enregistré en français. [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] Les ordinateurs qui ont suivi l'ENIAC sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les ordinateurs de première génération étaient très simples, ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, ils n'avaient pas assez de relais ou de tubes à vides à disposition pour cela. La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> sg5izlx1ksms3je5vs1uau2v4mp8huj 744109 744108 2025-06-04T21:07:24Z Mewtow 31375 /* Les ordinateurs électro-mécaniques : les premiers ordinateurs */ 744109 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Ils étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières=== A partir de 1944, de nombreux ordinateurs plus puissants ont été mis sur le marché. Des grandes noms de l'histoire de l'informatique date de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, suivi par le Z4 l'année suivante. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Mais c'est l'arrivée de l'ENIAC en 1945 qui a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, et a trait aux programmes qui peuvent être écrit pour un ordinateur. Nous ne la détaillerons pas ici. La seconde innovation est que l'ENIAC était composé non pas de relais et d'éléments mécaniques, mais uniquement de tubes à vides, des composants électroniques assez rudimentaires plus ou moins équivalents aux transistors modernes. Le ''Manchester Baby'' a introduit une innovation extrêmement importante, au point où on considère que c'est le premier ordinateur à avoir tous les critères nécessaires pour être appelé un ordinateur. Son innovation est que le programme n'était plus mémorisé sur des cartes perforée, mais dans une mémoire électronique dans l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''''Stored-program computer''''', ordinateur à programme enregistré en français. [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] Les ordinateurs qui ont suivi l'ENIAC sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les ordinateurs de première génération étaient très simples, ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, ils n'avaient pas assez de relais ou de tubes à vides à disposition pour cela. La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> qc4ygdlg6sknjrf2derri76f2nvpabk 744110 744109 2025-06-04T21:09:08Z Mewtow 31375 /* Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières */ 744110 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Ils étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les ordinateurs de première génération étaient très simples, ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, ils n'avaient pas assez de relais ou de tubes à vides à disposition pour cela. Mais c'est l'arrivée de l'ENIAC en 1945 qui a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, et a trait aux programmes qui peuvent être écrit pour un ordinateur. Nous ne la détaillerons pas ici. La seconde innovation est que l'ENIAC était composé non pas de relais et d'éléments mécaniques, mais uniquement de tubes à vides, des composants électroniques assez rudimentaires plus ou moins équivalents aux transistors modernes. Le ''Manchester Baby'' a introduit une innovation extrêmement importante, au point où on considère que c'est le premier ordinateur à avoir tous les critères nécessaires pour être appelé un ordinateur. Son innovation est que le programme n'était plus mémorisé sur des cartes perforée, mais dans une mémoire électronique dans l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''''Stored-program computer''''', ordinateur à programme enregistré en français. [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> esmvone9u7foaybfjvueoq2bv0ardel 744111 744110 2025-06-04T21:10:09Z Mewtow 31375 /* Les ordinateurs électro-mécaniques : les premiers ordinateurs */ 744111 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les ordinateurs de première génération étaient très simples, ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, ils n'avaient pas assez de relais ou de tubes à vides à disposition pour cela. Mais c'est l'arrivée de l'ENIAC en 1945 qui a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, et a trait aux programmes qui peuvent être écrit pour un ordinateur. Nous ne la détaillerons pas ici. La seconde innovation est que l'ENIAC était composé non pas de relais et d'éléments mécaniques, mais uniquement de tubes à vides, des composants électroniques assez rudimentaires plus ou moins équivalents aux transistors modernes. Le ''Manchester Baby'' a introduit une innovation extrêmement importante, au point où on considère que c'est le premier ordinateur à avoir tous les critères nécessaires pour être appelé un ordinateur. Son innovation est que le programme n'était plus mémorisé sur des cartes perforée, mais dans une mémoire électronique dans l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''''Stored-program computer''''', ordinateur à programme enregistré en français. [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 1y6u2mfmgf5zja24n2wef64qrucswxu 744112 744111 2025-06-04T21:18:03Z Mewtow 31375 /* Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières */ 744112 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les ordinateurs de première génération étaient très simples, ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, ils n'avaient pas assez de relais ou de tubes à vides à disposition pour cela. Une des toute première machine construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations. Elle était construite pour résoudre des équations différentielles linéaires, donc pour des calculs très précis. Mais c'était la première machine de calcul purement électronique. Elle utilisait une mémoire RAM construite avec des condensateurs, des circuits de calcul construits avec des tubes à vide, aucune pièce mécanique. Les nombres étaient encodés sur 50 bits. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les calculs étaient réalisés un bit à la fois dans les circuits de calcul. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2|Atanasoff–Berry.]] Mais c'est l'arrivée de l'ENIAC en 1945 qui a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, et a trait aux programmes qui peuvent être écrit pour un ordinateur. Nous ne la détaillerons pas ici. La seconde innovation est que l'ENIAC était composé non pas de relais et d'éléments mécaniques, mais uniquement de tubes à vides, des composants électroniques assez rudimentaires plus ou moins équivalents aux transistors modernes. Le ''Manchester Baby'' a introduit une innovation extrêmement importante, au point où on considère que c'est le premier ordinateur à avoir tous les critères nécessaires pour être appelé un ordinateur. Son innovation est que le programme n'était plus mémorisé sur des cartes perforée, mais dans une mémoire électronique dans l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''''Stored-program computer''''', ordinateur à programme enregistré en français. [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> dk7clw4ufxg5vm6h9ty5z104w7zyi2i 744113 744112 2025-06-04T21:18:21Z Mewtow 31375 /* Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières */ 744113 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les ordinateurs de première génération étaient très simples, ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, ils n'avaient pas assez de relais ou de tubes à vides à disposition pour cela. Une des toute première machine construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations. Elle était construite pour résoudre des équations différentielles linéaires, donc pour des calculs très précis. Mais c'était la première machine de calcul purement électronique. Elle utilisait une mémoire RAM construite avec des condensateurs, des circuits de calcul construits avec des tubes à vide, aucune pièce mécanique. Les nombres étaient encodés sur 50 bits. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les calculs étaient réalisés un bit à la fois dans les circuits de calcul. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] Mais c'est l'arrivée de l'ENIAC en 1945 qui a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, et a trait aux programmes qui peuvent être écrit pour un ordinateur. Nous ne la détaillerons pas ici. La seconde innovation est que l'ENIAC était composé non pas de relais et d'éléments mécaniques, mais uniquement de tubes à vides, des composants électroniques assez rudimentaires plus ou moins équivalents aux transistors modernes. Le ''Manchester Baby'' a introduit une innovation extrêmement importante, au point où on considère que c'est le premier ordinateur à avoir tous les critères nécessaires pour être appelé un ordinateur. Son innovation est que le programme n'était plus mémorisé sur des cartes perforée, mais dans une mémoire électronique dans l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''''Stored-program computer''''', ordinateur à programme enregistré en français. [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> ouuxzzcwk01ayaq6489eoq9htv0riqm 744114 744113 2025-06-04T21:25:19Z Mewtow 31375 /* Les premières générations : des ordinateurs qui prenaient des pièces de bâtiment entières */ 744114 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===La première génération : des ordinateurs qui prenaient des pièces de bâtiment entières=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les ordinateurs de première génération étaient très simples, ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, ils n'avaient pas assez de relais ou de tubes à vides à disposition pour cela. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. Le ''Manchester Baby'' a introduit une innovation extrêmement importante, au point où on considère que c'est le premier ordinateur à avoir tous les critères nécessaires pour être appelé un ordinateur. Son innovation est que le programme n'était plus mémorisé sur des cartes perforée, mais dans une mémoire électronique dans l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''''Stored-program computer''''', ordinateur à programme enregistré en français. [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] ===La seconde génération : le remplacement des tubes à vides par des transistors=== La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> t6ptdzor6ix8eysnq6rbclu8q4akzni 744115 744114 2025-06-04T23:22:44Z Mewtow 31375 /* La première génération : des ordinateurs qui prenaient des pièces de bâtiment entières */ 744115 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les ordinateurs de première génération étaient très simples, ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, ils n'avaient pas assez de relais ou de tubes à vides à disposition pour cela. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. Le ''Manchester Baby'' a introduit une innovation extrêmement importante, au point où on considère que c'est le premier ordinateur à avoir tous les critères nécessaires pour être appelé un ordinateur. Son innovation est que le programme n'était plus mémorisé sur des cartes perforée, mais dans une mémoire électronique dans l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''''Stored-program computer''''', ordinateur à programme enregistré en français. [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] ===La seconde génération : le remplacement des tubes à vides par des transistors=== La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> pl7cnkh9tunsubzcjwyxersmm7n6uks 744116 744115 2025-06-04T23:49:25Z Mewtow 31375 /* La première génération : les tubes à vide */ 744116 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===La première génération : les tubes à vide=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les ordinateurs de première génération étaient très simples, ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, ils n'avaient pas assez de relais ou de tubes à vides à disposition pour cela. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante, au point où on considère que c'est le premier ordinateur à avoir tous les critères nécessaires pour être appelé un ordinateur. Son innovation est que le programme n'était plus mémorisé sur des cartes perforée, mais dans une mémoire électronique dans l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''''Stored-program computer''''', ordinateur à programme enregistré en français. Le Manchester Baby avait une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Willimas (abordés dans une annexe à la fin du cours). Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, mais rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. ===La seconde génération : le remplacement des tubes à vides par des transistors=== La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> rfmlhd1k2kdds7yr238oo52ag6zn0jg 744117 744116 2025-06-04T23:49:33Z Mewtow 31375 /* La première génération : les tubes à vide */ 744117 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les ordinateurs de première génération étaient très simples, ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, ils n'avaient pas assez de relais ou de tubes à vides à disposition pour cela. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante, au point où on considère que c'est le premier ordinateur à avoir tous les critères nécessaires pour être appelé un ordinateur. Son innovation est que le programme n'était plus mémorisé sur des cartes perforée, mais dans une mémoire électronique dans l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''''Stored-program computer''''', ordinateur à programme enregistré en français. Le Manchester Baby avait une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Willimas (abordés dans une annexe à la fin du cours). Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, mais rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. ===La seconde génération : le remplacement des tubes à vides par des transistors=== La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 5bstp4bl48f1suqtfmn8r8j10bucuvn 744118 744117 2025-06-04T23:49:40Z Mewtow 31375 /* La seconde génération : le remplacement des tubes à vides par des transistors */ 744118 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les ordinateurs de première génération étaient très simples, ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, ils n'avaient pas assez de relais ou de tubes à vides à disposition pour cela. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante, au point où on considère que c'est le premier ordinateur à avoir tous les critères nécessaires pour être appelé un ordinateur. Son innovation est que le programme n'était plus mémorisé sur des cartes perforée, mais dans une mémoire électronique dans l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''''Stored-program computer''''', ordinateur à programme enregistré en français. Le Manchester Baby avait une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Willimas (abordés dans une annexe à la fin du cours). Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, mais rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 73y7kymhk7r9xu17y6zpdc0hg8o1hof 744119 744118 2025-06-04T23:51:54Z Mewtow 31375 /* La première génération : les tubes à vide */ 744119 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, surtout quand on sait que les ordinateurs de l'époque étaient composé de plusieurs milliers de ces tubes. Aussi, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. Et surtout, les tubes à vide consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simple à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Les ordinateurs de première génération étaient très simples, ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, ils n'avaient pas assez de relais ou de tubes à vides à disposition pour cela. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante, au point où on considère que c'est le premier ordinateur à avoir tous les critères nécessaires pour être appelé un ordinateur. Son innovation est que le programme n'était plus mémorisé sur des cartes perforée, mais dans une mémoire électronique dans l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''''Stored-program computer''''', ordinateur à programme enregistré en français. Le Manchester Baby avait une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Willimas (abordés dans une annexe à la fin du cours). Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, mais rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 6j9v78zf2smuaj1mkewss2508sb2hps 744120 744119 2025-06-04T23:56:02Z Mewtow 31375 /* La première génération : les tubes à vide */ 744120 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simple à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de de la taille des tubes à vide, les ordinateurs de l'époque étaient composé de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante, au point où on considère que c'est le premier ordinateur à avoir tous les critères nécessaires pour être appelé un ordinateur. Son innovation est que le programme n'était plus mémorisé sur des cartes perforée, mais dans une mémoire électronique dans l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''''Stored-program computer''''', ordinateur à programme enregistré en français. Le Manchester Baby avait une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Willimas (abordés dans une annexe à la fin du cours). Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, mais rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 3c5ofvrq7d5mfb97yd36p51bm44p7nv 744121 744120 2025-06-04T23:57:17Z Mewtow 31375 /* La première génération : les tubes à vide */ 744121 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simple à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de de la taille des tubes à vide, les ordinateurs de l'époque étaient composé de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme enregistré''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Il avait une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Willimas (abordés dans une annexe à la fin du cours). Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, mais rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> tbu1fpun59u3h23rh9axdur57hyor1f 744122 744121 2025-06-04T23:57:47Z Mewtow 31375 /* La première génération : les tubes à vide */ 744122 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simple à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de de la taille des tubes à vide, les ordinateurs de l'époque étaient composé de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Il avait une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Willimas (abordés dans une annexe à la fin du cours). Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, mais rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> exq4gh46e2zivxqi50z6r1tihffw07s 744123 744122 2025-06-05T00:00:25Z Mewtow 31375 /* La première génération : les tubes à vide */ 744123 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simple à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de de la taille des tubes à vide, les ordinateurs de l'époque étaient composé de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Il avait une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Willimas (abordés dans une annexe à la fin du cours). Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, mais rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. C'était une architecture avec un registre unique, appelé l'accumulateur, avec une instruction STORE pour copier son contenu en RAM et une instruction LOAD pour copier du nombre de la RAM vers l'accumulateur. Les instructions étaient chargées dans un registre pour être exécutées, le processeur avait aussi un registre pour mémoriser la position de l'instruction suivante en RAM. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> olx48xn316yj31ou592ymgk5svvcj28 744124 744123 2025-06-05T00:05:27Z Mewtow 31375 /* La première génération : les tubes à vide */ 744124 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simple à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de de la taille des tubes à vide, les ordinateurs de l'époque étaient composé de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Le programme devait tenir dans la RAM, avec une instruction prenant autant de place qu'un nombre, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 servait à indiquer où se trouvent les opérandes en RAM, les 16 restants sont inutilisés. Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, mais rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. C'était une architecture avec un registre unique, appelé l'accumulateur, avec une instruction STORE pour copier son contenu en RAM et une instruction LOAD pour copier du nombre de la RAM vers l'accumulateur. Les instructions étaient chargées dans un registre pour être exécutées, le processeur avait aussi un registre pour mémoriser la position de l'instruction suivante en RAM. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> sh5imug70k1nhsljbpyqhjv4mndjh7c 744125 744124 2025-06-05T00:06:07Z Mewtow 31375 /* La première génération : les tubes à vide */ 744125 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simple à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de de la taille des tubes à vide, les ordinateurs de l'époque étaient composé de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Le programme devait tenir dans la RAM, avec une instruction prenant autant de place qu'un nombre, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 servait à indiquer où se trouvent les opérandes en RAM, les 16 restants sont inutilisés. Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, mais rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. C'était une architecture avec un registre unique de 32 bits, appelé l'accumulateur, avec une instruction STORE pour copier son contenu en RAM et une instruction LOAD pour copier du nombre de la RAM vers l'accumulateur. Les instructions étaient chargées dans un registre pour être exécutées, le processeur avait aussi un registre pour mémoriser la position de l'instruction suivante en RAM. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 3hjaevnmffac5d556i0ml29nih79ggz 744126 744125 2025-06-05T00:10:24Z Mewtow 31375 /* La première génération : les tubes à vide */ 744126 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simple à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de de la taille des tubes à vide, les ordinateurs de l'époque étaient composé de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Le programme devait tenir dans la RAM, avec une instruction prenant autant de place qu'un nombre, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 servait à indiquer où se trouvent les opérandes en RAM, les 16 restants sont inutilisés. Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, mais rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. C'était une architecture avec un registre unique de 32 bits, appelé l'accumulateur, avec une instruction STORE pour copier son contenu en RAM et une instruction LOAD pour copier du nombre de la RAM vers l'accumulateur. Les instructions étaient chargées dans un registre pour être exécutées, le processeur avait aussi un registre pour mémoriser la position de l'instruction suivante en RAM. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, les instructions étaient codées sur 20 bits. La RAM était toujours composée de 32 nombres, leur taille était simplement augmentée. Par contre, elle était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, faisant chacune 32 nombres de 40 bits. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> tdmx3caxb12lhxqmkcte9dnjbr26c4r 744127 744126 2025-06-05T00:13:49Z Mewtow 31375 /* La première génération : les tubes à vide */ 744127 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simple à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de de la taille des tubes à vide, les ordinateurs de l'époque étaient composé de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Le programme devait tenir dans la RAM, avec une instruction prenant autant de place qu'un nombre, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 servait à indiquer où se trouvent les opérandes en RAM, les 16 restants sont inutilisés. Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, mais rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. C'était une architecture avec un registre unique de 32 bits, appelé l'accumulateur, avec une instruction STORE pour copier son contenu en RAM et une instruction LOAD pour copier du nombre de la RAM vers l'accumulateur. Les instructions étaient chargées dans un registre pour être exécutées, le processeur avait aussi un registre pour mémoriser la position de l'instruction suivante en RAM. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, les instructions étaient codées sur 20 bits. La RAM était toujours composée de 32 nombres, leur taille était simplement augmentée. Par contre, elle était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, faisant chacune 32 nombres de 40 bits. C'était là encore une architecture à accumulateur, elle intégrait aussi des registres d'indice. Et surtout : son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. [[File:MM1Schematic French.svg|centre|vignette|upright=2.5|Architecture de la Manchester Mark 1.]] ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> hzau4c69s3ibjlwftntxfzak7yt1kd0 744128 744127 2025-06-05T00:17:29Z Mewtow 31375 /* La première génération : les tubes à vide */ 744128 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simple à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de de la taille des tubes à vide, les ordinateurs de l'époque étaient composé de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Le programme devait tenir dans la RAM, avec une instruction prenant autant de place qu'un nombre, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 servait à indiquer où se trouvent les opérandes en RAM, les 16 restants sont inutilisés. Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, mais rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. C'était une architecture avec un registre unique de 32 bits, appelé l'accumulateur, avec une instruction STORE pour copier son contenu en RAM et une instruction LOAD pour copier du nombre de la RAM vers l'accumulateur. Les instructions étaient chargées dans un registre pour être exécutées, le processeur avait aussi un registre pour mémoriser la position de l'instruction suivante en RAM. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, les instructions étaient codées sur 20 bits. La RAM était toujours composée de 32 nombres, leur taille était simplement augmentée. Par contre, elle était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, faisant chacune 32 nombres de 40 bits. C'était là encore une architecture à accumulateur, elle intégrait aussi des registres d'indice. Et surtout : son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. [[File:MM1Schematic French.svg|centre|vignette|upright=2.5|Architecture de la Manchester Mark 1.]] Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> mwglx04a5hy3odgjsavgin70kwnssi7 744129 744128 2025-06-05T00:22:44Z Mewtow 31375 /* La première génération : les tubes à vide */ 744129 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simple à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de de la taille des tubes à vide, les ordinateurs de l'époque étaient composé de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Le programme devait tenir dans la RAM, avec une instruction prenant autant de place qu'un nombre, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 servait à indiquer où se trouvent les opérandes en RAM, les 16 restants sont inutilisés. Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, mais rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. C'était une architecture avec un registre unique de 32 bits, appelé l'accumulateur, avec une instruction STORE pour copier son contenu en RAM et une instruction LOAD pour copier du nombre de la RAM vers l'accumulateur. Les instructions étaient chargées dans un registre pour être exécutées, le processeur avait aussi un registre pour mémoriser la position de l'instruction suivante en RAM. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, les instructions étaient codées sur 20 bits. La RAM était toujours composée de 32 nombres, leur taille était simplement augmentée. Par contre, elle était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, faisant chacune 32 nombres de 40 bits. C'était là encore une architecture à accumulateur, elle intégrait aussi des registres d'indice. Et surtout : son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. [[File:MM1Schematic French.svg|centre|vignette|upright=2.5|Architecture de la Manchester Mark 1.]] Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> lnbwgcmwthhgsd8khvznl4e1marsntc 744130 744129 2025-06-05T00:23:58Z Mewtow 31375 /* La première génération : les tubes à vide */ 744130 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simple à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de de la taille des tubes à vide, les ordinateurs de l'époque étaient composé de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Le programme devait tenir dans la RAM, avec une instruction prenant autant de place qu'un nombre, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 servait à indiquer où se trouvent les opérandes en RAM, les 16 restants sont inutilisés. Le processeur avait un registre unique de 32 bits, appelé l'accumulateur. Pour gérer l'accumulateur, il avait une instruction STORE pour copier son contenu en RAM et une instruction LOAD pour copier du nombre de la RAM vers l'accumulateur. Les instructions étaient chargées dans un registre d'instruction pour être exécutées, le processeur avait aussi un registre pour mémoriser la position de l'instruction suivante en RAM. Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, mais rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, les instructions étaient codées sur 20 bits. La RAM était toujours composée de 32 nombres, leur taille était simplement augmentée. Par contre, elle était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, faisant chacune 32 nombres de 40 bits. C'était là encore une architecture à accumulateur, elle intégrait aussi des registres d'indice. Et surtout : son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. [[File:MM1Schematic French.svg|centre|vignette|upright=2.5|Architecture de la Manchester Mark 1.]] Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> f91ql4v28q5ie7267l7v63qxawnjsdr 744131 744130 2025-06-05T00:29:01Z Mewtow 31375 /* La première génération : les tubes à vide */ 744131 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simple à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de de la taille des tubes à vide, les ordinateurs de l'époque étaient composé de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Le programme devait tenir dans la RAM, avec une instruction prenant autant de place qu'un nombre, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, mais rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, les instructions étaient codées sur 20 bits. La RAM était toujours composée de 32 nombres, leur taille était simplement augmentée. Par contre, elle était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, faisant chacune 32 nombres de 40 bits. C'était là encore une architecture à accumulateur, elle intégrait aussi des registres d'indice. Et surtout : son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. [[File:MM1Schematic French.svg|centre|vignette|upright=2.5|Architecture de la Manchester Mark 1.]] Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> m4b7m5cmn8l1lky27oqluha19apwlpp 744135 744131 2025-06-05T00:33:30Z Mewtow 31375 /* La première génération : les tubes à vide */ 744135 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simple à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de de la taille des tubes à vide, les ordinateurs de l'époque étaient composé de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. [[File:MM1Schematic French.svg|centre|vignette|upright=2.5|Architecture de la Manchester Mark 1.]] Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> aj4qnxthtqvfiae6oag69gwdwc96eva 744138 744135 2025-06-05T00:34:29Z Mewtow 31375 /* La première génération : les tubes à vide */ 744138 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteur programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grandes noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servis pour les cryptanalystes pour casser les codes utilisés par les allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit.. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simple à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de de la taille des tubes à vide, les ordinateurs de l'époque étaient composé de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand chose de plus. A quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffre, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient fait chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont finit par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièce détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passé au milliers de transistors, puis au millions et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors était miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> kjthz6twxty9jy27mzllwa4qntd0ci4 744142 744138 2025-06-05T00:44:05Z Mewtow 31375 /* Les générations d'ordinateurs : un historique rapide */ 744142 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d'instructions, chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, la majorité de ces instructions effectuent une opération arithmétique, comme une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Une instruction est représentée dans un ordinateur par une série de nombres : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grands noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> krr1qhs0tc9ch5ex5gx2owdu5kxt08l 744145 744142 2025-06-05T11:49:16Z Mewtow 31375 /* Un ordinateur est un appareil programmable */ 744145 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grands noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 8a8wurewyp5on2dahmakp4ur93esu2d 744146 744145 2025-06-05T11:49:53Z Mewtow 31375 /* Les ordinateurs électro-mécaniques : les premiers ordinateurs */ 744146 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, on utilisait des cartes perforées en plastique, sur lesquelles on inscrivait le programme à exécuter, les données à traiter, bref : tout ce qu'on donnait à manger à l'ordinateur. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grands noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> lfnf2mtk6b0x714wzo55y6l8l9i35sb 744147 744146 2025-06-05T11:57:06Z Mewtow 31375 /* Les ordinateurs à programme mémorisé ou programme externe */ 744147 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique percées par endroits. Un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grands noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> fc3v3eqcz40by0dzalp53zh99llu1h3 744148 744147 2025-06-05T11:57:17Z Mewtow 31375 /* Les ordinateurs à programme mémorisé ou programme externe */ 744148 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique percées par endroits. Un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique. Les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grands noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 169nvf2yv8ux5qngiz6if51t8jl0k68 744149 744148 2025-06-05T11:57:38Z Mewtow 31375 /* Les ordinateurs électro-mécaniques : les premiers ordinateurs */ 744149 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== Au tout début de l'informatique, les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique percées par endroits. Un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique et précisémment sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grands noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 3u0r267jmf3ogp3q1jscn42c92m1udt 744150 744149 2025-06-05T11:57:47Z Mewtow 31375 /* Les ordinateurs à programme mémorisé ou programme externe */ 744150 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Au tout début de l'informatique, les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique percées par endroits. Un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique et précisémment sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, de nombreux ordinateurs ont été construits dans des laboratoires de recherche. Des grands noms de l'histoire de l'informatique datent de cette époque : le Harvard Mark I et le Colossus Mark 1 (UK) ont tous deux été mis en service en 1944, par exemple. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 5pwnqmhwsgavm5eimca5toyjntvf5ru 744151 744150 2025-06-05T12:05:33Z Mewtow 31375 /* Les ordinateurs électro-mécaniques : les premiers ordinateurs */ 744151 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Au tout début de l'informatique, les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique percées par endroits. Un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique et précisémment sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, quelques laboratoires de recherche ont fabriqués des ordinateurs dans leur coin, comme le Harvard Mark I et le Colossus Mark 1 (UK) qui ont été mis en service en 1944. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient soit des relais, soit des tubes à vides, les deux étant des interrupteurs commandables électriquement plus ou moins équivalents aux transistors. Les ordinateurs d'avant l'année 1944, étaient tous de ce type. Quelques ordinateurs des années 50 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> fi2ktmq7j3xs7pe97gc8upaiql9od3w 744152 744151 2025-06-05T12:07:01Z Mewtow 31375 /* Les ordinateurs électro-mécaniques : les premiers ordinateurs */ 744152 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Au tout début de l'informatique, les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique percées par endroits. Un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique et précisémment sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, quelques laboratoires de recherche ont fabriqués des ordinateurs dans leur coin, comme le Harvard Mark I et le Colossus Mark 1 (UK) qui ont été mis en service en 1944. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient généralement des relais, à savoir des interrupteurs commandables électriquement, qui sont plus ou moins équivalents aux transistors modernes. La majeure partie des ordinateurs des années 40 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, ce qui les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 2452c26i1wcfdmpa9b5cvzmckh3ah9g 744153 744152 2025-06-05T12:08:37Z Mewtow 31375 /* La première génération : les tubes à vide */ 744153 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Au tout début de l'informatique, les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique percées par endroits. Un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique et précisémment sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, quelques laboratoires de recherche ont fabriqués des ordinateurs dans leur coin, comme le Harvard Mark I et le Colossus Mark 1 (UK) qui ont été mis en service en 1944. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient généralement des relais, à savoir des interrupteurs commandables électriquement, qui sont plus ou moins équivalents aux transistors modernes. La majeure partie des ordinateurs des années 40 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, des espèces d'interrupteurs commandables, les ancêtres des transistors modernes. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] L'usage de tubes à vide les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> k8qicxk26kcfr1js1be759w6p5kphrw 744161 744153 2025-06-05T14:35:17Z Mewtow 31375 /* La première génération : les tubes à vide */ 744161 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Au tout début de l'informatique, les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique percées par endroits. Un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique et précisémment sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, quelques laboratoires de recherche ont fabriqués des ordinateurs dans leur coin, comme le Harvard Mark I et le Colossus Mark 1 (UK) qui ont été mis en service en 1944. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient généralement des relais, à savoir des interrupteurs commandables électriquement, qui sont plus ou moins équivalents aux transistors modernes. La majeure partie des ordinateurs des années 40 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, des espèces d'interrupteurs commandables, les ancêtres des transistors modernes. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] L'usage de tubes à vide les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition. Les multiplications étaient réalisées par des additions successives, mais le processeur intégrait des registres pour mémoriser les opérandes à multiplier. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 2naw81yydt3l8anajqihf7csne6ay87 744162 744161 2025-06-05T15:11:49Z Mewtow 31375 /* La première génération : les tubes à vide */ 744162 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Au tout début de l'informatique, les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique percées par endroits. Un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique et précisémment sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, quelques laboratoires de recherche ont fabriqués des ordinateurs dans leur coin, comme le Harvard Mark I et le Colossus Mark 1 (UK) qui ont été mis en service en 1944. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient généralement des relais, à savoir des interrupteurs commandables électriquement, qui sont plus ou moins équivalents aux transistors modernes. La majeure partie des ordinateurs des années 40 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, des espèces d'interrupteurs commandables, les ancêtres des transistors modernes. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. Les tubes à vides étaient utilisés pour le processeur et quelques circuits annexes, mais les mémoires utilisaient d'autres technologies. Les mémoires de l'époque n'étaient pas du tout des mémoires électroniques. Il existait déjà des ancêtres des disques durs, à savoir des mémoire magnétiques appelées tambours magnétiques, bandes magnétiques, mémoires à tore de ferrite, etc. Les mémoires RAM, quant à elles, utilisaient elles des technologies totalement abandonnées : les mémoires à lignes de délai étaient des mémoires acoustiques, les tubes Williams étaient des écrans CRT modifiés, etc. Un chapitre entier sera dédié aux technologies des mémoires de l'époque. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] L'usage de tubes à vide les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition. Les multiplications étaient réalisées par des additions successives, mais le processeur intégrait des registres pour mémoriser les opérandes à multiplier. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Transistors comme tubes à vide prenaient beaucoup de place, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> os0cuco7xo0fudoyuuzvua93r1al2a3 744163 744162 2025-06-05T15:17:12Z Mewtow 31375 /* La seconde génération : le remplacement des tubes à vides par des transistors */ 744163 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Au tout début de l'informatique, les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique percées par endroits. Un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique et précisémment sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, quelques laboratoires de recherche ont fabriqués des ordinateurs dans leur coin, comme le Harvard Mark I et le Colossus Mark 1 (UK) qui ont été mis en service en 1944. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient généralement des relais, à savoir des interrupteurs commandables électriquement, qui sont plus ou moins équivalents aux transistors modernes. La majeure partie des ordinateurs des années 40 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, des espèces d'interrupteurs commandables, les ancêtres des transistors modernes. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. Les tubes à vides étaient utilisés pour le processeur et quelques circuits annexes, mais les mémoires utilisaient d'autres technologies. Les mémoires de l'époque n'étaient pas du tout des mémoires électroniques. Il existait déjà des ancêtres des disques durs, à savoir des mémoire magnétiques appelées tambours magnétiques, bandes magnétiques, mémoires à tore de ferrite, etc. Les mémoires RAM, quant à elles, utilisaient elles des technologies totalement abandonnées : les mémoires à lignes de délai étaient des mémoires acoustiques, les tubes Williams étaient des écrans CRT modifiés, etc. Un chapitre entier sera dédié aux technologies des mémoires de l'époque. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] L'usage de tubes à vide les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition. Les multiplications étaient réalisées par des additions successives, mais le processeur intégrait des registres pour mémoriser les opérandes à multiplier. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Les transistors étaient au départ de la même taille que les tubes à vide, mais ils ont rapidement rétrécit. Ils prenaient encore beaucoup de place dans les 60-70, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> fy2b6laufhnhkqjqmiovcw8aenezh6q 744165 744163 2025-06-05T15:28:27Z Mewtow 31375 /* La première génération : les tubes à vide */ 744165 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Au tout début de l'informatique, les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique percées par endroits. Un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique et précisémment sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, quelques laboratoires de recherche ont fabriqués des ordinateurs dans leur coin, comme le Harvard Mark I et le Colossus Mark 1 (UK) qui ont été mis en service en 1944. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient généralement des relais, à savoir des interrupteurs commandables électriquement, qui sont plus ou moins équivalents aux transistors modernes. La majeure partie des ordinateurs des années 40 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, des espèces d'interrupteurs commandables, les ancêtres des transistors modernes. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. Les tubes à vide sont des ampoules à filament améliorées. Pour rappel, les ampoules à filament étaient des ampoules en verre dans lesquelles on plaçait un filament métallique. Le filament chauffait quand on envoyait du courant dedans et émettait de la lumière. Mais dans les tubes à vide, le filament n'émet pas de lumière quand on le chauffe : il émet des électrons, de l'électricité. De plus, ils ajoutent une électrode, une plaque en métal qui émet ou capte des électrons. Ici, l'électrode capte des électrons émis par le filament quand il chauffe. Vu qu'elle capte des électrons, on l'appelle l''''anode'''. Le résultat est un circuit qui laisse passer le courant, mais seulement dans un sens : du filament vers l'anode, l'autre sens n'est pas possible vu que l'anode ne peut pas émettre d'électrons. Un tel circuit est appelé une '''diode'''. {| |[[File:Diode vide schema explicatif.png|vignette|upright=1.5|Tube à vide basique.]] |[[File:Diode à vide schéma de fonctionnement.png|vignette|upright=1.5|Diode à vide, schéma de fonctionnement]] |} [[File:Diode à vide.png|vignette|Diode à vide]] Une amélioration des tubes à vide précédent rajoute une seconde plaque de métal, appelée la '''cathode'''. Elle est située juste après le filament. C'est elle qui émet les électrons, non pas le filament. Cependant, elle n'émet des électrons que si elle est chauffée par le filament. Le filament doit donc chauffer, ce qui réchauffe la cathode, qui elle-même émet des électrons en direction de l'anode. Les tubes à vides étaient utilisés pour le processeur et quelques circuits annexes, mais les mémoires utilisaient d'autres technologies. Les mémoires de l'époque n'étaient pas du tout des mémoires électroniques. Il existait déjà des ancêtres des disques durs, à savoir des mémoire magnétiques appelées tambours magnétiques, bandes magnétiques, mémoires à tore de ferrite, etc. Les mémoires RAM, quant à elles, utilisaient elles des technologies totalement abandonnées : les mémoires à lignes de délai étaient des mémoires acoustiques, les tubes Williams étaient des écrans CRT modifiés, etc. Un chapitre entier sera dédié aux technologies des mémoires de l'époque. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] L'usage de tubes à vide les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition. Les multiplications étaient réalisées par des additions successives, mais le processeur intégrait des registres pour mémoriser les opérandes à multiplier. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Les transistors étaient au départ de la même taille que les tubes à vide, mais ils ont rapidement rétrécit. Ils prenaient encore beaucoup de place dans les 60-70, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> k84mj0kgzngoegspgqxsb3yb1xmbsoy 744166 744165 2025-06-05T15:29:11Z Mewtow 31375 /* La première génération : les tubes à vide */ 744166 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Au tout début de l'informatique, les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique percées par endroits. Un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique et précisémment sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, quelques laboratoires de recherche ont fabriqués des ordinateurs dans leur coin, comme le Harvard Mark I et le Colossus Mark 1 (UK) qui ont été mis en service en 1944. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient généralement des relais, à savoir des interrupteurs commandables électriquement, qui sont plus ou moins équivalents aux transistors modernes. La majeure partie des ordinateurs des années 40 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, des espèces d'interrupteurs commandables, les ancêtres des transistors modernes. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. Les tubes à vide sont des ampoules à filament améliorées. Pour rappel, les ampoules à filament étaient des ampoules en verre dans lesquelles on plaçait un filament métallique. Le filament chauffait quand on envoyait du courant dedans et émettait de la lumière. Mais dans les tubes à vide, le filament n'émet pas de lumière quand on le chauffe : il émet des électrons, de l'électricité. De plus, ils ajoutent une électrode, une plaque en métal qui émet ou capte des électrons. Ici, l'électrode capte des électrons émis par le filament quand il chauffe. Vu qu'elle capte des électrons, on l'appelle l''''anode'''. Le résultat est un circuit qui laisse passer le courant, mais seulement dans un sens : du filament vers l'anode, l'autre sens n'est pas possible vu que l'anode ne peut pas émettre d'électrons. Un tel circuit est appelé une '''diode'''. {| |[[File:Diode vide schema explicatif.png|vignette|upright=1.5|Tube à vide basique.]] |[[File:Diode à vide schéma de fonctionnement.png|vignette|upright=1.5|Diode à vide, schéma de fonctionnement.]] |} Une amélioration des tubes à vide précédent rajoute une seconde plaque de métal, appelée la '''cathode'''. Elle est située juste après le filament. C'est elle qui émet les électrons, non pas le filament. Cependant, elle n'émet des électrons que si elle est chauffée par le filament. Le filament doit donc chauffer, ce qui réchauffe la cathode, qui elle-même émet des électrons en direction de l'anode. {| |[[File:Diode à vide.png|vignette|upright=1.5|Diode à vide, avec cathode.]] |[[File:Vacuum tubes (multilingual).svg|vignette|upright=1.5|Diode à vide avec cathode, schéma de fonctionnement.]] |} Les tubes à vides étaient utilisés pour le processeur et quelques circuits annexes, mais les mémoires utilisaient d'autres technologies. Les mémoires de l'époque n'étaient pas du tout des mémoires électroniques. Il existait déjà des ancêtres des disques durs, à savoir des mémoire magnétiques appelées tambours magnétiques, bandes magnétiques, mémoires à tore de ferrite, etc. Les mémoires RAM, quant à elles, utilisaient elles des technologies totalement abandonnées : les mémoires à lignes de délai étaient des mémoires acoustiques, les tubes Williams étaient des écrans CRT modifiés, etc. Un chapitre entier sera dédié aux technologies des mémoires de l'époque. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] L'usage de tubes à vide les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition. Les multiplications étaient réalisées par des additions successives, mais le processeur intégrait des registres pour mémoriser les opérandes à multiplier. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Les transistors étaient au départ de la même taille que les tubes à vide, mais ils ont rapidement rétrécit. Ils prenaient encore beaucoup de place dans les 60-70, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 1lhtwfhvk3fl7482qmnphab9jbpul6c 744167 744166 2025-06-05T15:29:58Z Mewtow 31375 /* La première génération : les tubes à vide */ 744167 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Au tout début de l'informatique, les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique percées par endroits. Un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique et précisémment sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, quelques laboratoires de recherche ont fabriqués des ordinateurs dans leur coin, comme le Harvard Mark I et le Colossus Mark 1 (UK) qui ont été mis en service en 1944. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient généralement des relais, à savoir des interrupteurs commandables électriquement, qui sont plus ou moins équivalents aux transistors modernes. La majeure partie des ordinateurs des années 40 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, des espèces d'interrupteurs commandables, les ancêtres des transistors modernes. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. Les tubes à vide sont des ampoules à filament améliorées. Pour rappel, les ampoules à filament étaient des ampoules en verre dans lesquelles on plaçait un filament métallique. Le filament chauffait quand on envoyait du courant dedans et émettait de la lumière. Mais dans les tubes à vide, le filament n'émet pas de lumière quand on le chauffe : il émet des électrons, de l'électricité. De plus, ils ajoutent une électrode, une plaque en métal qui émet ou capte des électrons. Ici, l'électrode capte des électrons émis par le filament quand il chauffe. Vu qu'elle capte des électrons, on l'appelle l''''anode'''. Le résultat est un circuit qui laisse passer le courant, mais seulement dans un sens : du filament vers l'anode, l'autre sens n'est pas possible vu que l'anode ne peut pas émettre d'électrons. Un tel circuit est appelé une '''diode'''. {| |[[File:Diode vide schema explicatif.png|vignette|upright=1.5|Tube à vide basique.]] |[[File:Diode à vide schéma de fonctionnement.png|vignette|upright=1.5|Diode à vide, schéma de fonctionnement. Le filament X chauffe la cathode (2), qui émet des électrons (3), vers l'anode (4).]] |} Une amélioration des tubes à vide précédent rajoute une seconde plaque de métal, appelée la '''cathode'''. Elle est située juste après le filament. C'est elle qui émet les électrons, non pas le filament. Cependant, elle n'émet des électrons que si elle est chauffée par le filament. Le filament doit donc chauffer, ce qui réchauffe la cathode, qui elle-même émet des électrons en direction de l'anode. {| |[[File:Diode à vide.png|vignette|upright=1.5|Diode à vide, avec cathode.]] |[[File:Vacuum tubes (multilingual).svg|vignette|upright=1.5|Diode à vide avec cathode, schéma de fonctionnement.]] |} Les tubes à vides étaient utilisés pour le processeur et quelques circuits annexes, mais les mémoires utilisaient d'autres technologies. Les mémoires de l'époque n'étaient pas du tout des mémoires électroniques. Il existait déjà des ancêtres des disques durs, à savoir des mémoire magnétiques appelées tambours magnétiques, bandes magnétiques, mémoires à tore de ferrite, etc. Les mémoires RAM, quant à elles, utilisaient elles des technologies totalement abandonnées : les mémoires à lignes de délai étaient des mémoires acoustiques, les tubes Williams étaient des écrans CRT modifiés, etc. Un chapitre entier sera dédié aux technologies des mémoires de l'époque. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] L'usage de tubes à vide les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition. Les multiplications étaient réalisées par des additions successives, mais le processeur intégrait des registres pour mémoriser les opérandes à multiplier. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Les transistors étaient au départ de la même taille que les tubes à vide, mais ils ont rapidement rétrécit. Ils prenaient encore beaucoup de place dans les 60-70, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 1i9p8rx97v4wdh2u8grpre5xf880egc 744168 744167 2025-06-05T15:40:04Z Mewtow 31375 /* La première génération : les tubes à vide */ 744168 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Au tout début de l'informatique, les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique percées par endroits. Un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique et précisémment sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, quelques laboratoires de recherche ont fabriqués des ordinateurs dans leur coin, comme le Harvard Mark I et le Colossus Mark 1 (UK) qui ont été mis en service en 1944. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient généralement des relais, à savoir des interrupteurs commandables électriquement, qui sont plus ou moins équivalents aux transistors modernes. La majeure partie des ordinateurs des années 40 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, des espèces d'interrupteurs commandables, les ancêtres des transistors modernes. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. Les tubes à vide sont des ampoules à filament améliorées. Pour rappel, les ampoules à filament étaient des ampoules en verre dans lesquelles on plaçait un filament métallique. Le filament chauffait quand on envoyait du courant dedans et émettait de la lumière. Mais dans les tubes à vide, le filament n'émet pas de lumière quand on le chauffe : il émet des électrons, de l'électricité. De plus, ils ajoutent une électrode, une plaque en métal qui émet ou capte des électrons. Ici, l'électrode capte des électrons émis par le filament quand il chauffe. Vu qu'elle capte des électrons, on l'appelle l''''anode'''. Le résultat est un circuit qui laisse passer le courant, mais seulement dans un sens : du filament vers l'anode, l'autre sens n'est pas possible vu que l'anode ne peut pas émettre d'électrons. Un tel circuit est appelé une '''diode'''. Une amélioration des tubes à vide précédent rajoute une seconde plaque de métal, appelée la '''cathode''', située juste après le filament. C'est elle qui émet les électrons, , mais seulement si elle est chauffée par le filament. Le filament doit donc chauffer, ce qui réchauffe la cathode, qui elle-même émet des électrons en direction de l'anode. {| |[[File:Diode à vide.png|vignette|upright=1.5|Diode à vide, avec cathode.]] |[[File:Diode à vide schéma de fonctionnement.png|vignette|upright=1.5|Diode à vide, schéma de fonctionnement. Le filament X chauffe la cathode (2), qui émet des électrons (3), vers l'anode (4).]] |} Les tubes à vide précédent peuvent être modifiés en ajoutant une grille métallique entre la cathode et l'anode. La grille est alimentée avec une tension électrique, ce qui la charge électriquement. Suivant sa charge, elle laisse plus ou moins passer les électrons de la cathode vers l'anode. Si elle n'est pas chargée, que la tension est de 0 Volts, elle ne fera pas obstacle aux électrons et le tube à vide fonctionnera comme une diode basique. Mais si la grille est chargée avec une tension négative, sa charge électrique va repousser les électrons et les empêcher de passer de la cathode vers l'anode. Le tube à vide se comportera alors comme un interrupteur : fermé ou ouvert suivant ce qu'on met sur la grille. De tels interrupteurs commandables électriquement sont combinés pour fabriquer des circuits plus élaborés, comme les portes logiques qu'on verra d'ici quelques chapitres. Les tubes à vides étaient utilisés pour le processeur et quelques circuits annexes, mais les mémoires utilisaient d'autres technologies. Les mémoires de l'époque n'étaient pas du tout des mémoires électroniques. Il existait déjà des ancêtres des disques durs, à savoir des mémoire magnétiques appelées tambours magnétiques, bandes magnétiques, mémoires à tore de ferrite, etc. Les mémoires RAM, quant à elles, utilisaient elles des technologies totalement abandonnées : les mémoires à lignes de délai étaient des mémoires acoustiques, les tubes Williams étaient des écrans CRT modifiés, etc. Un chapitre entier sera dédié aux technologies des mémoires de l'époque. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] L'usage de tubes à vide les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition. Les multiplications étaient réalisées par des additions successives, mais le processeur intégrait des registres pour mémoriser les opérandes à multiplier. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Les transistors étaient au départ de la même taille que les tubes à vide, mais ils ont rapidement rétrécit. Ils prenaient encore beaucoup de place dans les 60-70, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 45p6l328e2vj7isj23c1pr9hvkm5j23 744169 744168 2025-06-05T15:40:38Z Mewtow 31375 /* La première génération : les tubes à vide */ 744169 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Au tout début de l'informatique, les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique percées par endroits. Un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique et précisémment sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, quelques laboratoires de recherche ont fabriqués des ordinateurs dans leur coin, comme le Harvard Mark I et le Colossus Mark 1 (UK) qui ont été mis en service en 1944. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient généralement des relais, à savoir des interrupteurs commandables électriquement, qui sont plus ou moins équivalents aux transistors modernes. La majeure partie des ordinateurs des années 40 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, des espèces d'interrupteurs commandables, les ancêtres des transistors modernes. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. Les tubes à vide sont des ampoules à filament améliorées. Pour rappel, les ampoules à filament étaient des ampoules en verre dans lesquelles on plaçait un filament métallique. Le filament chauffait quand on envoyait du courant dedans et émettait de la lumière. Mais dans les tubes à vide, le filament n'émet pas de lumière quand on le chauffe : il émet des électrons, de l'électricité. De plus, ils ajoutent une électrode, une plaque en métal qui émet ou capte des électrons. Ici, l'électrode capte des électrons émis par le filament quand il chauffe. Vu qu'elle capte des électrons, on l'appelle l''''anode'''. Le résultat est un circuit qui laisse passer le courant, mais seulement dans un sens : du filament vers l'anode, l'autre sens n'est pas possible vu que l'anode ne peut pas émettre d'électrons. Un tel circuit est appelé une '''diode'''. Une amélioration des tubes à vide précédent rajoute une seconde plaque de métal, appelée la '''cathode''', située juste après le filament. C'est elle qui émet les électrons, , mais seulement si elle est chauffée par le filament. Le filament doit donc chauffer, ce qui réchauffe la cathode, qui elle-même émet des électrons en direction de l'anode. {| |[[File:Diode à vide.png|vignette|upright=1.5|Diode à vide, avec cathode.]] |[[File:Diode à vide schéma de fonctionnement.png|vignette|upright=1.5|Diode à vide, schéma de fonctionnement. Le filament X chauffe la cathode (2), qui émet des électrons (3), vers l'anode (4).]] |} Les tubes à vide précédent peuvent être modifiés en ajoutant une grille métallique entre la cathode et l'anode. La grille est alimentée avec une tension électrique, ce qui la charge électriquement. Suivant sa charge, elle laisse plus ou moins passer les électrons de la cathode vers l'anode. Si elle n'est pas chargée, que la tension est de 0 Volts, elle ne fera pas obstacle aux électrons et le tube à vide fonctionnera comme une diode basique. Mais si la grille est chargée avec une tension négative, sa charge électrique va repousser les électrons et les empêcher de passer de la cathode vers l'anode. Le tube à vide se comportera alors comme un interrupteur : fermé ou ouvert suivant ce qu'on met sur la grille. De tels interrupteurs commandables électriquement sont combinés pour fabriquer des circuits plus élaborés, comme les portes logiques qu'on verra d'ici quelques chapitres. [[File:Triode.png|centre|vignette|upright=1.5||Triode]] Les tubes à vides étaient utilisés pour le processeur et quelques circuits annexes, mais les mémoires utilisaient d'autres technologies. Les mémoires de l'époque n'étaient pas du tout des mémoires électroniques. Il existait déjà des ancêtres des disques durs, à savoir des mémoire magnétiques appelées tambours magnétiques, bandes magnétiques, mémoires à tore de ferrite, etc. Les mémoires RAM, quant à elles, utilisaient elles des technologies totalement abandonnées : les mémoires à lignes de délai étaient des mémoires acoustiques, les tubes Williams étaient des écrans CRT modifiés, etc. Un chapitre entier sera dédié aux technologies des mémoires de l'époque. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] L'usage de tubes à vide les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition. Les multiplications étaient réalisées par des additions successives, mais le processeur intégrait des registres pour mémoriser les opérandes à multiplier. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Les transistors étaient au départ de la même taille que les tubes à vide, mais ils ont rapidement rétrécit. Ils prenaient encore beaucoup de place dans les 60-70, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 578yd676ktcvh2bsq6zh99cen4iu2u6 744170 744169 2025-06-05T15:41:34Z Mewtow 31375 /* La première génération : les tubes à vide */ 744170 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Au tout début de l'informatique, les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique percées par endroits. Un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique et précisémment sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, quelques laboratoires de recherche ont fabriqués des ordinateurs dans leur coin, comme le Harvard Mark I et le Colossus Mark 1 (UK) qui ont été mis en service en 1944. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient généralement des relais, à savoir des interrupteurs commandables électriquement, qui sont plus ou moins équivalents aux transistors modernes. La majeure partie des ordinateurs des années 40 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, des espèces d'interrupteurs commandables, les ancêtres des transistors modernes. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. Les tubes à vide sont des ampoules à filament améliorées. Pour rappel, les ampoules à filament étaient des ampoules en verre dans lesquelles on plaçait un filament métallique. Le filament chauffait quand on envoyait du courant dedans et émettait de la lumière. Mais dans les tubes à vide, le filament n'émet pas de lumière quand on le chauffe : il émet des électrons, de l'électricité. De plus, ils ajoutent une électrode, une plaque en métal qui émet ou capte des électrons. Ici, l'électrode capte des électrons émis par le filament quand il chauffe. Vu qu'elle capte des électrons, on l'appelle l''''anode'''. Le résultat est un circuit qui laisse passer le courant, mais seulement dans un sens : du filament vers l'anode, l'autre sens n'est pas possible vu que l'anode ne peut pas émettre d'électrons. Un tel circuit est appelé une '''diode'''. Une amélioration des tubes à vide précédent rajoute une seconde plaque de métal, appelée la '''cathode''', située juste après le filament. C'est elle qui émet les électrons, , mais seulement si elle est chauffée par le filament. Le filament doit donc chauffer, ce qui réchauffe la cathode, qui elle-même émet des électrons en direction de l'anode. {| |[[File:Diode à vide.png|vignette|upright=1.5|Diode à vide, avec cathode.]] |[[File:Diode à vide schéma de fonctionnement.png|vignette|upright=1.5|Diode à vide, schéma de fonctionnement. Le filament X chauffe la cathode (2), qui émet des électrons (3), vers l'anode (4).]] |} Les tubes à vide précédent peuvent être modifiés en ajoutant une grille métallique entre la cathode et l'anode. La grille est alimentée avec une tension électrique, ce qui la charge électriquement. Suivant sa charge, elle laisse plus ou moins passer les électrons de la cathode vers l'anode. Si elle n'est pas chargée, que la tension est de 0 Volts, elle ne fera pas obstacle aux électrons et le tube à vide fonctionnera comme une diode basique. Mais si la grille est chargée avec une tension négative, sa charge électrique va repousser les électrons et les empêcher de passer de la cathode vers l'anode. Le tube à vide se comporte alors comme un interrupteur : fermé ou ouvert suivant ce qu'on met sur la grille. Un tel tube à vide est appelée une '''triode''', car c'est une diode à laquelle on a ajouté une entrée pour charger la grille. De tels interrupteurs commandables électriquement sont combinés pour fabriquer des circuits plus élaborés, comme les portes logiques qu'on verra d'ici quelques chapitres. [[File:Triode.png|centre|vignette|upright=2.5|Triode, ancêtre du transistor]] Les tubes à vides étaient utilisés pour le processeur et quelques circuits annexes, mais les mémoires utilisaient d'autres technologies. Les mémoires de l'époque n'étaient pas du tout des mémoires électroniques. Il existait déjà des ancêtres des disques durs, à savoir des mémoire magnétiques appelées tambours magnétiques, bandes magnétiques, mémoires à tore de ferrite, etc. Les mémoires RAM, quant à elles, utilisaient elles des technologies totalement abandonnées : les mémoires à lignes de délai étaient des mémoires acoustiques, les tubes Williams étaient des écrans CRT modifiés, etc. Un chapitre entier sera dédié aux technologies des mémoires de l'époque. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] L'usage de tubes à vide les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition. Les multiplications étaient réalisées par des additions successives, mais le processeur intégrait des registres pour mémoriser les opérandes à multiplier. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Les transistors étaient au départ de la même taille que les tubes à vide, mais ils ont rapidement rétrécit. Ils prenaient encore beaucoup de place dans les 60-70, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> mgot873unhnil3b2yrcrl19776ipzzy 744171 744170 2025-06-05T15:45:56Z Mewtow 31375 /* La première génération : les tubes à vide */ 744171 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Au tout début de l'informatique, les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique percées par endroits. Un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique et précisémment sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, quelques laboratoires de recherche ont fabriqués des ordinateurs dans leur coin, comme le Harvard Mark I et le Colossus Mark 1 (UK) qui ont été mis en service en 1944. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient généralement des relais, à savoir des interrupteurs commandables électriquement, qui sont plus ou moins équivalents aux transistors modernes. La majeure partie des ordinateurs des années 40 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, des espèces d'interrupteurs commandables, les ancêtres des transistors modernes. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. Les tubes à vide sont des ampoules à filament améliorées. Pour rappel, les ampoules à filament étaient des ampoules en verre dans lesquelles on plaçait un filament métallique. Le filament chauffait quand on envoyait du courant dedans et émettait de la lumière. De plus, un tube à vide contient en plus une électrode, une plaque en métal qui émet ou capte des électrons. [[File:Diode vacuum tube.svg|vignette|Diode vacuum tube]] Dans le cas le plus simple, le filament n'émet pas de lumière quand on le chauffe : il émet des électrons, de l'électricité. Il n'y a qu'une seule électrode, qui capte des électrons émis par le filament quand il chauffe. Vu qu'elle capte des électrons, on l'appelle l''''anode'''. Le résultat est un circuit qui laisse passer le courant, mais seulement dans un sens : du filament vers l'anode, l'autre sens n'est pas possible vu que l'anode ne peut pas émettre d'électrons. Un tel circuit est appelé une '''diode'''. Une variante des tubes à vide précédent utilise un filament chauffant, qui n'émet pas d’électrons. A la place, le filament chauffe une seconde électrode, appelée la '''cathode''', qui émet les électrons quand elle est assez chaude. Le filament doit donc chauffer, ce qui réchauffe la cathode, qui elle-même émet des électrons en direction de l'anode. {| |[[File:Diode à vide.png|vignette|upright=1.5|Diode à vide, avec cathode.]] |[[File:Diode à vide schéma de fonctionnement.png|vignette|upright=1.5|Diode à vide, schéma de fonctionnement. Le filament X chauffe la cathode (2), qui émet des électrons (3), vers l'anode (4).]] |} Les tubes à vide précédent peuvent être modifiés en ajoutant une grille métallique entre la cathode et l'anode. La grille est alimentée avec une tension électrique, ce qui la charge électriquement. Suivant sa charge, elle laisse plus ou moins passer les électrons de la cathode vers l'anode. Si elle n'est pas chargée, que la tension est de 0 Volts, elle ne fera pas obstacle aux électrons et le tube à vide fonctionnera comme une diode basique. Mais si la grille est chargée avec une tension négative, sa charge électrique va repousser les électrons et les empêcher de passer de la cathode vers l'anode. Le tube à vide se comporte alors comme un interrupteur : fermé ou ouvert suivant ce qu'on met sur la grille. Un tel tube à vide est appelée une '''triode''', car c'est une diode à laquelle on a ajouté une entrée pour charger la grille. De tels interrupteurs commandables électriquement sont combinés pour fabriquer des circuits plus élaborés, comme les portes logiques qu'on verra d'ici quelques chapitres. [[File:Triode.png|centre|vignette|upright=2.5|Triode, ancêtre du transistor]] Les tubes à vides étaient utilisés pour le processeur et quelques circuits annexes, mais les mémoires utilisaient d'autres technologies. Les mémoires de l'époque n'étaient pas du tout des mémoires électroniques. Il existait déjà des ancêtres des disques durs, à savoir des mémoire magnétiques appelées tambours magnétiques, bandes magnétiques, mémoires à tore de ferrite, etc. Les mémoires RAM, quant à elles, utilisaient elles des technologies totalement abandonnées : les mémoires à lignes de délai étaient des mémoires acoustiques, les tubes Williams étaient des écrans CRT modifiés, etc. Un chapitre entier sera dédié aux technologies des mémoires de l'époque. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] L'usage de tubes à vide les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition. Les multiplications étaient réalisées par des additions successives, mais le processeur intégrait des registres pour mémoriser les opérandes à multiplier. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Les transistors étaient au départ de la même taille que les tubes à vide, mais ils ont rapidement rétrécit. Ils prenaient encore beaucoup de place dans les 60-70, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 18xq13z726xgxse2su8npqt6mkjtzx4 744172 744171 2025-06-05T15:47:28Z Mewtow 31375 /* La première génération : les tubes à vide */ 744172 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Au tout début de l'informatique, les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique percées par endroits. Un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique et précisémment sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, quelques laboratoires de recherche ont fabriqués des ordinateurs dans leur coin, comme le Harvard Mark I et le Colossus Mark 1 (UK) qui ont été mis en service en 1944. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient généralement des relais, à savoir des interrupteurs commandables électriquement, qui sont plus ou moins équivalents aux transistors modernes. La majeure partie des ordinateurs des années 40 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, des espèces d'interrupteurs commandables, les ancêtres des transistors modernes. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. Les tubes à vide sont des ampoules à filament améliorées. Pour rappel, les ampoules à filament étaient des ampoules en verre dans lesquelles on plaçait un filament métallique. Le filament chauffait quand on envoyait du courant dedans et émettait de la lumière. De plus, un tube à vide contient en plus une électrode, une plaque en métal qui émet ou capte des électrons. [[File:Diode vacuum tube.svg|vignette|Diode vacuum tube]] Dans le cas le plus simple, le filament n'émet pas de lumière quand on le chauffe : il émet des électrons, de l'électricité. Il n'y a qu'une seule électrode, qui capte des électrons émis par le filament quand il chauffe. Vu qu'elle capte des électrons, on l'appelle l''''anode'''. Le résultat est un circuit qui laisse passer le courant, mais seulement dans un sens : du filament vers l'anode, l'autre sens n'est pas possible vu que l'anode ne peut pas émettre d'électrons. Un tel circuit est appelé une '''diode'''. Une variante des tubes à vide précédent utilise un filament chauffant, qui n'émet pas d’électrons. A la place, le filament chauffe une seconde électrode, appelée la '''cathode''', qui émet les électrons quand elle est assez chaude. Le filament doit donc chauffer, ce qui réchauffe la cathode, qui elle-même émet des électrons en direction de l'anode. {| |[[File:Diode à vide.png|vignette|upright=1.5|Diode à vide, avec cathode.]] |[[File:Diode à vide schéma de fonctionnement.png|vignette|upright=1.5|Diode à vide, schéma de fonctionnement. Le filament X chauffe la cathode (2), qui émet des électrons (3), vers l'anode (4).]] |} [[File:Triode vacuum tube FR.png|vignette|Triode.]] Les tubes à vide précédents peuvent être modifiés en ajoutant une grille métallique entre la cathode et l'anode. La grille est alimentée avec une tension électrique, ce qui la charge électriquement. Suivant sa charge, elle laisse plus ou moins passer les électrons de la cathode vers l'anode. Si elle n'est pas chargée, que la tension est de 0 Volts, elle ne fera pas obstacle aux électrons et le tube à vide fonctionnera comme une diode basique. Mais si la grille est chargée avec une tension négative, sa charge électrique va repousser les électrons et les empêcher de passer de la cathode vers l'anode. Le tube à vide se comporte alors comme un interrupteur : fermé ou ouvert suivant ce qu'on met sur la grille. Un tel tube à vide est appelée une '''triode''', car c'est une diode à laquelle on a ajouté une entrée pour charger la grille. De tels interrupteurs commandables électriquement sont combinés pour fabriquer des circuits plus élaborés, comme les portes logiques qu'on verra d'ici quelques chapitres. [[File:Triode.png|centre|vignette|upright=2.5|Triode, ancêtre du transistor]] Les tubes à vides étaient utilisés pour le processeur et quelques circuits annexes, mais les mémoires utilisaient d'autres technologies. Les mémoires de l'époque n'étaient pas du tout des mémoires électroniques. Il existait déjà des ancêtres des disques durs, à savoir des mémoire magnétiques appelées tambours magnétiques, bandes magnétiques, mémoires à tore de ferrite, etc. Les mémoires RAM, quant à elles, utilisaient elles des technologies totalement abandonnées : les mémoires à lignes de délai étaient des mémoires acoustiques, les tubes Williams étaient des écrans CRT modifiés, etc. Un chapitre entier sera dédié aux technologies des mémoires de l'époque. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] L'usage de tubes à vide les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition. Les multiplications étaient réalisées par des additions successives, mais le processeur intégrait des registres pour mémoriser les opérandes à multiplier. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Les transistors étaient au départ de la même taille que les tubes à vide, mais ils ont rapidement rétrécit. Ils prenaient encore beaucoup de place dans les 60-70, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 2d8saqtpblv31xaulgklrwfsbxvprj4 744173 744172 2025-06-05T15:50:16Z Mewtow 31375 /* La première génération : les tubes à vide */ 744173 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Au tout début de l'informatique, les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique percées par endroits. Un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique et précisémment sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, quelques laboratoires de recherche ont fabriqués des ordinateurs dans leur coin, comme le Harvard Mark I et le Colossus Mark 1 (UK) qui ont été mis en service en 1944. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient généralement des relais, à savoir des interrupteurs commandables électriquement, qui sont plus ou moins équivalents aux transistors modernes. La majeure partie des ordinateurs des années 40 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide, des espèces d'interrupteurs commandables, les ancêtres des transistors modernes. Les tubes à vide étaient assez encombrants, ils consommaient beaucoup de courant, ils chauffaient et étaient assez peu fiables. Ils tombaient en panne assez souvent. Et ils étaient assez simples à fabriquer, mais restaient malgré tout chers. [[File:Diode vacuum tube.svg|vignette|Diode vacuum tube]] Les tubes à vide sont des ampoules à filament améliorées. Pour rappel, les ampoules à filament étaient des ampoules en verre dans lesquelles on plaçait un filament métallique. Le filament chauffait quand on envoyait du courant dedans et émettait de la lumière. Dans les tubes à vides, le filament n'émet pas de lumière quand on le chauffe : il émet des électrons, de l'électricité. De plus, on ajoute une plaque métalliques appelée l'anode, qui capte des électrons émis par le filament. Le résultat est un circuit qui laisse passer le courant, mais seulement dans un sens : du filament vers l'anode, l'autre sens n'est pas possible vu que l'anode ne peut pas émettre d'électrons. Un tel circuit est appelé une '''diode'''. [[File:Triode vacuum tube FR.png|vignette|Triode.]] Les tubes à vide précédents peuvent être modifiés en ajoutant une grille métallique entre la cathode et l'anode. La grille est alimentée avec une tension électrique, ce qui la charge électriquement. Suivant sa charge, elle laisse plus ou moins passer les électrons de la cathode vers l'anode. Si elle n'est pas chargée, que la tension est de 0 Volts, elle ne fera pas obstacle aux électrons et le tube à vide fonctionnera comme une diode basique. Mais si la grille est chargée avec une tension négative, sa charge électrique va repousser les électrons et les empêcher de passer de la cathode vers l'anode. Le tube à vide se comporte alors comme un interrupteur : fermé ou ouvert suivant ce qu'on met sur la grille. Un tel tube à vide est appelée une '''triode''', car c'est une diode à laquelle on a ajouté une entrée pour charger la grille. De tels interrupteurs commandables électriquement sont combinés pour fabriquer des circuits plus élaborés, comme les portes logiques qu'on verra d'ici quelques chapitres. Les tubes à vides étaient utilisés pour le processeur et quelques circuits annexes, mais les mémoires utilisaient d'autres technologies. Les mémoires de l'époque n'étaient pas du tout des mémoires électroniques. Il existait déjà des ancêtres des disques durs, à savoir des mémoire magnétiques appelées tambours magnétiques, bandes magnétiques, mémoires à tore de ferrite, etc. Les mémoires RAM, quant à elles, utilisaient elles des technologies totalement abandonnées : les mémoires à lignes de délai étaient des mémoires acoustiques, les tubes Williams étaient des écrans CRT modifiés, etc. Un chapitre entier sera dédié aux technologies des mémoires de l'époque. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] L'usage de tubes à vide les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition. Les multiplications étaient réalisées par des additions successives, mais le processeur intégrait des registres pour mémoriser les opérandes à multiplier. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Les transistors étaient au départ de la même taille que les tubes à vide, mais ils ont rapidement rétrécit. Ils prenaient encore beaucoup de place dans les 60-70, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> rq245v6wjk3g5tbqg4hkhptw8llkce3 744174 744173 2025-06-05T15:53:48Z Mewtow 31375 /* La première génération : les tubes à vide */ 744174 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Au tout début de l'informatique, les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique percées par endroits. Un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique et précisémment sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, quelques laboratoires de recherche ont fabriqués des ordinateurs dans leur coin, comme le Harvard Mark I et le Colossus Mark 1 (UK) qui ont été mis en service en 1944. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient généralement des relais, à savoir des interrupteurs commandables électriquement, qui sont plus ou moins équivalents aux transistors modernes. La majeure partie des ordinateurs des années 40 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== [[File:Diode vacuum tube.svg|vignette|Diode vacuum tube]] Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide. Les tubes à vide sont des ampoules à filament améliorées. Pour rappel, les ampoules à filament étaient des ampoules en verre dans lesquelles on plaçait un filament métallique. Le filament chauffait quand on envoyait du courant dedans et émettait de la lumière. Dans les tubes à vides, le filament n'émet pas de lumière quand on le chauffe : il émet des électrons, de l'électricité. De plus, on ajoute une plaque métalliques appelée l'anode, qui capte des électrons émis par le filament. Le résultat est un circuit qui laisse passer le courant, mais seulement dans un sens : du filament vers l'anode, l'autre sens n'est pas possible vu que l'anode ne peut pas émettre d'électrons. Un tel circuit est appelé une '''diode'''. [[File:Triode vacuum tube FR.png|vignette|Triode.]] Les tubes à vide précédents peuvent être modifiés en ajoutant une grille métallique entre la cathode et l'anode. La grille est alimentée avec une tension électrique, ce qui la charge électriquement. Suivant sa charge, elle laisse plus ou moins passer les électrons de la cathode vers l'anode. Si elle n'est pas chargée, que la tension est de 0 Volts, elle ne fera pas obstacle aux électrons et le tube à vide fonctionnera comme une diode basique. Mais si la grille est chargée avec une tension négative, sa charge électrique va repousser les électrons et les empêcher de passer de la cathode vers l'anode. Le tube à vide se comporte alors comme un interrupteur : fermé ou ouvert suivant ce qu'on met sur la grille. Un tel tube à vide est appelée une '''triode''', car c'est une diode à laquelle on a ajouté une entrée pour charger la grille. De tels interrupteurs commandables électriquement sont combinés pour fabriquer des circuits plus élaborés, comme les portes logiques qu'on verra d'ici quelques chapitres. Au vu de ce qu'on vient de dire, on peut facilement deviner que les tubes à vide avaient beaucoup de défauts. Ils étaient assez encombrants, dans le sens où une ampoule prend beaucoup de place. Et il est difficile de miniaturiser une ampoule, personne n'imagine une ampoule de quelques microns de côté, alors que les transistors actuels sont plus petits que ça. De plus, ils consommaient beaucoup de courant et chauffaient. Faire chauffer un filament demande un courant important et une bonne partie de ce courant part en chaleur. De plus, ils étaient assez peu fiables et tombaient en panne assez souvent. Et s'ils étaient assez simples à fabriquer, ils restaient malgré tout chers. Les tubes à vides étaient utilisés pour le processeur et quelques circuits annexes, mais les mémoires utilisaient d'autres technologies. Les mémoires de l'époque n'étaient pas du tout des mémoires électroniques. Il existait déjà des ancêtres des disques durs, à savoir des mémoire magnétiques appelées tambours magnétiques, bandes magnétiques, mémoires à tore de ferrite, etc. Les mémoires RAM, quant à elles, utilisaient elles des technologies totalement abandonnées : les mémoires à lignes de délai étaient des mémoires acoustiques, les tubes Williams étaient des écrans CRT modifiés, etc. Un chapitre entier sera dédié aux technologies des mémoires de l'époque. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] L'usage de tubes à vide les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrit pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition. Les multiplications étaient réalisées par des additions successives, mais le processeur intégrait des registres pour mémoriser les opérandes à multiplier. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Les transistors étaient au départ de la même taille que les tubes à vide, mais ils ont rapidement rétrécit. Ils prenaient encore beaucoup de place dans les 60-70, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> 9116h9lujccv7m3f5sla0tuwmhxgsgi 744175 744174 2025-06-05T16:56:40Z Mewtow 31375 /* La première génération : les tubes à vide */ 744175 wikitext text/x-wiki Pour commencer, nous allons voir qu'il existe de nombreux types d'ordinateurs. Le plus connu est certainement le PC, l'ordinateur personnel, que vous avez sans doute dans votre salon. Les ordinateurs portables sont un deuxième type d'ordinateur assez intuitif, que vous avez peut-être. Mais il y a aussi d'autres types d'ordinateurs auxquels vous n'avez jamais été confrontés. ==Les différents types d'ordinateurs== Dans cette section, nous allons décrire rapidement les ordinateurs les plus courant, mais surtout voir ce qu'il y a à l'intérieur d'un ordinateur. ===L'ordinateur de type PC fixe=== De l'extérieur, l'ordinateur est composé d'une unité centrale sur laquelle on branche des périphériques. [[File:Typical computer architecture systems.jpg|vignette|upright=1.5|Exemples de périphériques, connectés à une unité centrale (ici appelée à tort ''operating system'').]] Les '''périphériques''' regroupent l'écran, la souris, le clavier, l'imprimante, et bien d'autres choses. Ils permettent à l'utilisateur d'interagir avec l'ordinateur : un clavier permet de saisir du texte sous dans un fichier, une souris enregistre des déplacements de la main en déplacement du curseur, un écran affiche des données d’images/vidéos, un haut-parleur émet du son, etc. Tout ce qui est branché sur un ordinateur est, formellement un périphérique. L''''unité centrale''' est là où se trouvent tous les composants importants d'un ordinateur, ceux qui font des calculs, qui exécutent des logiciels, qui mémorisent vos données, etc. Voici ce à quoi ressemble l'intérieur de l'unité centrale. Trois sections sont visibles : l'alimentation électrique en haut à gauche, la carte mère en bas à gauche et en jaune/orange, les disques et lecteurs à droite des câbles. Et on voit aussi beaucoup de câbles. [[File:Asus P5K-SEIntel E6320.jpg|centre|vignette|upright=2|Exemple d'unité centrale.]] Tout en haut à gauche, se trouve l''''alimentation électrique''', qui convertit le courant de la prise électrique en un courant plus faible, utilisable par les autres composants. Elle émet de nombreux câbles assez gros, qui sont reliés au reste. Les PC actuels utilisent des alimentations électriques standardisées, qui fournissent trois tensions au reste de l'ordinateur : une tension de 12 Volts, une de 5 Volts, une de 3,3 Volts. À droite, caché par la partie "métallique" du boitier, se trouvent les lecteurs de CD/DVD, et les disques durs. Les lecteurs CD-ROM ou DVD-ROM permettaient de lire des CD ou des DVD. Je parle au passé, car ils ont aujourd'hui disparu des ordinateurs modernes. Les '''disques durs''' sont des mémoires de stockage, qui mémorisent vos données de manière permanente. De nos jours, ils sont remplacés par des SSD, qui sont des disques durs électroniques, là où les disques durs proprement dit sont des mémoires magnétiques. Nous verrons la différence dans deux chapitres dédiés, un sur les disques durs, l'autre sur les SSD. En bas à droite, se trouve la '''carte mère''' un support plat, en plastique ou en céramique, sur laquelle sont soudés/connectés les autres composants. Sur celle-ci, de nombreux composants sont soudés, d'autres sont branchés dessus avec des câbles, d'autres sont connectés dessus avec des connecteurs. Ils sont reliés entre eux par des fils conducteurs, le plus souvent du cuivre ou de l’aluminium, ce qui leur permet de s’échanger des données. Sur les cartes simples, ces fils sont intégrés dans la carte électronique, dans des creux du plastique. Ils portent le nom de pistes. Avant, les disques durs, SSD et lecteurs de CD/DVD sont branchés dessus via des connecteurs dédiés, appelés des connecteurs S-ATA. De nos jours, ils sont branchés sur un autre connecteur, grâce à l'interface NVME. Toujours est-il qu'ils sont reliés à la carte mère par des câbles, ce qui montre que ce sont des sortes de périphériques interne. Ils sont placés dans le boitier, mais on aurait tout aussi bien pu les mettre à l'extérieur, vu qu'ils communiquent avec l'ordinateur par l'intermédiaire d'un câble ou d'un connecteur dédié. Mais deux autres composants très importants sont eux placés sur la carte mère, directement. Ils ont chacun un connecteur dédié, sur lequel ils sont branchés directement, sans passer par l'intermédiaire d'un câble, mais sans être soudés non plus. Il s'agit du processeur et de la mémoire RAM, deux composants centraux des PC modernes. [[File:Pentium III SL4CB.jpg|thumb|Processeur Pentium III.]] Le '''processeur''' traite les données, les modifie, les manipule. Pour faire simple, il s’agit d’une grosse calculatrice hyper-puissante. Il comprend à la fois un circuit qui fait des calculs, et un circuit de contrôle qui s'occupe de séquencer les calculs dans l'ordre demandé. Il est souvent caché sous un radiateur, lui-même surmonté par un ventilateur. En effet, un processeur chauffe beaucoup, ce qui demande d'évacuer cette chaleur. Un chapitre entier expliquera pourquoi les processeurs chauffent, ainsi que les techniques utilisées pour limiter leur production de chaleur et leur consommation électrique. La '''mémoire vive''' conserve des informations/données temporairement, tant que le processeur en a besoin. Elle prend la forme de barrettes de RAM, comme montré ci-dessous. [[File:2 gb ddr2 667.jpg|centre|vignette|upright=2|Barrette de RAM.]] Outre ces composants dits principaux, un ordinateur peut comprendre plusieurs composants moins importants, surtout présents sur les ordinateurs personnels. Ils sont techniquement facultatifs, mais sont très présents dans les ordinateurs personnels. Cependant, certains ordinateurs spécialisés s'en passent. Il s'agit des diverses '''cartes d'extension''' sont branchées sur la carte mère. Elles permettent d’accélérer certains calculs ou certaines applications, afin de décharger le processeur. Par exemple, la carte graphique s'occupe des calculs graphiques, qu'il s'agisse de graphismes 3D de jeux vidéos ou de l'affichage en 2D du bureau. Dans un autre registre, la carte son prend en charge le microphone et les haut-parleurs. [[Fichier:Personal computer, exploded 4.svg|thumb|upright=1.0|Éclaté d'un ordinateur de type PC :<br /> 1 : Écran ;<br /> 2 : Carte mère ;<br /> 3 : Processeur ;<br /> 4 : Câble Parallel ATA ;<br /> 5 : Mémoire vive (RAM) ;<br /> 6 : Carte d'extension ;<br /> 7 : Alimentation électrique ;<br /> 8 : Lecteur de disque optique ;<br /> 9 : Disque dur ;<br /> 10 : Clavier ;<br /> 11 : Souris.]] Si on regarde une carte mère de face, on voit un grand nombre de connecteurs, mais aussi des circuits électroniques soudés à la carte mère. [[File:Architecture matérielle d'une carte mère.png|centre|vignette|upright=2.0|Architecture matérielle d'une carte mère]] Les '''connecteurs''' sont là où on branche les périphériques, la carte graphique, le processeur, la mémoire, etc. Dans l'ensemble, toute carte mère contient les connecteurs suivants : * Le processeur vient s’enchâsser dans la carte mère sur un connecteur particulier : le '''socket'''. Celui-ci varie suivant la carte mère et le processeur, ce qui est source d'incompatibilités. * Les barrettes de mémoire RAM s’enchâssent dans un autre type de connecteurs: les '''slots mémoire'''. * Les mémoires de masse disposent de leurs propres connecteurs : connecteurs P-ATA pour les anciens disques durs, et S-ATA pour les récents. * Les périphériques (clavier, souris, USB, Firewire, ...) sont connectés sur un ensemble de connecteurs dédiés, localisés à l'arrière du boitier de l'unité centrale. * Les autres périphériques sont placés dans l'unité centrale et sont connectés via des connecteurs spécialisés. Ces périphériques sont des cartes imprimées, d'où leur nom de '''cartes filles'''. On peut notamment citer les cartes réseau, les cartes son, ou les cartes vidéo. ===Les ordinateurs portables=== [[File:Samsung QX-511 (2).JPG|vignette|Ordinateur portable Samsung QX-511 (2), pour illustration.]] Un ordinateur portable est identique à un ordinateur de type PC. Si vous ouvrez votre ordinateur portable (attention à la garantie), vous retrouverez les mêmes composants qu'un PC à l'intérieur. Un point important est la présence d'une batterie à l'intérieur du PC portable, absente des PC fixes. [[File:LG gram 14Z90Q mainboard with battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q avec sa batterie.]] Une fois la batterie et les circuits associés retiré, la seule différence notable est que tous les composants sont soudés sur la carte mère, au lieu d'être branchés sur des connecteurs, à part éventuellement la RAM et le disque dur. [[File:LG gram 14Z90Q mainboard without battery.jpg|centre|vignette|upright=2|LG gram 14Z90Q sans sa batterie.]] La RAM est parfois soudée sur la carte mère, d'autres fois sous la forme de barrettes de mémoire vive semblables à celles des PC. Dans le dernier cas, elle est connectée à des connecteurs spécifiques, ce qui permet de les changer/upgrader. Les PC portables sont parfois construits de manière à pouvoir changer la RAM facilement, en ouvrant un cache spécial, concu pour. [[File:Lenovo G555 состав - Донор.JPG|centre|vignette|upright=2|Lenovo G555.]] La conception d'un ordinateur portable est légèrement différente de celle d'un PC, pour des raisons thermiques. Un PC fixe a plus de place pour évacuer sa chaleur. Les ventilateurs peuvent plus facilement déplacer l'air dans le boitier, même si le flux d'air dans le boitier est éventuellement gêné par la carte graphique. Mais l'évacuation de la chaleur est assez efficace. Sur les PC portables, leur finesse fait que le trajet de l'air est beaucoup plus contraint. Évacuer la chaleur produite par l'ordinateur est plus complexe, ce qui demande d'utiliser des systèmes de refroidissement et de ventilation spécifiques. Là où les PC fixes se débrouillent avec des radiateurs et des ventilateurs posés sur le processeur, les PC portables font autrement. Ils ne peuvent pas forcément mettre le ventilateur sur le processeur. A la place, ils mettent le ventilateur à côté, mais le processeur est surmonté par un mécanisme de transmission de la chaleur, qui transfère la chaleur du processeur vers le ventilateur. [[File:Diagram - How a laptop cooling system works.png|centre|vignette|upright=2|Comment fonctionne le système de ventilation d'un ordinateur portable, en anglais.]] Les difficultés pour dissiper la chaleur font que les ordinateurs portables utilisent souvent des composants peu performants, mais qui chauffent peu. En effet, nous verrons que plus un composant est puissant, plus il chauffe. La relation n'est pas parfaite, mais les processeurs haute performance chauffent plus que les modèles d'entrée ou milieu de gamme moins puissants. En conséquence, les PC portables sont souvent moins puissants que les PC fixes, même pour les modèles dit ''gaming''. ===Les serveurs et ''mainframes''=== Les grandes entreprises utilisent des ordinateurs de grande taille, très puissants, appelés des ''mainframes''. Ils sont souvent confondus avec les serveurs par le grand public, il y a une différence entre les deux. Un serveur est une fonction logicielle/réseau, pas un type d'ordinateur. Mais laissons cette différence de côté, ce qui est dit pour les ''mainframes'' sert pour les gros serveurs haute performance. [[File:IBM Z15 mainframe.jpg|vignette|Exemple de ''mainframe''' de type IBM Z15.]] Les anciens ''mainframes'' des années 50-80 avaient une taille pouvant être impressionnante, au point de prendre une pièce complète d'un bâtiment. Mais de nos jours, les ''mainframes'' tiennent dans une grosse armoire un peu haute. Les ''mainframes'' doivent rester allumé en permanence et ne doivent pas être éteint, sauf éventuellement quelques jours par an pour des opérations de maintenance. Ils utilisent pour cela des techniques spécifiques, avec beaucoup de redondance interne. [[File:ACONIT hall grandes machines.jpg|centre|vignette|upright=2|''Mainframe'' ACONIT.]] Les ''mainframes'' sont aussi conçus pour mutualiser au maximum leur utilisation, ils peuvent être utilisés par plusieurs utilisateurs à la suite, voire en même temps. Pour cela, les anciens ''mainframes'' étaient capables de faire tourner plusieurs applications distinctes l'une à la suite de l'autre, avec des commutations fréquentes entre logiciels. De nos jours, ils sont capables d'exécuter un grand nombre de tâches en même temps, grâce à la présence de plusieurs processeurs. Les ''mainframes'' modernes sont même capables de faire tourner plusieurs systèmes d'exploitation en même temps si besoin. Les anciens ''mainframes'' étaient des ordinateurs assez simples, avec un processeur, de la mémoire RAM, un ou plusieurs disques durs, pas plus. Le ''mainframe'' était tellement énorme et cher que les entreprises n'en avaient qu'un seul pour toute l'entreprise. Les employés avaient sur leur bureau des terminaux, qui permettaient d'accéder à l'ordinateur central, mais n'étaient pas des ordinateurs. Les terminaux étaient des composants électroniques simples, avec un écran, un clavier et une souris, mais sans processeur. Ils envoyaient des données au ''mainframe'', ils en recevaient de sa part, mais tout traitement était réalisé sur le ''mainframe''. L'arrivée sur le marché des ordinateurs personnels, de type PC fixe/portable, a entrainé l'abandon de ce genre de pratique, tous les employés ont maintenant un ordinateur rien que pour eux. {| |- ! colspan="2" | Exemples de terminaux |- |[[File:Terminal-in2-sm9400.jpg|centre|vignette|upright=1.5|Exemple de terminal. Notez la présence d'un écran et d'un clavier, mais l'asbence d'une unité centrale.]] |[[File:Chromatics CT4100.jpg|vignette|upright=1.5|Autre exemple de terminal. Le clavier est couplé à un stylo CRT, qui remplacait la souris et agissait sur l'écran comme s'il était tactile.]] |- ! colspan="2" | Intérieur d'un terminal |- |[[File:CT1024 Monitor.jpg|vignette|upright=1.5|Terminal CT1024, sans le boitier extérieur.]] |[[File:CT1024 Terminal System.jpg|vignette|upright=1.5|Terminal CT1024, description des composants interne.]] |} De nos jours, les ''mainframes'' contiennent en réalité plusieurs ordinateurs simples interconnectés via un réseau local. Un ''mainframe'' qui tient dans une armoire contient facilement une dizaine ou centaine de processeurs, plein de RAM, des disques durs séparés dans une armoire distincte, etc. Vu qu'ils communiquent uniquement via le réseau, ils n'ont pas d'interface, pas d'écran, 'entrée via clavier/souris. Le tout est commandé avec une console de commande, typiquement un ordinateur portable ou un terminal assez simple séparé de l'armoire, qui permet à un administrateur de faire des opérations de surveillance, configuration et maintenance. Il peut y avoir une console de commande pour plusieurs armoires séparées, la console peut même être dans un autre bâtiment et accéder au ''mainframe'' par le réseau. [[File:IBM System Z9 (type 2094 inside).jpg|centre|vignette|upright=2|''Mainframe'' de type IBM System Z9. L'ordinateur portable sert de console pour qu'un administrateur fasse des opérations de surveillance, configuration et maintenance.]] Les processeurs et la RAM sont typiquement installés sur des cartes amovibles, qui sont connectées au fond de l'armoire lors de l'installation. Il est même possible de retirer ou d'ajouter des cartes en fonctionnement, afin d'ajouter/retirer des processeurs, des disques durs, etc. Ce qui est très utile si un composant est en panne et qu'il faut le remplacer. [[File:IBM TotalStorage Exp400.jpg|centre|vignette|upright=2|IBM TotalStorage Exp400]] ==Un peu d'abstraction : qu'est-ce qu'un ordinateur ?== Un ordinateur comprend donc un processeur, plusieurs mémoires, des cartes d'extension et une carte mère pour connecter le tout. Mais il s'agit là d'une description assez terre-à-terre de ce qu'est un ordinateur. Une autre description, plus abstraite, se base sur le fait qu'un ordinateur est une énorme calculatrice programmable. Elle permet d'expliquer pourquoi il y a une distinction entre processeur et mémoire, entre unité centrale et périphériques. Tout ce qui va suivre pourra vous paraitre assez abstrait, mais rassurez-vous : les prochains chapitres rendront tout cela plus concrets. ===La séparation entre entrées-sorties et traitement=== L'unité centrale peut être vue comme une énorme calculatrice ultra-puissante, qui exécute des commandes/opérations. Mais à elle seule, elle ne servirait à rien, il faut interagir avec par l'intermédiaire de plusieurs périphériques. Il existe deux types de périphériques, qui sont conceptuellement différents. Les périphériques comme le clavier ou la souris permettent d'envoyer des informations à l'ordinateur, d'agir sur celui-ci. A l'inverse, les écrans transmettent des informations dans le sens inverse : de l'ordinateur vers l'utilisateur. Les premiers sont appelés des '''entrées''', les seconds des '''sorties'''. Dans un ordinateur, les informations sont représentées sous la forme de nombres. Toute donnée dans un ordinateur est codée avec un ou plusieurs nombres regroupés dans une donnée, un fichier, ou autre. Et la transmissions avec les entrées et sorties se fait là-encore avec des nombres. Par exemple, quand vous appuyez sur votre clavier, le clavier envoie un numéro de touche à l'unité centrale, qui indique quelle touche a été appuyée. L'image à afficher à l'écran est codée sous la forme d'une suite de nombres (un par pixel). L'image est envoyée à l'écran, qui traduit la suite de nombre en image à afficher. Les entrées traduisent des actions utilisateurs en nombres, on dit que les entrées encodent les actions utilisateur. Les sorties font la traduction inverse, elles transforment des suites de nombres en une action physique. On dit qu'elles décodent des informations. Pour résumer, toute appareil électronique est composé par : * Des '''entrées''' sur lesquelles l'utilisateur agit sur l'ordinateur. Les entrées transforment les actions de l'utilisateur en nombres, qui sont interprétés par l'ordinateur. * Une '''unité de traitement''', qui manipule des nombres et fait des calculs/opérations dessus. Les nombres proviennent des entrées, du disque dur, ou d'autres sources, peu importe. * Des '''sorties''', qui va récupèrent le résultat calculé par l'unité de traitement pour en faire quelque chose : écrire sur une imprimante ou sur un moniteur, émettre du son,... [[File:Ordinateur théorique Simple 1.png|centre|vignette|upright=2|Ordinateur théorique Simple 1]] L'unité de traitement proprement dite, celle qui fait les calculs, est couplée à une mémoire qui mémorise les opérandes et résultats des calculs. La séparation entre processeur et mémoire est nécessaire pour qu'un appareil électronique soit qualifié d'ordinateur. De nombreux appareils n'ont pas de séparation entre unité de traitement et mémoire, comme certaines vielles radios AM/FM. [[File:Schéma de principe d'un ordinateur.png|centre|vignette|upright=2|Schéma de principe d'un ordinateur]] ===Un ordinateur est un appareil programmable=== Les appareils simples sont non-programmables, ce qui veut dire qu’ils sont conçus pour une utilisation particulière et qu’ils ne peuvent pas faire autre chose. Par exemple, les circuits électroniques d’un lecteur de DVD ne peuvent pas être transformé en lecteur audio ou en console de jeux... Les circuits non-programmables sont câblés une bonne fois pour toute, et on ne peut pas les modifier. On peut parfois reconfigurer le circuit, pour faire varier certains paramètres, via des interrupteurs ou des boutons, mais cela s’arrête là. Et cela pose un problème : à chaque problème qu'on veut résoudre en utilisant un automate, on doit recréer un nouveau circuit. À l'inverse, un ordinateur n’est pas conçu pour une utilisation particulière, contrairement aux autres objets techniques. Il est possible de modifier leur fonction du jour au lendemain, on peut lui faire faire ce qu’on veut. On dit qu'ils sont '''programmables'''. Pour cela, il suffit d’utiliser un logiciel, une application, un programme (ces termes sont synonymes), qui fait ce que l'on souhaite. La totalité des logiciels présents sur un ordinateur sont des programmes comme les autres, même le système d'exploitation (Windows, Linux, ...) ne fait pas exception. Un programme est une suite de d''''instructions machines''', chaque instruction effectuant une action dans l'ordinateur. Sur les ordinateurs modernes, les instructions les plus communes effectuent une opération arithmétique : une addition, une multiplication, une soustraction, etc. Les ordinateurs modernes sont donc de grosses calculettes très puissantes, capables d'effectuer des millions d'opérations par secondes. Et qui dit opération dit nombres : un ordinateur gère nativement des nombres, qui sont codés en binaire sur la quasi-totalité des ordinateurs modernes. Les ordinateurs modernes sont capables de faire des calculs sur des nombres entiers, mais aussi des nombres à virgule. Il existe plusieurs manières de représenter des nombres en binaire, certaines représentant des nombres entiers dits naturels (0 et plus), d'autres des nombres signés (positifs ou négatifs), d'autres des nombres à virgule. Un chapitre entier détaillera comment sont encodés ces nombres. Une instruction est représentée dans un ordinateur par une série de nombres entiers : un nombre qui indique quelle opération/commande effectuer et des autres nombres pour coder les données (ou de quoi les retrouver dans l'ordinateur). L'ordinateur récupére les commandes une par une, les traduit en opération à effectuer, exécuter l'opération, et enregistre le résultat. Puis il recommence avec la commande suivante. [[File:Ordinateur Théorique Complexe 1.png|centre|vignette|upright=3|Ordinateur Théorique Complexe. En jaune, le programme informatique, la liste de commande. Le rectangle gris est l'ordinateur proprement dit.]] De nombreux appareils sont programmables, mais tous ne sont pas des ordinateurs. Par exemple, certains circuits programmables nommés FPGA n'en sont pas. Pour être qualifié d'ordinateur, un appareil programmable doit avoir un processeur séparé de la mémoire. De plus, il doit utiliser un '''codage numérique''', chose que nous allons aborder dans le chapitre suivant. ===Les ordinateurs à programme mémorisé ou programme externe=== [[File:Blue-punch-card-front.png|vignette|upright=0.5|Carte Perforée.]] Au tout début de l'informatique, les programmes étaient enregistrés sur des cartes perforées, à savoir des cartes en papier/plastique percées par endroits. Un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. Par la suite, les premiers ordinateurs grand public, comme les Amstrad ou les Commodore, utilisaient des cassettes audio magnétiques pour stocker les programmes. Dans le même style, les consoles de jeu utilisaient autrefois des cartouches de jeu, qui contenaient le programme du jeu à exécuter. Pour résumer, les anciens ordinateurs mémorisaient les programmes sur un support externe, lu par un périphérique. De tels ordinateurs sont dits à '''programme externe'''. : D’anciens ordinateurs personnels, comme l’Amstrad ou le Commodore, permettaient de taper les programmes à exécuter à la main, au clavier, avant d’appuyer une touche pour les exécuter. Nul besoin de vous dire que les cassettes audio étaient plus pratiques. Mais de nos jours, les programmes sont enregistrés sur le disque dur de l'ordinateur ou dans une mémoire intégrée à l'ordinateur. On dit qu'ils sont installés, ce qui est un mot bien compliqué pour dire que le programme est enregistré sur le disque dur de l’ordinateur. A défaut de disque dur, le programme/logiciel est enregistré dans une mémoire spécialisée pour le stockage. Par exemple, sur les cartes électroniques grand public de marque Arduino, les programmes sont envoyés à la carte via le port USB, mais les programmes sont enregistrés dans la carte Arduino, dans une mémoire FLASH dédiée. Disque dur ou non, le programme est mémorisé dans la mémoire de l'ordinateur. Il est possible d'installer ou de désinstaller les programmes en modifiant le contenu de la mémoire. Le terme utilisé est alors celui de '''programme stocké en mémoire'''. Les programmes à installer sont disponibles soit sur un périphérique, comme un DVD ou une clé USB, soit sont téléchargés depuis internet. Les premiers PC fournissaient les logiciels sur des disquettes, qui contenaient un programme d'installation pour enregistrer le programme sur le disque dur de l'ordinateur. Par la suite, le support des logiciels a migré vers les CD et DVD, les logiciels devenant de plus en plus gros. De nos jours, la majorité des applications sont téléchargées depuis le net, l'usage de périphériques est devenu obsolète, même les consoles de jeu abandonnent cette méthode de distribution. ==Les générations d'ordinateurs : un historique rapide== L'informatique a beaucoup évolué dans le temps. Et une bonne partie de cette évolution tient à l'évolution de l’électronique sous-jacente. Les ordinateurs actuels sont fabriqués avec des transistors, des petits composants électroniques qui servent d'interrupteurs programmables, qu'on détaillera dans ce qui suit. Mais ça n'a pas toujours été le cas. Et cela permet de distinguer plusieurs '''générations d'ordinateurs'''. ===Les ordinateurs électro-mécaniques : les premiers ordinateurs=== Le tout premier ordinateur est le '''Z1''', un modèle unique inventé par Konrad Suze entre 1936 et 1938. Son processeur gérait non pas des nombres entiers, mais des nombres à virgule (des nombres dits flottants, pour être précis), encodés sur 22 bits. Le processeur du Z1 était capable de faire des additions et des soustractions, car il intégrait un circuit additionneur-soustracteur basique. Des circuits annexes permettaient de faire des multiplications et des divisions en enchainant des additions/soustractions successives. Il fonctionnait à une fréquence de 1 Hz, ce qui fait qu'il pouvait faire une addition/soustraction par seconde maximum. Niveau mémoire, la RAM de l'ordinateur était très limitée : seulement 16 nombres de 22 bits chacun. S'il s'agissait d'une mémoire électronique, les programmes étaient mémorisés sur une mémoire mécanique et précisémment sur des cartes perforées, à savoir des cartes en papier/plastique dans lesquelles un 1 est codé par un trou dans le papier et un 0 par une absence de trou. Les programmes étaient exécutés par l'ordinateur quand on insérait la carte perforée dans le lecteur et qu'on appuyait sur un bouton. [[File:German Museum of Technology, Berlin 2017 024.jpg|centre|vignette|upright=2|Réplique du Z1 au ''German Museum of Technology'' de Berlin, 2017.]] Après sa destruction dans un bombardement, le Z1 a été reconstruit et amélioré, ce qui donné les deux ordinateurs Z2 et Z3. Quelques années plus tard, quelques laboratoires de recherche ont fabriqués des ordinateurs dans leur coin, comme le Harvard Mark I et le Colossus Mark 1 (UK) qui ont été mis en service en 1944. Ils ont servi pour les cryptanalystes pour casser les codes utilisés par les Allemands pour leurs transmissions, pendant la seconde guerre mondiale. Les ordinateurs cités dans le précédent paragraphe étaient tous des ordinateurs dit '''électro-mécaniques''', car ils mélangeaient des composants électroniques et des composants mécaniques (tout ce qui a trait aux cartes perforées, notamment). Les composants électroniques étaient généralement des relais, à savoir des interrupteurs commandables électriquement, qui sont plus ou moins équivalents aux transistors modernes. La majeure partie des ordinateurs des années 40 étaient de ce type, mais leur nombre n'a pas dépassé 30. Il faut dire qu'ils ont rapidement laissé la place à des ordinateurs purement électroniques, que nous allons voir dans ce qui suit. ===La première génération : les tubes à vide=== [[File:Diode vacuum tube.svg|vignette|Diode vacuum tube]] Les ordinateurs qui ont suivi les ordinateurs électromécaniques sont regroupés dans la '''première génération d'ordinateur'''. Ils étaient conçus avec des tubes à vide. Les tubes à vide sont des ampoules à filament améliorées. Pour rappel, les ampoules à filament étaient des ampoules en verre dans lesquelles on plaçait un filament métallique. Le filament chauffait quand on envoyait du courant dedans et émettait de la lumière. Dans les tubes à vides, le filament n'émet pas de lumière quand on le chauffe : il émet des électrons, de l'électricité. De plus, on ajoute une plaque métalliques appelée l'anode, qui capte des électrons émis par le filament. Le résultat est un circuit qui laisse passer le courant, mais seulement dans un sens : du filament vers l'anode, l'autre sens n'est pas possible vu que l'anode ne peut pas émettre d'électrons. Un tel circuit est appelé une '''diode'''. [[File:Triode vacuum tube FR.png|vignette|Triode.]] Les tubes à vide précédents peuvent être modifiés en ajoutant une grille métallique entre la cathode et l'anode. La grille est alimentée avec une tension électrique, ce qui la charge électriquement. Suivant sa charge, elle laisse plus ou moins passer les électrons de la cathode vers l'anode. Si elle n'est pas chargée, que la tension est de 0 volt, elle ne fera pas obstacle aux électrons et le tube à vide fonctionnera comme une diode basique. Mais si la grille est chargée avec une tension négative, sa charge électrique va repousser les électrons et les empêcher de passer de la cathode vers l'anode. Le tube à vide se comporte alors comme un interrupteur : fermé ou ouvert suivant ce qu'on met sur la grille. Un tel tube à vide est appelée une '''triode''', car c'est une diode à laquelle on a ajouté une entrée pour charger la grille. De tels interrupteurs commandables électriquement sont combinés pour fabriquer des circuits plus élaborés, comme les portes logiques qu'on verra d'ici quelques chapitres. Au vu de ce qu'on vient de dire, on peut facilement deviner que les tubes à vide avaient beaucoup de défauts. Ils étaient assez encombrants, dans le sens où une ampoule prend beaucoup de place. Et il est difficile de miniaturiser une ampoule, personne n'imagine une ampoule de quelques microns de côté, alors que les transistors actuels sont plus petits que ça. De plus, ils consommaient beaucoup de courant et chauffaient. Faire chauffer un filament demande un courant important et une bonne partie de ce courant part en chaleur. De plus, ils étaient assez peu fiables et tombaient en panne assez souvent. Et s'ils étaient assez simples à fabriquer, ils restaient malgré tout chers. Les tubes à vides étaient utilisés pour le processeur et quelques circuits annexes, mais les mémoires utilisaient d'autres technologies. Les mémoires de l'époque n'étaient pas du tout des mémoires électroniques. Il existait déjà des ancêtres des disques durs, à savoir des mémoires magnétiques appelées tambours magnétiques, bandes magnétiques, mémoires à tore de ferrite, etc. Les mémoires RAM, quant à elles, utilisaient des technologies totalement abandonnées : les mémoires à lignes de délai étaient des mémoires acoustiques, les tubes Williams étaient des écrans CRT modifiés, etc. Un chapitre entier sera dédié aux technologies des mémoires de l'époque. [[File:Elektronenroehren-auswahl.jpg|centre|vignette|upright=2|Tubes à vides.]] L'usage de tubes à vide les place entre les premiers ordinateurs électro-mécaniques et les ordinateurs utilisant des transistors. Au vu de la taille des tubes à vide, les ordinateurs de l'époque étaient composés de plusieurs milliers de ces tubes, guère plus. Et malgré cela, un ordinateur prenait facilement un étage de bâtiment entier, ou au moins plusieurs pièces. La conséquence est que les ordinateurs de première génération étaient très simples, rudimentaires quand on les compare aux ordinateurs modernes. Ils ne géraient que quelques opérations simples : l'addition, la soustraction, pas grand-chose de plus. À quelques exceptions près, ils ne géraient pas la multiplication et encore moins la division, cela aurait demandé trop de tubes à vides. Une des toutes premières machines construite avec des tubes à vide était l'Atanasoff–Berry. Ce n'était pas un ordinateur, car elle ne pouvait pas exécuter de programme sans intervention humaine pour séquencer des opérations, mais c'était la première machine de calcul purement électronique, sans aucune pièce mécanique. Elle utilisait une mémoire RAM construite avec des condensateurs, ceux-ci étant placés sur des cylindres tournants. Les circuits de calcul étaient construits avec des tubes à vide et faisaient leur travail un bit à la fois. Elle fonctionnait à une fréquence de 60 Hz et pouvait faire 30 additions/soustractions par seconde. Les nombres étaient encodés sur 50 bits. [[File:Atanasoff Berry Computer.gif|centre|vignette|upright=2.5|Atanasoff–Berry.]] L'arrivée de l'ENIAC en 1945 a changé la donne. Cet ordinateur a introduit plusieurs innovations majeures. La première est assez technique, il s'agit de la turing-complétude, elle a trait aux programmes qui peuvent être écrits pour un ordinateur, nous ne la détaillerons pas ici. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] En 1948, le ''Manchester Baby'' a introduit une innovation extrêmement importante : le programme n'était plus mémorisé sur des cartes perforées, mais dans une mémoire électronique à l’intérieur de l'ordinateur lui-même. En clair, le ''Manchester Baby'' était le premier '''ordinateur à programme stocké en mémoire''' en français. Au-delà de ça, le Manchester Baby restait quand même très simple, c'était limite un prototype. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. À l'intérieur, il y avait un processeur et une RAM de 32 nombres de 32 bits, fabriquées avec des tubes Williams (abordés dans une annexe à la fin du cours). Une instruction prenant autant de place qu'un nombre en RAM, ce qui limitait les programmes à 32 instructions maximum. Le processeur gérait 8 instructions en tout, mais la seule instruction de calcul qu'il gérait était la soustraction. L'addition n'était pas supportée. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustrait. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. Contrairement à la Manchester Baby, son processeur gérait l'addition. Les multiplications étaient réalisées par des additions successives, mais le processeur intégrait des registres pour mémoriser les opérandes à multiplier. Par la suite, les ordinateurs commerciaux ont vu le jour. Les ordinateurs précédents provenaient de projets de recherches, souvent publics. Mais les entreprises privées se sont mises à fabriquer des ordinateurs elle-mêmes, pour les vendre à d'autres entreprises. On peut notamment citer les ordinateurs comme le UNIVAC I, le Bull Gamma 3 ou les premiers ordinateurs IBM. La performance de ces ordinateurs était nettement plus importante que leurs prédécesseurs, avec des fréquences de l'ordre de la centaine de kilo-hertz. Par exemple, le Bull Gamma 3 allait à 281 kHz, l'IBM 650 allait à 50 Khz. ===La seconde génération : le remplacement des tubes à vides par des transistors=== [[File:IBM 7070.jpg|vignette|Cartes imprimées de l'IBM 704, avec des transistors et résistances dessus.]] La '''seconde génération''' est celle des ordinateurs fabriqués avec des '''transistors''' isolés, reliés entre avec des fils électriques. Les transistors en question possèdent trois broches, des pattes métalliques sur lesquelles on connecte des fils électriques. Le transistor s'utilise le plus souvent comme un interrupteur commandé par sa troisième broche. Le courant qui traverse les deux premières broches passe ou ne passe pas selon ce qu'on met sur la troisième. [[File:Transistor basic flow.svg|centre|vignette|Un transistor est un morceau de conducteur, dont la conductivité est contrôlée par sa troisième broche/borne.]] Les ordinateurs de seconde génération avaient entre 1000 et 500 000 transistors. Les capacités des ordinateurs étaient donc nettement supérieures à celles des ordinateurs de première génération. Une part non négligeable des ordinateurs de seconde génération supportait l'opération de multiplication, absente sur les ordinateurs de première génération. Néanmoins, cela variait beaucoup selon les ordinateurs. Un exemple assez hors du commun est celui du premier modèle de l'IBM 1620. Le tout premier modèle n'avait aucun circuit de calcul, il n'était même pas capable de faire une addition ou une multiplication. A la place, il utilisait une table d'addition et une table de multiplication en mémoire RAM. Les deux tables devaient être initialisées par le logiciel lors du démarrage de la machine. La table d'addition faisait une centaine de chiffres, la table de multiplication faisait le double. Le processeur de l'ordinateur gérait des instructions pour faire des additions ou des multiplications, mais ces opérations lisaient le résultat dans la table d'addition. Les calculs étaient faits chiffre par chiffre, avec un encodage partiellement décimal, partiellement binaire (des chiffres décimaux étaient encodés en binaire, nous en reparlerons quand nous parlerons du BCD) ! [[File:KL CoreMemory.jpg|vignette|Mémoire à tore de ferrite.]] Les transistors n'étaient utilisés que pour le processeur et les circuits annexes. La mémoire n'était pas faite en transistors, pas à cette époque. La mémoire était une mémoire aujourd'hui abandonnée, appelée une '''mémoire à tores de ferrite'''. Elle sera détaillée dans un chapitre ultérieur. Mais sachez pour le moment qu'il s'agit d'une mémoire au support magnétique, les données étant stockées sur un support magnétique. Les transistors étaient au départ de la même taille que les tubes à vide, mais ils ont rapidement rétrécit. Ils prenaient encore beaucoup de place dans les 60-70, ce qui fait que les ordinateurs étaient assez gros. Concrètement, ils prenaient une pièce de bâtiment entière dans le meilleur des cas. C'était l'époque des gros ''mainframes'', reliés à des terminaux, peu puissants comparé aux standards actuels. Seules les grandes entreprises et les grands instituts de recherche pouvaient se payer les services de ce genre d'ordinateurs. Seuls les professionnels avaient accès à ce genre d'équipement. ===La troisième génération : le circuit intégré=== [[File:D8259AC-2.jpg|vignette|Exemple de circuit intégré.]] La troisième génération est toujours fabriquée avec des transistors, mais dont la taille a été réduite. Avec l'évolution de la technologie, les transistors ont diminué en taille, de plus en plus. Ils sont devenus tellement petits qu'ils ont fini par être regroupés dans des '''circuits intégrés''', des circuits regroupent plusieurs transistors sur la même puce de silicium. Les circuits intégrés se présentent le plus souvent sous la forme de boitiers rectangulaires, comme illustré ci-contre. D'autres ont des boitiers de forme carrées, comme ceux que l'on peut trouver sur les barrettes de mémoire RAM, ou à l'intérieur des clés USB/ disques SSD. Lors de cette génération, les processeurs étaient fournis en pièces détachées qu'il fallait relier entre elles. Le processeur était composé de plusieurs circuits intégrés séparés, impossible de mettre un processeur dans un seul boitier. Un exemple de processeur conçu en kit est la série des Intel 3000. Elle regroupe plusieurs circuits séparés aux noms à coucher dehors, mais dont vous comprendrez ce qu'ils veulent dire dans les chapitres adéquats : l'Intel 3001 est un séquenceur, l'Intel 3002 regroupe unité de calcul et registres, le 3003 est un circuit d'anticipation de retenue complémentaire du 3002, le 3212 est une mémoire tampon, le 3214 est une unité de gestion des interruptions, les 3216/3226 sont des interfaces de bus mémoire. On pourrait aussi citer la famille de circuits intégrés AMD Am2900. Même si le processeur était en pièces détachées, utiliser une dizaine de circuits intégrés était nettement mieux que d'utiliser plusieurs milliers de transistors individuels. En conséquence, les ordinateurs ont vu leur taille grandement réduite, passant de pièces entières à une simple armoire, voire à quelques cartes intégrées superposées. De plus, le prix des circuits intégré était abordable, du moins comparé aux ordinateurs d'avant. Le prix des ordinateurs a alors grandement décru, permettant à des entreprises et administrations de taille modeste de s'équiper d'ordinateurs. ===La quatrième génération : le microprocesseur=== [[File:MOS6502.svg|vignette|Microprocesseur, ici un processeur MOS6502, de la quatrième génération.]] Lors de la troisième génération, les circuits intégrés regroupaient plusieurs dizaines ou centaines de transistors, mais sont rapidement montés en gamme. De centaines de transistors, ils sont passés au millier de transistors, puis au million et maintenant au-delà du milliard. Les transistors étaient devenus tellement petits, tellement miniaturisés, qu'il était devenu possible de mettre un processeur entier dans un circuit intégré. C'est ainsi qu'est né le microprocesseur, à savoir un processeur qui tient tout entier dans un seul circuit imprimé. La quatrième génération d’ordinateur est celle des ordinateurs basés autour d'un microprocesseur. Les tout premiers microprocesseurs étaient des processeurs à application militaire, comme le processeur du F-14 CADC ou celui de l'Air data computer. Le tout premier microprocesseur commercialisé au grand public est le 4004 d'Intel, sorti en 1971. L'intel 4004 comprenait environ 2300 transistors, avait une fréquence de 740 MHz, pouvait faire 46 opérations différentes, et manipulait des entiers de 4 bits. Il était au départ un processeur de commande, prévu pour être intégré dans la calculatrice Busicom calculator 141-P, mais il fut utilisé pour d'autres applications quelque temps plus tard. Immédiatement après le 4004, les premiers microprocesseurs 8 bits furent commercialisés. Le 4004 fut suivi par le 8008 et quelques autres processeurs 8 bits extrêmement connus, comme le 8080 d'Intel, le 68000 de Motorola, le 6502 ou le Z80. Les microprocesseurs permirent encore uen fois de réduire la taille des ordinateurs, qui pouvaient tenir dans un boitier de PC, ou un boitier de console de jeu. Le prix des ordinateurs a aussi chuté en même temps que les transistors étaient miniaturisés. C'est cette invention qui permis l'invention des consoles de jeux et des mini-ordinateurs, à savoir les ordinateurs personnels. Sans miniaturisation, on n'aurait pas d'ordinateur personnel, pas de PC fixe ou portable. ==L'organisation du cours : les différents niveaux d'explication== Le fonctionnement d'un ordinateur est assez complexe à expliquer car les explications peuvent se faire sur plusieurs niveaux. Par plusieurs niveaux, on veut dire qu'un ordinateur est composé de composants très simples, qui sont assemblés pour donner des composants eux-même plus complexes, qui sont eux-même regrouper, etc. Étudier tout cela demande de voir plusieurs niveaux, allant de transistors très petits à des processeurs multicœurs. Les niveaux les plus bas sont de l'électronique pur et dure, alors que ceux plus haut sont à mi-chemin entre électronique et informatique. ===Les niveaux d'abstraction en architecture des ordinateurs=== Les trois premiers niveaux sont de l'électronique pur et dure. Ils correspondent aux premiers chapitres du cours, qui porteront sur les circuits électroniques en général. * Le premier niveau est celui des '''transistors''', des circuits intégrés, des ''wafer'' et autres circuits de très petite taille. * Le second niveau est celui des '''portes logiques''', des circuits très basiques, très simples, à la base de tous les autres. * Le troisième niveau est celui dit de la '''''Register Transfer Level''''', où un circuit électronique est construit à partir de circuits basiques, dont des registres et autres circuits dits combinatoires. Les deux niveaux suivants sont de l'informatique proprement dit. C'est dans ces deux niveaux qu'on étudie les ordinateurs proprement dit, les circuits qu'il y a dedans et non l'électronique en général. * Le quatrième niveau est celui de la '''microarchitecture''', qui étudie ce qu'il y a à l'intérieur d'un processeur, d'une mémoire, des périphériques et autres. * Le cinquième niveau est celui de l''''architecture externe''', qui décrit l'interface du processeur, de la mémoire, d'un périphérique ou autre. Par décrire l'interface, on veut dire : comment un programmeur voit le processeur et la mémoire, comment il peut les manipuler. Une architecture externe unique peut avoir plusieurs microarchitecture, ce qui fait qu'on sépare les deux. Tout cela sera plus clair quand on passera aux chapitres sur le processeur et les mémoires. Nous n'allons pas voir les 5 niveaux dans l'ordre, des transistors vers l'architecture externe. En réalité, nous allons procéder autrement. La première partie du cours portera sur les trois premiers niveaux, le reste sur les deux autres. Les 5 niveaux seront vus dans des chapitres séparés, du moins le plus possible. Au niveau pédagogique, tout est plus simple si on scinde les 5 niveaux. Bien sûr, il y a quelques explications qui demandent de voir plusieurs niveaux à la fois. Par exemple, dans le chapitre sur les mémoires caches, nous auront des explications portant sur la RTL, la microarchitecture du cache et son architecture externe. Mais le gros du cours tentera de séparer le plus possible les 5 niveaux. ===Les trois parties principales du cours=== Nous allons commencer par parler du binaire, avant de voir les portes logiques. Avec ces portes logiques, nous allons voir comment fabriquer des circuits basiques qui reviendront très souvent dans la suite du cours. Nous verrons les registres, les décodeurs, les additionneurs et plein d'autres circuits. Puis, nous reviendrons au niveau des transistors pour finir la première partie. La raison est que c'est plus simple de faire comme cela. Tout ce qui a trait aux transistors sert à expliquer comment fabriquer des portes logiques, et il faut expliquer les portes logiques pour voir le niveau de la RTL. Une fois la première partie finie, nous allons voir les différents composants d'un ordinateur. Une première partie expliquera ce qu'il y a dans un ordinateur, quels sont ses composants. Nous y parlerons de l'architecture de base, de la hiérarchie mémoire, des tendances technologiques, et d'autres généralités qui serviront de base pour la suite. Puis, nous verrons dans l'ordre les bus électroniques, les mémoires RAM/ROM, le processeur, les périphériques, les mémoires de stockage (SSD et disques durs) et les mémoires caches. Pour chaque composant, nous allons voir leur architecture externe, avant de voir leur microarchitecture. La raison est que la microarchitecture ne peut se comprendre que quand on sait quelle architecture externe elle implémente. Enfin, dans une troisième partie, nous allons voir les optimisations majeures présentes dans tous les ordinateurs modernes, avec une partie sur le pipeline et le parallélisme d'instruction, et une autre sur les architectures parallèles. Pour finir, les annexes de fin parlerons de sujets un peu à part. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | next=L'encodage des données | nextText=L'encodage des données }} </noinclude> grvzr6ea0195vj8tsrxjgbe2zt19vp1 Programmation PHP/Problèmes connus 0 72289 744164 743681 2025-06-05T15:27:25Z JackPotte 5426 /* The referenced column name 'xxx' has to be a primary key column on the target entity class */ 744164 wikitext text/x-wiki <noinclude>{{PHP}}</noinclude> Le processus de débogage est relativement le même d'un bug à l'autre : * En cas d'erreur 400, regarder d'abord les logs les plus spécifiques (ex : le var/log de l'application), puis les logs des serveurs Web (ex : /var/log/nginx), puis ceux du système (/var/log). * En cas d'erreur 500 ou de non réponse, passer directement aux logs des serveurs. * En cas d'absence de log, localiser le problème avec : ** [[../Exceptions#Logs|Des ajouts de logs supplémentaires]]. ** [[../Xdebug/]]. La liste suivante doit permettre de gagner du temps pour solutionner les erreurs que l'on peut trouver dans les logs. == Erreurs sans message PHP == === IIS tourne dans le vide après la mise à jour de PHP === Vérifier que les dépendances sont bien installées (ex : Visual C++)<ref>http://windows.php.net/download/</ref>. === Les modifications du fichier php.ini ne sont pas prises en compte dans phpinfo === Sur Wamp, redémarrer PHP et Apache ne suffit pas car Apache contient une copie du fichier <code>php.ini</code> dans <u>C:\wamp64\bin\apache\apache2.4.54.2\bin</u>, créée lors de la sélection de la version de PHP (au clic sur PHP/Version). === La connexion a été réinitialisée === Erreur sous Firefox provenant d'un <code>mysql_close()</code> ou d'une directive Apache. === La page n'est pas redirigée correctement === Un <code>header</code> revient en boucle après une suite de conditions. S'il est local, le remplacer par <code>chdir()</code>. === Le code PHP n'est pas interprété (et est affiché) === Si <code>a2enmod php7.4</code> indique que le module est déjà installé, c'est peut-être lié à <code>a2enmod userdir</code>. Cela peut se régler avec : <syntaxhighlight lang=bash> vim /etc/apache2/mods-enabled/php7.4.conf </syntaxhighlight> Commenter les lignes : <syntaxhighlight lang=apache> <IfModule mod_userdir.c> ... </IfModule> </syntaxhighlight> Et relancer Apache. Sinon c'est peut-être le vhost utilisé qui n'est pas le bon (voir /var/log/apache2) ou qu'il ne contient pas : <syntaxhighlight lang=apache> ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ <Directory "/usr/lib/cgi-bin"> Require all granted AllowOverride None Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Allow from all </Directory> </syntaxhighlight> === Les dernières lignes d'un POST sont ignorées === Il faut soit augmenter la variable PHP max_input_vars (ce qui ne peut pas être fait avec <code>ini_set()</code><ref>https://stackoverflow.com/questions/9973555/setting-max-input-vars-php-ini-directive-using-ini-set</ref>), soit il faut fragmenter en plusieurs requêtes, par exemple toutes les 300 lignes. === Une expression régulière (''regex'') marche sur https://regex101.com/ mais pas en local === Si la machine est Windows, tenir compte de la différence de retour chariot : <code>\r\n</code> au lieu de <code>\n</code>. === Une addition ou soustraction de dates ajoute ou retire un jour === Cela survient quand on part d'un mois à 31 jours pour arriver à un mois qui en a moins. Par exemple : <pre> var_dump((new DateTime('2024-12-31'))->add(new DateInterval("P6M"))); // 2025-07-01 00:00:00 var_dump((new DateTime('2024-12-31'))->add(new DateInterval("P12M"))); // 2025-12-31 00:00:00 </pre> Pour avoir un calcul juste, on peut ajuster le jour du résultat ainsi : <pre> $startDate = new DateTime('2024-12-31'); $originalDay = $startDate->format('d'); $startDate->add(new DateInterval('P6M')); if ($startDate->format('d') !== $originalDay) { // Ajuster au dernier jour du mois précédent $startDate->modify('last day of previous month'); } var_dump($startDate); // 2025-06-30 00:00:00 </pre> === Une addition ou soustraction de dates ajoute ou retire une heure === C'est à cause des changements d'heure d'hiver et heure été. Par exemple : <pre> var_dump((new DateTime('2024-12-31'))->add(new DateInterval("PT4320H"))); // 2025-06-29 01:00:00 var_dump((new DateTime('2024-12-31'))->add(new DateInterval("PT8640H"))); // 2025-12-26 00:00:00 </pre> Pour avoir un calcul juste, on peut changer de fuseau horaire le temps du calcul, vers un qui n'est pas soumis aux changements d'heures<ref>https://stackoverflow.com/questions/804571/how-to-subtract-two-dates-ignoring-daylight-savings-time-in-php</ref> : <pre> var_dump((new DateTime('2024-12-31 UTC'))->add(new DateInterval("PT4320H"))); // 2025-06-29 00:00:00 var_dump((new DateTime('2024-12-31 UTC'))->add(new DateInterval("PT8640H"))); // 2025-12-26 00:00:00 </pre> ou à l'échelle du serveur : <pre> $timeZone = date_default_timezone_get(); date_default_timezone_set('UTC'); // calcul date_default_timezone_set($timeZone); </pre> == PHP natif == === Connect Error, 2002: Aucune connexion n'a pu être établie car l'ordinateur cible l'a expressément refusée. === Relancer le serveur de base de données. === Connect Error, 2002: Une tentative de connexion a échoué car le parti connecté n'a pas répondu convenablement au-delà d'une certaine durée ou une connexion établie a échoué car l'hôte de connexion n'a pas répondu. === Ouvrir les pare-feux. === Invalid body indentation level (expecting an indentation level of at least 8) === En PHP7.3, la syntaxe heredoc impose de supprimer l'indentation de la balise fermante : elle soit suivre "\n". === json_decode renvoie NULL (aléatoirement) === Ajouter le paramètre 4 : JSON_THROW_ON_ERROR. === json_decode throw "Control character error, possibly incorrectly encoded" === La string à décoder est trop longue. === Malformed UTF-8 characters, possibly incorrectly encoded === Changer l'encodage de la chaine avant son encodage en JSON, avec<ref>https://stackoverflow.com/questions/31115982/malformed-utf-8-characters-possibly-incorrectly-encoded-in-laravel</ref> : $chaine = mb_convert_encoding($chaine, 'UTF-8', 'auto'); === MySQL server has gone away === La limite des 61 jointures a peut-être été atteinte dans une requête. Sinon vérifier les limites des ressources (du .ini) : par défaut default_socket_timeout égal 60 s. === This extension requires the Microsoft ODBC Driver 11 for SQL Server === Installer le pilote depuis https://www.microsoft.com/en-us/download/details.aspx?id=36434. === Unable to initialize module. Module compiled with module API=x. PHP compiled with module API=y. These options need to match === Se procurer une autre DLL à renseigner dans le fichier <code>php.ini</code>. === You can only iterate a generator by-reference if it declared that it yields by-reference === Se produit quand on itère sur la référence d'un générateur PHP : <syntaxhighlight lang="php"> foreach ($generator as &$item) { ... } </syntaxhighlight> Il faut donc retirer l'opérateur de référence (&) de l'itération... === Cannot traverse an already closed generator === Un <code>iterator_to_array($generator)</code> le ferme en le convertissant en tableau. === child exited on signal 7 (SIGBUS) === Modifier le fichier <code>php.ini</code><ref>https://whynhow.info/17522/How-to-get-rid-of-SIGBUS-when-running-php-fpm?</ref> : <syntaxhighlight lang="ini"> pm.max_children = 80 pm.max_spare_servers = 20 pm.max_requests = 200 apc.stat = 0 </syntaxhighlight> <code>max_children</code> est calculé en divisant la RAM par la taille des processus<ref>https://www.kinamo.fr/fr/support/faq/determiner-le-nombre-de-processes-valide-pour-php-fpm-sur-nginx</ref>. === Invalid resource type: unknown type === Le paramètre n°2 de <code>fopen()</code> ne permet pas la lecture<ref>https://www.php.net/manual/fr/function.fopen.php</ref>. === Each stream must be readable === On essaie de lire un fichier fermé : déplacer le <code>fclose()</code> après s'il y en a un avant. === fclose(): supplied resource is not a valid stream resource === On essaie de fermer un fichier fermé : utiliser <code>if (is_resource($f))</code> avant. === SSL peer certificate or SSH remote key was not OK === Lors d'un <code>curl_exec</code>, ajouter : <syntaxhighlight lang="php"> curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); </syntaxhighlight> ou : <syntaxhighlight lang="php"> $options['verify_host'] = false; $options['verify_peer'] = false; </syntaxhighlight> === Fatal error === ==== {{rouge|[] operator not supported for strings}} ==== <syntaxhighlight lang="php"> // On récupère une variable dont on ne connait pas le type pour en faire un tableau if (!isset($tableau1)) { $tableau1 = array(); } elseif (is_string($tableau1)) { $tableau1 = array($tableau1); } $tableau1[] = 'paramètre suivant'; </syntaxhighlight> ==== {{rouge|Allowed memory size of x bytes exhausted}} ==== Modifier le fichier <code>php.ini</code> ou bien ajouter une autre limite dans le programme : <syntaxhighlight lang="php"> ini_set('memory_limit', '100M'); </syntaxhighlight> Pour faire sauter la limitation : <syntaxhighlight lang="php"> ini_set('memory_limit', '-1'); </syntaxhighlight> Si c'est dans une commande : php -d memory_limit=-1 ma_commande Si c'est Composer : COMPOSER_MEMORY_LIMIT=-1 ./composer.phar update Sinon, utiliser Xdebug en mode pas à pas pour visualiser les variables à supprimer (avec <code>unset()</code>). ==== {{rouge|Call to a member function ... on a non-object}} ==== La méthode est invoquée sur une variable qui n'est pas une classe. ==== {{rouge|Call to undefined function}} ==== Si une fonction est définie mais qu'on ne peut pas l'invoquer dans une méthode de classe, il faut préalablement l'importer en tenant compte du [[../Programmation_orientée_objet#Polymorphisme|polymorphisme]]. ===== {{rouge|Call to undefined function sqlsrv_connect()}} ===== Installer le pilote correspondant à la version de PHP du serveur Web : # Télécharger sur https://www.microsoft.com/en-us/download/details.aspx?id=20098. # Copier dans le dossier PHP (ex : <u>C:\Program Files (x86)\EasyPHP\binaries\php\php_runningversion\ext</u>). # Ajouter au fichier <code>php.ini</code>. # Redémarrer le serveur Web. ==== {{rouge|Call to undefined method}} ==== La méthode est invoquée sur une classe qui ne l'a pas. Si elle est censée l'avoir c'est qu'elle n'est pas récupérée, ce qui peut arriver avec les jointures entre entités d'ORM. ==== {{rouge|Cannot access empty property}} ==== Une variable non définie ne peut pas fournir de propriété. Si elle était définie ailleurs c'est qu'elle est inaccessible, et donc qu'il faut la récupérer (ex : avec <code>global</code>). ==== {{rouge|Error connecting to the ODBC database: [Microsoft][SQL Server Native Client 10.0][SQL Server]échec de l'ouverture de session de l'utilisateur}} ==== La précédente connexion n'a pas dû être fermée proprement avant une tentative de reconnexion. Essayer au choix : <syntaxhighlight lang="php"> mysql_close($conn); // MySQL sqlsrv_close($conn); // MS-SQL odbc_close($conn); // ODBC </syntaxhighlight> ==== {{rouge|Out of memory}} ==== Éditer le fichier <code>php.ini</code> pour augmenter la limite mémoire : memory_limit = 256M Si cela ne suffit pas, vérifier la taille des structures et tableaux alloués, probablement par une boucle avec trop d'itérations ou une boucle infinie, ou le chargement d'une ressource trop volumineuse en mémoire. ==== {{rouge|pdo_sqlsrv_db_handle_factory: Unknown exception caught}} ==== Installer et configurer le paquet suivant : <syntaxhighlight lang="bash"> apt-get install -y locales echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && locale-gen </syntaxhighlight> ==== {{rouge|Uncaught exception 'com_exception' with message 'Failed to create COM object `xxx.application': Accès refusé.}} ==== Sur le serveur Web Windows, dans ''démarrer'', exécuter ''dcomcnfg'' (sinon y aller dans ''Outils d'administration'', ''Service de composants''), puis ''Ordinateurs'', ''Poste de travail'', ''Configuration DCOM'', aller dans les propriétés de l'application mentionnée, puis dans l'onglet ''Sécurité'', définir la première permission (''Autorisations d'exécution et d'activation'' à ''Personnaliser'' et ajouter le compte du serveur ou site qui exécute le script (ex pour ISS : IIS_IUSRS ou IUSR). Par exemple pour Word l'application se prénomme "Document Microsoft Office Word", et Excel "Microsoft Excel Application". ==== {{rouge|Uncaught exception 'com_exception' with message 'Source: Microsoft Office Excel Description: Mémoire insuffisante.}} ==== Il faut certainement rerégler la Configuration DCOM voire le serveur Web. ==== {{rouge|Uncaught exception 'PDOException' with message}} ==== ===== {{rouge|could not find driver}} ===== Se référer à la liste des pilotes connus dans [[../PDO#Installation]]. ===== {{rouge|SQLSTATE[HY000]: General error}} ===== PDO ne gère pas le code SQL "set @ma_variable" ou "if". Donc il faut plutôt faire ces calculs en PHP. ===== {{rouge|SQLSTATE[28000] [1045] Access denied for user}} ===== Si l'utilisateur existe avec les privilèges nécessaires, y compris depuis toute localisation (@%), il faut quand-même créer un deuxième compte homonyme pour l'emplacement distant (ex : 'username'@'example.com'). Par exemple dans phpMyAdmin, remplir la provenance mentionnée en erreur ('example.com') dans le champ "Client". ===== {{rouge|SQLSTATE[28000] SQLConnect: 18456 [Microsoft][ODBC SQL Server Driver][SQL Server] Échec de l'ouverture de session de l'utilisateur}} ===== Se référer à [[../PDO#Accès à la base de données avec PDO]] : la source de données ODBC doit être suivie du compte pour y accéder. ===== {{rouge|SQLSTATE[IM002] SQLConnect: 0 [Microsoft][Gestionnaire de pilotes ODBC] Source de données introuvable et nom de pilote non spécifié}} ===== Se référer à [[../PDO#Accès à la base de données avec PDO]] : la source de données ODBC doit être créée dans <u>C:\Windows\SysWOW64\odbcad32.exe</u>. ===== {{rouge|SQLSTATE[IMSSP]: An invalid keyword 'host' was specified in the DSN string}} ===== Se référer à [[../PDO#Accès à la base de données avec PDO]] : le paramètre 'host' est valide pour MySQL mais pas pour MS-SQL. ===== {{rouge|SQLSTATE[IMSSP]: The DSN string ended unexpectedly}} ===== Se référer à [[../PDO#Accès à la base de données avec PDO]] : les virgules et points-virgules changent d'un pilote à l'autre. ===== {{rouge|SQLSTATE[IMSSP]: This extension requires the Microsoft SQL Server 2012 Native Client ODBC Driver to communicate with SQL Server}} ===== Se référer à [[../PDO#Accès à la base de données avec PDO]] : utiliser la syntaxe ODBC. === Notice === ==== {{rouge|Undefined property}} ==== La propriété de la variable n'est pas déclarée. ==== {{rouge|Undefined index: SERVER_NAME in ...php}} ==== Certaines versions de PHP utilisent <code>$_SERVER['HTTP_HOST']</code> au lieu de <code>$_SERVER['SERVER_NAME']</code>. ==== {{rouge|Undefined variable}} ==== La variable n'est pas déclarée. ==== {{rouge|Use of undefined constant}} ==== La constante n'est pas déclarée. === Parse error === ==== {{rouge|syntax error, unexpected '(', expecting variable (T_VARIABLE) or '$' in...}} ==== Séparer le $ dans la chaine (ex : <code>{$</code> -> <code>{ $</code>). ==== {{rouge|syntax error, unexpected <nowiki>''</nowiki> (T_ENCAPSED_AND_WHITESPACE), expecting identifier (T_STRING) or variable (T_VARIABLE) or number (T_NUM_STRING)}} ==== Remplacer les variables incluses dans des chaines. Ex : <syntaxhighlight lang="php"> $query="select $contact['member']"; // pas bien $query="select ".$contact['member']; // bien </syntaxhighlight> ==== {{rouge|syntax error, unexpected '$Variable' (T_VARIABLE), expecting function (T_FUNCTION)}} ==== Dans une classe en dehors des méthodes, il faut déclarer les variables avec leur portée : <syntaxhighlight lang="php"> private $Variable; </syntaxhighlight> === Strict Standards === ==== {{rouge|Declaration of extFunctions::logs() should be compatible with functions::logs($chaine)}} ==== La fonction (<code>logs()</code> dans l'exemple) existe déjà, peut-être avec des majuscules (peu importe les arguments). ==== {{rouge|Only variables should be passed by reference}} ==== Il faut appliquer la fonction <code>end()</code> sur une variable au lieu du résultat d'une opération<ref>http://stackoverflow.com/questions/4636166/only-variables-should-be-passed-by-reference</ref>. Ex : <syntaxhighlight lang="php"> // $extension = end(explode('.', $fichier)); $ext = explode('.', $fichier); $extension = end($ext); </syntaxhighlight> === Warning === ==== {{rouge|Cannot use a scalar value as an array}} ==== Un tableau de valeurs ne peut pas être redéfini en tableau de tableaux si elles existent. Remplacer les cas ainsi : <syntaxhighlight lang="php"> $tab['1'] = 1; //$tab['1']['un'] = 'un'; $tab['un']['un'] = 'un'; </syntaxhighlight> ==== {{rouge|Creating default object from empty value}} ==== Se produit quand on appelle l'attribut d'un objet NULL. ==== {{rouge|date_diff() expects parameter 1 to be DateTimeInterface}} ==== La classe native <code>DateTime()</code> est plus pratique que la fonction <code>date_diff()</code> : <syntaxhighlight lang="php"> $Avant = new DateTime('20140101'); $Apres = new DateTime(); print $Avant->diff($Apres)->format("%d"); </syntaxhighlight> ==== {{rouge|Illegal string offset}} ==== On invoque une entrée inexistante dans un tableau associatif. Lever l'exception avec <code>Try</code> ou <code>if (!isset(</code>. ==== {{rouge|mkdir(): File exists}} ==== Sous Docker Desktop pour Windows, mkdir() appelle file_exists(), et ce dernier renvoie ''true'' si le dossier a existé. ==== {{rouge|PHP Startup: Unable to load dynamic library 'memcached.so'}} ==== sudo pecl install memcached Si cela persiste : sudo apt-get install php-igbinary sudo apt-get install php-msgpack sudo service php7.2-fpm reload ==== {{rouge|PHP Startup: Unable to load dynamic library 'redis.so'}} ==== sudo pecl install redis == Erreurs SMTP == === ''La connexion a échoué'' === Vérifier le serveur HTTP qui interprète le fichier <code>.php</code>. === ''SMTP Error: Could not connect to SMTP host'' === Changer de SMTP, ex : http://www.commentcamarche.net/faq/893-parametres-de-serveurs-pop-imap-et-smtp-des-principaux-fai === Si les mails partent sans arriver === * Vérifier que l'IP de l'expéditeur n'est pas blacklistée : http://whatismyipaddress.com/blacklist-check * Définir un reverse DNS si absent * Veiller à ce que le mail ne soit pas présumé spam, en évitant les sujets vides par exemple, ou les pièces jointes exécutables non compressées (.exe, .cmd, .vbs...). == Composer == === 1 package has known vulnerabilities === Exemple avec un <code>guzzlehttp/guzzle (7.4.3)</code> absent du composer.json : composer depends guzzlehttp/guzzle puis <code>composer update</code> du résultat. Si cela ne suffit pas, installer Guzzle puis le désinstaller pour mettre à jour sa dépendance indirecte : composer require guzzlehttp/guzzle && composer remove guzzlehttp/guzzle === "./composer.json" does not contain valid JSON === Lors d'un ''composer install'', si ce message survient à tort, c'est qu'un autre fichier .json du projet contient le problème. Si cela persiste malgré la correction, il se peut qu'il faille redémarrer Docker Desktop sur Windows. === Conclusion: don't install xxx === Lors d'un ''composer require'', spécifier une version inférieure du paquet requis. === No driver found to handle VCS repository === VCS fonctionne en protocole git, vérifier que l'URL est bien au format "git@repo:bundle.git". Sinon il y a deux alternatives : * Pour HTTPS, remplacer la dépendance de type "vcs" par une de type "package"<ref>https://stackoverflow.com/questions/24443318/getting-error-no-driver-found-to-handle-vcs-repository-on-composer-and-svn?answertab=votes#tab-top</ref>. * Pour décompresser un .zip, utiliser le type "artifact". === no matching package found === Ajouter le paramètre suivant : composer require mon_paquet --update-with-all-dependencies === Permission denied (public key) === Si le dépôt privé se clone bien sans passer par "composer" : voir la page [[Programmation PHP/Composer]]. === You must be using the interactive console to authenticate === Pour installer cette bibliothèque, il faut que Composer puisse se loguer. Pour ce faire, il utilise auth.json qui peut se trouver dans<ref>https://getcomposer.org/doc/articles/http-basic-authentication.md</ref> : # <code>$HOME/.composer/auth.json</code> # ou à côté du <code>composer.json</code> Exemple de auth.json<ref>https://github.com/magento/magento2/issues/2523#issuecomment-159884152</ref> : <syntaxhighlight lang="json"> { "github-oauth": { "github.com": "<snip>" }, "http-basic": { "repo.magento.com": { "username": "<snip>", "password": "<snip>" } } } </syntaxhighlight> === Your Composer dependencies require a PHP version ">= 8.0.0". === Ajouter au paragraphe "config" : <syntaxhighlight lang="json"> "platform-check": false </syntaxhighlight> Puis relancer <code>composer install</code> pour que cela soit pris en compte. === Your requirements could not be resolved to an installable set of packages === Si deux dépendances s'empêchent mutuellement de se mettre à jour, les demander dans la même commande : <syntaxhighlight lang="bash"> composer require mon-bundle ^1.0 symfony/http-client 5.3.* -W </syntaxhighlight> === Timeout sur composer install === Désactiver Xdebug et relancer. == PHPUnit == === Les tests ne se lancent pas === Si phpunit.xml.dist utiliser un bootstrap.php, y ajouter <code>error_reporting(E_ALL);</code>. Sinon, si un var_dump() fonctionne dans le setUp() du test unitaire mais pas dans ses méthodes de test, c'est peut-être une exception qui se lance dans un trait ou dans le vendor PHPUnit. Pour la trouver, lancer l'application et regarder les logs (par exemple depuis un contrôleur). Sinon, si ça fonctionne en commentant le "extends", tester la classe mère pour y trouver l'exception. Sinon, dans Symfony, <code>tail var/log/test/mon_log.log</code>. Sinon, lancer Xdebug pour comprendre. === et echo() ou var_dump() dans les tests n'affiche rien === Lancer le test en mode le plus verbeux : * Avec le paramètre : -vvv * Modifier phpunit.xml.dist avec : ** <nowiki><server name="SHELL_VERBOSITY" value="3" /></nowiki><ref>https://symfony.com/doc/current/console/verbosity.html</ref> ** <nowiki><ini name="error_reporting" value="true" /></nowiki> === Les tests fonctionnels renvoient toujours 404 === Sur Symfony, <code>self::createClient()</code> appelle directement l'API sans serveur HTTP. Si on utilise phpunit dans symfony/phpunit-bridge, il va chercher sur example.com. Sinon il manque peut-être un trailing slash dans la route appelée. === Les tests se lancent mais s'arrêtent sans explication, en renvoyant "killed" === Un var_dump() sature la mémoire. === Did you forget a "use" statement for MaClasse ''ou'' Class 'MaClasse' not found === Si des classes existent mais que PHPUnit n'arrive pas à les charger : * Vérifier les namespaces racines définis dans composer.json par ''autoload'' et ''autoload-dev''. * Retirer ''suffix=".php"'' du phpunit.xml utilisé. === The .git directory is missing from... === Supprimer vendor/ et relancer composer. === THE ERROR HANDLER HAS CHANGED! === Plusieurs solutions possibles : * phpunit --self-update * Dans Symfony, changer phpunit.xml.dist avec SYMFONY_DEPRECATIONS_HELPER = weak_vendors * set_error_handler(array(&$this, 'handleGeoError')); * Si le projet Symfony a Sentry, on peut le retirer des tests dans bundles.php. === Trying to configure method "get" which cannot be configured because it does not exist, has not been specified, is final, or is static === Un mock ne récupère aucune méthode de sa classe car elle n'a pas pu être instanciée. * La casse du nom de la classe ou du namespace de son <code>use</code> n'est probablement pas exacte. * Sinon c'est la portée de la méthode mockée qui n'a pas publique. Si un dump du mock montre les attributs mais pas les méthodes, remplacer <code>->getMockForAbstractClass()</code> par <code>->getMock()</code>. * S'il s'agit d'une méthode finale, il faut la définir lors de l'instanciation du mock. Ex : <syntaxhighlight lang="php"> $this->serializerMock = $this ->getMockBuilder(SerializerInterface::class) ->setMethods(['serialize', 'deserialize', 'decode']) ->getMock() ; $this->serializerMock ->method('decode') ->willReturn('') ; </syntaxhighlight> === Trying to @cover or @use not existing method === Si la méthode existe bien, c'est que la classe testée n'a pas été définie en annotation (avec son namespace) : <syntaxhighlight lang="php"> /** * @coversDefaultClass App\Service\MyService */ class MyServiceTest extends TestCase { ... } </syntaxhighlight> === TypeError: Argument 1 passed to PHPUnit\Framework\TestCase::registerMockObjectsFromTestArguments() must be of the type array, null given === Si cela survient dans tous les tests qui invoquent un trait, retirer le constructeur de ce trait. === Warning No tests found in class "Xxx". === Si les méthodes de tests contiennent des assertions invisibles de PHPUnit, leur ajouter <code>/** @test */</code> pour afficher pourquoi ils ne se lancent pas. Par exemple, il peut s'agir d'un mock qui demande un constructeur. Si c'est normal de ne pas lancer de test dans une classe mère, la rendre abstraite ou statique. == Symfony == [[Image:Symfony 2.8 - Profiler.png|vignette|Profiler sous Symfony 2.8.|upright=2]] En cas d'erreur, un composant de débogage appelé "Profiler", est accessible en bas à gauche de la page d'erreur, avec des logs et mesures de performances. Installation : <pre> composer require --dev symfony/profiler-pack </pre> On peut par exemple accéder au phpinfo() via l'URL <u>.../_profiler/phpinfo</u>. {{attention|Le profiler fonctionne pour les contrôleurs mais pas pour les commandes.|clear=left}} === La première soumission d'un formulaire ne marche pas, mais les suivantes oui === Retirer le : <pre> $uow = $em->getUnitOfWork(); $uow->computeChangeSets(); </pre> === Le contrôle de formulaire avec name=‘xxx’ ne peut recevoir le focus. === Il s'agit généralement d'un champ caché : le passer en required=false ou faire en sorte qu'il soit toujours rempli même caché. === Un champ de formulaire ChoiceType n'affiche pas sa valeur par défaut, qui est pourtant dans la liste === La liste contient une clé d'un type different. Exemple de solution : <pre>'data' => (string) $myInteger,</pre> === Une route de contrôleur fonctionne dans un client HTTP mais pas dans un autre === Si $request est vide avec certains clients HTTP : * Utiliser HTTPS au lieu de HTTP. * Vérifier les paramètres d'en-tête HTTP (Accept: 'application/json' et Content-Type: 'application/json'). * Utiliser $request->getContent() ou ou $request->toArray() au lieu de $request->request<ref>https://silex.symfony.com/doc/2.0/cookbook/json_request_body.html</ref> (ça ne marche pas à la place de $request->query). === Une route de contrôleur fonctionne dans un client HTTP mais pas en PhpUnit, ex : No matching accepted Response format could be determined (406 Not Acceptable) === <syntaxhighlight lang="bash"> composer remove friendsofsymfony/rest-bundle </syntaxhighlight> === Attempted to load class "WebProfilerBundle" from namespace "Symfony\Bundle\WebProfilerBundle" === Si cela fonctionne avec "composer install" mais pas avec " composer install --no-dev", il faut définir <code>APP_ENV=prod</code> dans le .env. === Attribute "autowire" on service "xxx" cannot be inherited from "_defaults" when a "parent" is set. Move your child definitions to a separate file or define this attribute explicitly. === Lors d'utilisation de service abstrait, on ne peut pas utiliser l'autowiring. On peut alors {{w|lang=en|Composition over inheritance|transformer ce service abstrait en dépendance à injecter plutôt qu'à hériter}}. === Cannot autowire service... alors qu'il existe === Peut se produire : * quand le dossier de la classe est dans "App\.exclude" du services.yaml. * quand il n'est pas exclus et qu'on le déclare dans un .yaml importé dans services.yaml (donc en doublon de l'autowiring). Il faut alors soit le désactiver, soit exclure les namespaces concernés, soit déplacer ces déclarations dans services.yaml. * dans un bundle, si <code>$loader->load('services.yaml');</code> est bien effectué<ref>https://symfony.com/doc/current/bundles/configuration.html</ref>, alors le déclarer dans le services.yaml du bundle. Sinon, vérifier qu'il n'y a pas un chemin erroné dans l'extension prepend(). * Depuis Symfony 6.1 on peut utiliser l'attribut <code>#[Autowire]</code><ref>https://symfony.com/doc/current/service_container/autowiring.html</ref>. <syntaxhighlight lang=php> #[AsEventListener(event: KernelEvents::CONTROLLER)] class MyListener { public function __construct( private readonly Security $security, // exemple private readonly ControllerResolverInterface $controllerResolver ) { } } </syntaxhighlight> L'erreur est : <blockquote>Cannot autowire service "App\EventListener\MyListener": argument "$controllerResolver" of method "__construct()" references interface "Symfony\Component\HttpKernel\Controller\ControllerResolverInterface" but no such service exists. You should maybe alias this interface to one of these existing services: "debug.controller_resolver", "debug.controller_resolver.inner".</blockquote> La solution est d'écrire : <syntaxhighlight lang=php> #[AsEventListener(event: KernelEvents::CONTROLLER)] class MyListener { public function __construct( private readonly Security $security, // exemple #[Autowire(service: 'controller_resolver')] private readonly ControllerResolverInterface $controllerResolver ) { } } </syntaxhighlight> === Cannot load resource "../../src/Controller/". Make sure to use PHP 8+ or that annotations are installed and enabled. === <syntaxhighlight lang="bash"> composer require sensio/framework-extra-bundle </syntaxhighlight> === Circular reference detected === L'autoloader se heurte à un argument du constructeur d'une classe : il faut le sortir de la méthode <code>__construct()</code> pour le définir dans une méthode portant son nom. Exemple de déclaration en YAML : <syntaxhighlight lang="yaml"> app.ma_classe: class: App\MaClasse arguments: - '@service.sans.probleme' calls: - method: setServiceAvecProbleme arguments: - '@service.avec.probleme' tags: - { name: doctrine.event_subscriber } </syntaxhighlight> ==== A circular reference has been detected when serializing the object ==== Idem en <code>fetch="EXTRA_LAZY"</code> dans l'entité. Pour résoudre cela sans changer de relation entre les entités, il y a plusieurs solutions : * Dans l'entité, <code>use Symfony\Component\Serializer\Annotation\Ignore;</code> et annotation <code>/** @Ignore() */</code> au dessus de l'attribut en erreur. * Dans le contrôleur, éviter de renvoyer la réponse brute, mais filtrer les attributs avec <code>use Symfony\Component\Serializer\SerializerInterface;</code> et <code>$this->serializer->serialize($data, 'json', $context)</code>. === curl error 6 while downloading https://flex.symfony.com/versions.json: Could not resolve host: flex.symfony.com === <syntaxhighlight lang=bash> composer update symfony/flex --no-plugins --no-scripts </syntaxhighlight> === CURLPIPE_HTTP1 is no longer supported === Si cela se produit sur un projet Symfony avec composer, il faut juste : <syntaxhighlight lang="bash"> composer global require symfony/flex ^1.5 rm -Rf vendor/symfony/flex </syntaxhighlight> === Environment variables "xxx" are never used. Please, check your container's configuration. === Pazsser par des variables intermédiaires dans services.yaml : <syntaxhighlight lang="yaml"> yyy: '%env(xxx)%' </syntaxhighlight> === Error 400 Bad Request ''Your browser sent a request that this server could not understand.'' === Les règles de réécriture d'URL Apache sont erronées (voir ci-dessous). === Error 404 Not Found ''The requested URL /xxx was not found on this server.'' === Si la page d'accueil fonctionne mais pas les sous-pages (alors qu'un nom de domaine est déjà dédié au site dans le vhost), les règles de réécriture d'URL de la configuration Apache sont manquantes ou erronées. Il faut donc créer <code>public/.htaccess</code> : <syntaxhighlight lang="apache"> <IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php [QSA,L] </IfModule> </syntaxhighlight> === Invalid header: CR/LF/NUL found === Un JSON envoyé en POST dans symfony/http-client contient des retours chariots inattendus : les retirer. Ex : <syntaxhighlight lang="php"> $json = preg_replace("(\r?\n)", '', $json); </syntaxhighlight> === manifest.json does not exist === yarn install && yarn add --dev @symfony/webpack-encore && yarn build === Maximum function nesting level of '6000' reached === Si cela se produit par exemple en vidant le cache, c'est que deux services se renvoient la balle (même indirectement) depuis leurs constructeurs. === NetworkError when attempting to fetch resource (Firefox) / Failed to fetch (Chrome) === Dans l'API avec Swagger UI : violation du CQRS empêchant l'affichage du résultat de l'API dans /api/doc, à causes des domaines. Sur un domaine local, cela peut être résolu en changeant l'URL avant /api/doc pour qu'elle soit valide (ex : passer de wikibooks/api/doc à wikibooks.org/api/doc). Sinon réessayer en HTTP au lieu de HTTPS. Sinon c'est la clé renseignée (du .env) qui est différente de celle en BDD. Si le serveur Web est Nginx, retirer du vhost "add_header Access-Control-Allow-Origin *;" et "limit_exept". === request->request et request->query sont vides à tort === Utiliser $request->getContent() ou $request->toArray() à la place<ref>https://symfony.com/doc/5.4/components/http_foundation.html</ref>. === SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known === Un service inexistant ou avec des paramètres en erreur est appelé. Cela peut être provoqué par une variable d'environnement d'URL manquante ou erronée (ex : retirer le protocole, ou ajouter la version du SGBD). === SSL certificate problem: unable to get local issuer certificate === Utiliser l'installation avec "Composer.phar" plutôt que "Symfony.phar". === InvalidArgumentException Invalid env(bool:xxx) name: only "word" characters are allowed === Soit retirer la résolution "bool:" sur la variable d'environnement concernée, soit la renommer si elle contient des symboles autres que des lettres, des nombres ou underscore (ex : "=", "%", ":", etc.). === The autoloader expected class "App\MaClasse" to be defined in file "/var/www/.../MaClasse.php". The file was found but the class was not in it, the class name or namespace probably has a typo. === Revérifier que : * le fichier a bien l'extension .php * la balise ouvrante <code><?php</code> * comporte bien la classe du même nom à la majuscule prêt * avec le bon namespace et qui correspond aux dossiers (vérifiable dans la déclaration avec CTRL + clic dans PhpStorm). === Uncaught ReflectionException === Si c'est lors du passage de PHP 7 à 8, essayer de lancer le script sans Symfony pour avoir le détail (ex : utiliser PhpUnit directement au lieu de PhpUnit bridge). Cela peut par exemple provenir de return type différents entre une interface (ex : ArrayAccess) et son implémentation. === You have requested a non-existent parameter "kernel.secret". Did you mean this: "kernel.charset"? === À l'installation d'une dépendance, si les champs sont renseignés dans config/packages, alors c'est qu'ils ne sont pas chargé dans le bundle par Kernel.php. Peut se traduire aussi par des erreurs de chargement de bundle du type : ''The child config "x" under "y" must be configured.'' === "The controller for URI \"/api/ma_route/123\" is not callable: Controller \"MonController\" does neither exist a service nor as class." === Si <code>bin/console debug:autowiring --all</code> montre le service et <code>bin/console debug:route</code> la route, renseigner routes.yaml et vider le cache. Ex : <syntaxhighlight lang="yaml"> index: methods: DELETE path: /api/ma_route/{id} controller: App\Controller\MonController::__invoke </syntaxhighlight> Si ça ne fonctionne pas, passer par un évènement sur la méthode générique. === Doctrine === ==== Le champ ne se sauvegarde pas en base ==== * Est-ce qu'il y a le flush après la modification du champ ? * Le cache Doctrine a-t-il bien été vidé depuis l'ajout du champ ? * Est-il bien dans la variable, sinon est-il mappé dans un formulaire ? * Est-il en annotation PHP alors que Symfony est configuré pour les attributs ? * Est-il qu'il y a eu un clear() avant le flush(), ce qui aurait détaché l'entité à sauvegarder ? ==== Le champ sauvegardé en base est toujours 0 ==== Se produit quand on utilise l'annotation <code>@ORM\GeneratedValue(strategy="IDENTITY")</code> sur un champ qui n'est pas ''AUTOINCREMENT'' en base de données. ==== A new entity was found through the relationship 'X' that was not configured to cascade persist operations for entity: X. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}) ==== * Dans le cas d'un Doctrine\ORM\ORMInvalidArgumentException: ** Si on est en train de suppriemr une entité, il manque son retrait d'une collection au préalable (ex : <code>$entityToKeep->removeEntityToDelete($entityToDelete)</code>); ** Un service a un tag et un argument constructeur incompatible. Ce service en argument fait un $em->clear() au lieu de clear(object), ou persist(object) au lieu de merge(object). * Dans le cas "Multiple non-persisted new entities were found through the given association graph" ** Ajouter un persist dans l'entité ou avant le flush. ** Sinon, on tente de flusher une entité récupérée, ou dont une de ses entités liées a été récupérée, par l’entityManager d'un replica SQL (potentiellement non répliqué). Utiliser la base de données maitresee à la place. ** Sinon c'est que le même flush est réalisé plusieurs fois : ajouter du cache d'instance pour ne pas ré-exécuter ce code. ==== Binding an entity with a composite primary key to a query is not supported ==== Se produit quand on utilise la méthode magique find() d'un repository sur une entité qui a une clé composite (au moins deux attributs avec <code>@ORM\Id</code>). Il faut alors utiliser <code>findBy(['id' => xxx])</code>. ==== Call to undefined function Closure at EventDispatcher.php:299 ==== Ajouter dans composer.json : <syntaxhighlight lang="json"> "conflict": { "symfony/symfony": "*", "doctrine/common": ">=3.0", "doctrine/persistence": "<1.3" }, </syntaxhighlight> Puis lancer "composer update". ==== Cannot autowire service "App\Components\CRM\Repository\MonRepository": argument "$class" of method "Doctrine\ORM\EntityRepository::__construct()" references class "Doctrine\ORM\Mapping\ClassMetadata" but no such service exists. ==== Se produit avec l'autowiring, quand on ajoute l'annotation vers un repo dans une entité. Ex : @ORM\Entity(repositoryClass="App\MonRepository") En fait depuis Doctrine 1.8<ref>https://www.it-swarm.dev/fr/php/service-autowire-impossible-largument-fait-reference-la-classe-mais-ce-service-nexiste-pas/836794307/</ref>, le repository doit étendre "ServiceEntityRepository" au lieu de "EntityRepository", et avoir un constructeur. Par exemple : <syntaxhighlight lang="php"> use App\Entity\MonEntite; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Symfony\Bridge\Doctrine\ManagerRegistry; // anciennement Doctrine\Persistence\ManagerRegistry; class MonEntiteRepository extends ServiceEntityRepository { public function __construct(ManagerRegistry $registry) { parent::__construct($registry, MonEntite::class); } </syntaxhighlight> ==== Cannot select entity through identification variables without choosing at least one root entity alias ==== Retirer les <code>->addSelect()</code> du queryBuilder, ou utiliser <code>->from()</code>. ==== Class "App\Entity\X" seems not to be a managed Doctrine entity. Did you forget to map it? ==== On fait appel à une classe PHP comme si c'était une entité Doctrine : il faut simplement ajouter les annotations Doctrine à la classe, ou bien recréer la table à partir du code PHP. ==== Column not found: 1054 Unknown column 't0.xxx_id' in 'field list' ==== Il faut juse ajouter la colonne de jointure sous l'annotation *To*. Ex : <code>@ORM\JoinColumn(name="id", referencedColumnName="id_personne")</code> ==== Could not find the entity manager for class '...' ==== Dans doctrine.yaml, retirer <code>type: annotation</code>. ==== Entity has to be managed or scheduled for removal for single computation ==== * Si remove : retirer le ON CASCADE DELETE de l’entité supprimée. * Si update : faire le add avant. ==== Entity of type 'App\\MonEntite' for IDs id(1) was not found ==== S'il s'agit de l'ID d'une entité jointe, le rendre nullable (<code>@ORM\JoinColumn(nullable=true)</code>)<ref>https://cilefen.github.io/symfony/2016/12/29/doctrine-orm-nulls.html</ref>. S'il s'agit d'une entité dont la clé primaire est une clé étrangère, lui ajouter : <pre> @ORM\GeneratedValue(strategy="NONE") </pre> ==== Entity of type App\\MonEntite is missing an assigned ID for field 'id'. ==== Une entité n'arrive pas à être sauvegardée avec un ID null (non auto-incrémenté). Il faut donc le générer (par exemple avec un <code>new UuidV4()</code>). Sinon vérifier que l'erreur ne vient pas d'un listener en sur <code>Doctrine\ORM\Events::prePersist</code> qui tente de persister l'entité récupérée via <code>$eventArgs->getEntity()</code>. ==== Invalid PathExpression. Must be a StateFieldPathExpression ==== Cela peut arriver quand on ajoute une clé étrangère dans un select sans sa jointure : $this->createQueryBuilder('user') ->select(['user.id', 'user.company']) On peut donc le remplacer par : $this->createQueryBuilder('user') ->select('user.id') ->leftJoin('user.company', 'u') Par contre, si on ne veut pas la jointure, utiliser "identity" : $this->createQueryBuilder('user') ->select(['user.id', 'identity(user.company) company']) ==== No alias was set before invoking getRootAlias() ==== Se produit soit : * Lors d'un <code>$qb = $this->entityManager->getEntityManager()->createQueryBuilder();</code> (sans alias comme dans : <code>$this->createQueryBuilder('me')</code> hérité de <code>EntityRepository</code>). Il faut alors rajouter un alias pour l'entité courante ainsi : <pre> $em->createQueryBuilder() ->select('me') ->from(MonEntite::class, 'me') </pre> * Ou pour un update où on répète à tort l'alias ('me') dans <code>update()</code> (ce qui peut aussi donner <code>Error: Class 'pn' is not defined</code> quand il n'y a pas de jointure) : <pre> $this->createQueryBuilder('me') ->update() ->set('me.isDeleted', 1) </pre> ==== Property \"metadata\" on resource \"App\\MonEntite\" is declared as a subresource, but its type could not be determined in ==== Survient quand une entité étend une autre sans discriminator<ref>https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/inheritance-mapping.html</ref>. ==== The association mon_entité1#entité2 refers to the owning side field mon_entité2#id which does not exist ==== Si l'entité 2 ne fait pas référence à l'entité 1, supprimer dans l'entité 1, champ entité2, le <code>mappedBy=</code>. ==== The class 'Doctrine\Common\Collections\ArrayCollection' was not found in the chain configured namespaces App\Entity ==== Il peut y avoir une entité avec une relation ManyToMany dans laquelle on met un ArrayCollection au lieu de l'entité demandée<ref>https://openclassrooms.com/forum/sujet/symfony2-collection-erreur-de-namespace</ref>. Sinon vérifier qu'on attend pas un PersistentCollection au lieu d'un ArrayCollection (ou vice-versa avec ->unwrap()). ==== The EntityManager is closed ==== Cela survient quand l'EntityManager rencontre une exception. On peut<ref>https://www.kerstner.at/2014/09/doctrine-2-exception-entitymanager-closed/</ref> : * la lever avec : <syntaxhighlight lang="php"> if ($this->em->isOpen()) { $this->em->persist($entity); $this->em->flush($entity); } </syntaxhighlight> * recréer l'entityManager : <syntaxhighlight lang="php"> if (!$this->em->isOpen()) { $this->em = $this->em->create( $this->em->getConnection(), $this->em->getConfiguration() ); } </syntaxhighlight> ==== The field xxx has the property type 'bool' that differs from the metadata field type 'int' returned by the 'integer' DBAL type ==== Se produit avec : <pre> bin/console doctrine:schema:validate </pre> Quand il trouve par exemple une option par défaut manquante. Ex : <pre> #[ORM\Column(type: 'boolean', nullable: true, options: ['default' => null])] </pre> ==== The identifier id is missing for a query ==== Se produit lors d'un repository->find(null). ==== The metadata storage is not up to date, please run the sync-metadata-storage command to fix this issue ==== Si le paramètre "server_version" est présent dans le {{wt|DSN}} "DATABASE_URL", l'ajouter, sinon le retirer. ==== The referenced column name 'xxx' has to be a primary key column on the target entity class ==== S'il n'est pas possible d'utiliser la clé étrangère comme clé primaire, retirer simplement la ligne : <pre> #[ORM\JoinColumn(name: 'my_id', referencedColumnName: 'my_id')] </pre> Mais ça peut provoquer un problème N+1... ==== The table with name 'xxx' already exists ==== Si cela survient lors du <code>bin/console doctrine:schema:validate</code>, create ou update sur une base vide, et qu'il n'y a pas de doublon dans le dossier "Entity"<ref>https://openclassrooms.com/forum/sujet/doctrine-schema-update-impossible</ref> : * Chercher les doublons dans d'autres namespaces. * Retirer les appels directs à la table de l'entité mal placés (<code>#[ORM\JoinTable(name: xxx</code>)). * Forcer la version du SGBD dans <code>DATABASE_URL</code>, en l'ajoutant dans <code>?serverVersion=</code>. * Dans le cas du validate, on peut ajouter <code>--skip-sync</code> pour bypasser cette partie du test. ==== Transaction commit failed because the transaction has been marked for rollback only ==== Se produit quand un flush() rencontre une erreur SQLSTATE (ex : colonne manquante, même d'une autre table, ou locks à cause d'UPDATE du même champ qui se répètent). * Le commenter pour la voir apparaitre. * Si elle n'apparait pas (ex : timeout), regarder directement [[MySQL/Parcourir_les_bases_de_données|dans les logs de la base de données]]. Cela peut être dû à la présence de deux attributs dans une entité, pointant vers la même colonne de sa table (ex : un ID de clé étrangère et son objet correspondant). ==== Uncaught PHP Exception Doctrine\Common\Proxy\Exception\UnexpectedValueException: "Your proxy directory "var/cache/prod/doctrine/orm/Proxies" must be writable" ==== Si cela se produit avec <code>APP_ENV=prod</code> et pas <code>dev</code> dans le .env : rm -Rf var/cache/ var/log ==== Uncaught Symfony\Component\Debug\Exception\UndefinedFunctionException: Attempted to call function "apc_fetch" ==== <syntaxhighlight lang="bash"> sudo pecl install apcu sudo pecl install apcu_bc sudo apt-get install -y php7.2-apcu php7.2-apcu-bc </syntaxhighlight> ==== Unexpected non-iterable value for to-many relation ==== Modifier la déclaration du champ en erreur avec un itérable. Ex : <syntaxhighlight lang="php"> public $mesObjets = new ArrayCollection(); </syntaxhighlight> S'il n'y a pas de champ en erreur, il faut le retrouver avec <code>dd($type)</code> dans AbstractItemNormalizer. ==== Unknown database ==== Lancer ''doctrine:database:create'' : <syntaxhighlight lang="bash"> bin/console d:d:c </syntaxhighlight> Puis rajouter les éventuelles tables : <syntaxhighlight lang="bash"> bin/console doctrine:schema:update --force </syntaxhighlight> ==== Unrecognized field (ORMException) ==== Se produit quand un findBy de repository ne trouve pas un champ de son entité. Cela peut être résolu avec : * <code>bin/console cache:clear</code> * Vérifier si on ne recherche pas à tort une valeur sans sa clé (si ''Unrecognized field: 0''). * Passer par un QueryBuilder plutôt que par un find. * Ne pas faire hériter le repo de ServiceEntityRepository. ==== WARNING [cache] Failed to save key... "cache-adapter" => "Symfony\Component\Cache\Adapter\ApcuAdapter" ==== Ajouter <code>apc.enable_cli=1</code> dans le fichier <code>php.ini</code>. ==== DoctrineMigrations ==== ===== S'il n'exécute pas tout (sans logs même en -vvv) ===== Séparer en plusieurs migrations, notamment les créations de tables et de fonctions. ===== The schema provider is not available ===== Remplacer "connection" par "em" dans doctrine_migrations.yaml : <syntaxhighlight lang="yaml"> doctrine_migrations: em: default </syntaxhighlight> ===== Syntax error or access violation ===== Il faut probablement échapper des caractères, par exemple avec la syntaxe heredoc ou $this->connection->quote(). === API Platform === ==== Invalid IRI ==== Ajouter le getId() dans l'entité récupérée par IRI. ==== InvalidArgumentException: "No item route associated with the type xxx ==== Se produit quand on a pas une route POST sans route GET<ref>https://github.com/api-platform/core/issues/3501</ref>, ou si le GET n'a pas d'ID pour créer des URI. Il faut donc en créer une, mais pas forcément besoin de créer un contrôleur : <syntaxhighlight lang="php"> * @ApiResource( * itemOperations={ * "get"={ * "method"="GET", * "controller"=NotFoundAction::class, * "read"=false, * "output"=false, * }, * }, * ) </syntaxhighlight> ==== No identifiers defined for resource of type ==== <syntaxhighlight lang="php"> /** * @ApiProperty(identifier=true) */ private $id; </syntaxhighlight> Si aucun ID n'est possible, en renvoyer "1" par exemple. ==== Unable to generate an IRI for ==== En général, rajouter un getId() dans l'entité. ==== The total number of joined relations has exceeded the specified maximum. Raise the limit if necessary with the \"api_platform.eager_loading.max_joins\" configuration key, or limit the maximum serialization depth using the \"enable_max_depth\" option of the Symfony serializer ==== Sur MySQL (ou MariaDB) il existe un maximum de 64 jointures. Donc s'il n'est pas possible d'augmenter max_joins, il faut limiter les jointures par les deux annotations suivantes : <syntaxhighlight lang="php"> * @API\ApiSubresource(maxDepth=1) * @ORM\OneToMany(targetEntity="MonEntité", mappedBy="monChamp", fetch="EXTRA_LAZY") </syntaxhighlight> === Twig === ==== Un template Twig ne se rafraichit pas dans la navigateur ==== En local, dans .env, passer de <code>APP_ENV=prod</code> à <code>APP_ENV=dev</code>. Sinon vider le cache Symfony. ==== A hash key must be followed by a colon (:) ==== Il faut probablement mettre des parenthèses autour des variables dans un merge de tableau. Ex : myArray|merge([{(myKey): (myValue)}]) ==== Array to string conversion ==== Plusieurs solutions sont possibles pour afficher un tableau dans un template JSON. * Pour avoir un tableau, ajouter (et retirer les guillemets autour de la valeur si besoin) : <syntaxhighlight lang=twig> "my_key": {{ my_value |json_encode(constant('JSON_PRETTY_PRINT'))|raw }}, </syntaxhighlight> voire : <syntaxhighlight lang=twig> "my_key": {{ my_value |join(', ') }}, </syntaxhighlight> * Pour avoir un objet en chaine de caractères, faire le json_encode en amont puis laisser les guillemets : <syntaxhighlight lang=twig> "my_key": "{{ my_value }}", </syntaxhighlight> ==== double quoted property ==== Une virgule de trop après une clé. ==== key \"id\" for array with keys \"0\" does not exist. ==== Appel d'une clé absente d'un tableau. ==== The CSRF token is invalid. Please try to resubmit the form ==== Dans le formulaire concerné, ajouter la ligne : <syntaxhighlight lang=php> public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ ... 'csrf_protection' => false, ]); } </syntaxhighlight> ==== unexpected token "punctuation" of value "{" ==== Au choix : * Ajouter les apostrophes aux clés du tableau concerné. * Ajouter des parenthèses à ses expressions. * Remplacer les accolades par des crochets pour le premier niveau. ==== xmlParseEntityRef: no name ==== Un "&" n'est pas échappé en XML. Il faut ajouter un filtre "| escape" en Twig pour le faire. == PhpStorm == Les logs sont accessibles par : tail -f ~/.PhpStorm2019.2/system/log/idea.log === Certains dossiers sont rouges (exclus) dans la navigation et l'indexation, alors qu'ils ne sont pas censés l'être === Fermer le projet, supprimer le .idea, et le rouvrir. === Impossible de CTRL + clic dans un .twig (chemin introuvable) === Vérifier que le plugin Symfony de PhpStorm est bien installé et activé. Si cela persiste, dans ''File\Settings\PHP\Symfony\Twig \ Template'', ajouter le chemin vers les .twig importés du bundle concerné. === L'historique Git d'un dossier est tronqué === Si <code>git log .</code> montre plus de commits que le clic droit / Git / Show history, alors cliquer sur Files / Invalidate Caches, et tout cocher. Si cela ne fonctionne pas après redémarrage, et que le projet fait partie d'un groupe de projets ouverts, le fermer (clic droit dessus et "Remove from project view"), puis le rouvrir. === Dans l'onglet Git, on ne voit pas la liste des fichiers modifiés === Dans Settings, Version Control, Commit, décocher "Use non-modal commit interface". === Un fichier a disparu des onglets, a un icône de point d'interrogation, et ne peut être rouvert === Il n'est pas ou plus associé à un type de fichier, aller dans ''File\Associate with File Type''. === incoming connection from xdebug === Lors d'une erreur au remplissage de cette pop-up, on peut la corriger dans .idea/workspace.xml. === No differences files that files have differences only in line separators === Les scripts lancés depuis PhpStorm sous Windows modifient les retours à la ligne (CLRF to LF). Changer l'option dans ''Settings/Preferences | Editor | Code Style | Line separator''<ref>https://stackoverflow.com/questions/40470895/phpstorm-saving-with-linux-line-ending-on-windows</ref> vers "System dependent". Sinon, configurer git : git config --global core.autocrlf true === Undefined class xxx === Une classe existe mais PhpStorm ne la voit pas : ajouter son dossier dans File\Settings\Directories, retirer l'exclusion (rouge) du dossier concerné. == Xdebug == Des logs Xdebug sont ajoutables dans le fichier <code>php.ini</code> : <syntaxhighlight lang="ini"> xdebug.remote_log = /var/www/xdebug.log xdebug.show_error_trace = 1 ; Profiling (enable via cookie or GET/POST variable: XDEBUG_PROFILE=1). xdebug.profiler_enable = 1 xdebug.profiler_enable_trigger = 0 xdebug.profiler_output_dir = /tmp/ ; var_dump() settings. xdebug.overload_var_dump = 1 xdebug.cli_color = 1 </syntaxhighlight> === En CLI, la console s'ouvre sur default_prepend.php et on ne voit pas l'exécution de la commande === Cela se produit quand plusieurs projets sont ouverts dans PhpStorm et que la commande n'appartient pas au principal. === Le navigateur déclenche bien le débogage pas à pas, mais on ne voit pas le fichier PHP dans l'IDE === Il manque le mapping (par exemple avec les routes du conteneur). Par exemple dans PhpStorm, Servers, cocher "Use path mappings" et le renseigner. === Messages d'erreur === ==== Cannot find file '/usr/local/php/php/auto_prepends/default_prepend.php' locally ==== Sous PhpStorm avec Docker, cliquer sous l'erreur pour modifier le ''path mapping''. ==== Code coverage needs to be enabled in php.ini by setting 'xdebug.mode' to 'coverage' ==== Pour éviter d'éditer le .ini, on peut remplacer : bin/phpunit --coverage-text par : php -dxdebug.mode=coverage bin/phpunit --coverage-text ==== Could not connect to client ==== Le serveur est introuvable, changer : * En V2, xdebug.remote_host ou remote_port. * En V3, xdebug.client_host ou xdebug.client_port. ==== Gateway Timeout ==== Cette erreur du navigateur généralement due au serveur Web. * Sur Apache, dans httpd.conf augmenter le nombre de secondes par défaut dans <code>Timeout 60</code><ref>https://www.h3xed.com/web-development/php-and-apache-504-gateway-timeout-troubleshooting-and-solutions</ref>. * Sur Nginx, augmenter <code>fastcgi_read_timeout 60s;</code><ref>http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_read_timeout</ref>. *Sur IIS, étendre la valeur du paramètre ''Activity Timeout'' des ''FastCGI Settings''<ref>https://www.leighton.com/blog/php-debugging-in-phpstorm-6-0-with-xdebug/</ref>. * Cela peut aussi provenir d'un load balancer en amont du serveur HTTP. De plus, on peut aussi revoir les variables du fichier <code>php.ini</code>. Ex : <syntaxhighlight lang="ini"> max_execution_time=30 # 30 s par défaut max_input_time=-1 # Utilisera "max_execution_time" si -1, sinon la valeur indiquée </syntaxhighlight> ==== Failed to read FastCGI header ==== Si le log Apache affiche cela lors d'un ''Gateway Timeout'', il faut ajouter à httpd.conf<ref>https://support.plesk.com/hc/en-us/articles/115000064929-Website-is-not-accessible-The-timeout-specified-has-expired-Error-dispatching-request-to</ref> : <syntaxhighlight lang="apache"> ProxyTimeout 6000 <IfModule mod_fcgi.c> FcgidProcessLifeTime 6000 FcgidBusyTimeout 6000 FcgidConnectTimeout 6000 FcgidIdleTimeout 6000 FcgidInitialEnv 6000 FcgidIOTimeout 6000 IdleTimeout 6000 IPCConnectTimeout 6000 IPCCommTimeout 6000 IdleScanInterval 6000 </IfModule> </syntaxhighlight> Parfois il convient aussi de modifier le fichier <code>php.ini</code><ref>https://www.reddit.com/r/drupal/comments/ase67i/for_issue_reference_service_unavailable_error/</ref> : <syntaxhighlight lang="ini"> opcache.optimization_level=0xFFFFFBFF xdebug.remote_cookie_expire_time=6000 </syntaxhighlight> Enfin, sur PhpStorm on rencontre cela dans le cas de sous-requêtes qui dépassent la valeur du paramètre "Max. simultaneous connections". ==== No code coverage driver is available ==== Installer ou activer [[../Xdebug|Xdebug]]. Il doit apparaitre ensuite dans <code>php -v</code>. ==== Remote file path 'default_prepend.php' is not mapped to any file path in project ==== Sous PhpStorm il faut décocher dans les ''settings'', ''debug'', les deux cases ''Force break...'', puis de redémarrer l'IDE<ref>https://www.jetbrains.com/help/phpstorm/troubleshooting-php-debugging.html</ref>. ==== Time-out connecting to client ==== Changer xdebug.remote_host ou xdebug.remote_port car le serveur existe mais n'écoute pas le port spécifié. Si le navigateur ne déclenche plus le débogage sur l'IDE, alors que ce dernier écoute et que la clé du navigateur est bien définie, c'est peut-être le pare-feu qui bloque. Exemple de reset sur Linux avec [[Le système d'exploitation GNU-Linux/Protection avec iptables|iptables]]<ref>https://ubuntuforums.org/showthread.php?t=1381516</ref> : <syntaxhighlight lang="bash"> iptables --policy INPUT ACCEPT; iptables --policy OUTPUT ACCEPT; iptables --policy FORWARD ACCEPT; iptables -Z; # zero counters iptables -F; # flush rules iptables -X; # delete all extra chains </syntaxhighlight> ==== Waiting for incoming connection with ide key 'xxx' ==== Xdebug peut marcher pour certains sites, sauf un qui ne déclenche rien dans l'IDE. Ce message apparait alors dans PhpStorm si on clique sur "Debug". * Vérifier le serveur et son port) associé à l'URL<ref>https://stackoverflow.com/questions/17715128/xdebug-phpstorm-waiting-for-incoming-connection-with-ide-key</ref>. * Voir la page [[Programmation PHP/Xdebug]]. == GraphQL == === Fields "maRoute" conflict because they have differing arguments. Use different aliases on the fields to fetch both if this was intentional. === Si on appelle plusieurs fois la même route dans la même requête, il faut définir des alias. Ex : <syntaxhighlight lang="cypher"> mutation { maRoute(...) aliasMaRoute: maRoute(...) } </syntaxhighlight> Le résultat de la requête sera donc un tableau avec ['data' => [[maRoute => ...], [aliasMaRoute => ...]]. == Windows == === imagecreatefromstring(): gd-png: libpng warning: Interlace handling should be turned on when using png_read_image === Remplacer le php_gd2.dll du PHP 7.4.33 par celui du 7.4.2 téléchargé depuis https://www.pconlife.com/viewfileinfo/php-gd2-dll/. Exemple du chemin par défaut : C:\wamp64\bin\php\php7.4.33\ext\ == Références == {{Références}} <noinclude>[[Catégorie:Messages d'erreur]]</noinclude> sgixck30nu9ydnqjxw61m468tdixx83 Auto-éditer un wikilivre/Auto-référencer 0 74478 744187 710411 2025-06-06T04:32:12Z 2A01:CB18:1150:4600:C5FF:3372:4F9:EE19 /* Les lignes qui méritent notre attention */Correction d'une faute d'orthographe 744187 wikitext text/x-wiki <!--{{En cours}}--> <div class="noprint"> <div style="background: #EAF5FB; font-size: 120%; margin: 1em auto; padding: 0.3em; text-align: center; width: 70%;"> <div style="background: #EAF5FB; border: 2px solid #fff; padding: 0.3em;"> <span style="font-size: 125%;">'''Programmation bash (exercices, tests et documentation.)'''</span><br /> ''Un livre appartenant à la série [[Programmation]] de [[Accueil|Wikilivres]]''. </div> </div> <strong>self-referencing</strong> </div> __TOC__ <div style="width: 270px; float: right;"> {{Moteur}} {{version imprimable}} <!--{{étiquette progression|en cours}}--><!--{{étiquette progression|ébauche}}encours, avancé, complet --> <!--{{étiquette progression|avancé}}--> {{niveau|12|img=douze}} </div> {{Nouvelle page imprimée}} == Codes shell pour créer la page « Annexe » d'un wikilivre == {{:Auto-éditer_un_wikilivre/Auto-référencer/Description du projet}} <small><small>[[Auto-éditer_un_wikilivre/Auto-référencer/Description du projet|modifier cette description du projet]]</small></small> {{Nouvelle page imprimée}} === Entête des modules === ; (header) ; Documentation : Le fichier de commandes header.sh doit être inclus dans tous les modules de test du programme principal. Il initialise le répertoire des commandes, le répertoire de travail du projet; le projet est le nom du livre, de l'article ou de la page. Si ils n'existent pas ils seront créés Ce projet éducatif et de tests est destiné à être utilisé sous wikilivres en langue française et en caractères UTF8. Les variables Site et SitePrefix se rapportent à "fr.wikibooks.org". Le programme est prévu pour fonctionner à l'initiative du contributeur qui qui doit copier la page "Contenus" ou la page de la compilation dans le répertoire de travail "~/Annexe/<nom du livre>" Les modules en tests sont indépendants, cependant ils doivent être exécutés dans l'ordre ./header.sh <livre>, ./lister <livre>, ./télécharger <livre> ./ajouter_sclt <livre>, ./ajouter_sclic, ./ajouter_sclip <livre> La liste des pages à analyser est indispensable dans tous les modules en tests. L'absence de la liste des pages à analyser est signalée à chaque lancement des modules du programme principal "Annexer" AVERTISSEMENT : Ce programme avec ses modules doit être utilisé par des wikipédiens, à titre personnel. La structure du résultat est voisine de l'impression par PediaPress. Pour cette raison ce programme n'est pas commercialisable. ; Organigramme : <pre> 2:#P Nom du fichier de commandes : header ou header.sh 3:#P Syntaxe : ".header.sh <nom du livre>" 4:#P Exemple : "./header.sh LivreTest" à la console pour les essais. 5:#P Ce fichier d'entête est commun aux fichiers de commandes annexer, lister, 6:#P télécharger, ajouter_sclt, ajouter_sclip dans lesquels ils sont inclus. 7:#P Date de création : 24 mars 2020 8:#P Modifié le : 14 mai 2020 par GC ajout des "données_de_conversions" url->utf8 9:#P Modifié le : 16 mai 2020 par GC maj de la nouvelle syntaxe de la commande. 10:#P Version sur WikiLivres le : 17 mai 2020 11:#P 34:#P Note : L'extraction de la documentation peut se faire par la commande : 35:#P Documentation : 36:#P mkd -Stw D header.sh <livre>_doc/header.sh.D.doc 37:#P grep -e '#D' header.sh | sed s/#D//g > <livre>_doc/header.sh.HPw.doc 38:#P Organigrammes : 39:#P grep -e -n '#H' -e '#P' -e '#w' header.sh 40:#P ou : grep -E "#H|#P|#w" header.sh > <livre>_doc/header.sh.HPw.doc 41:#P Exemples : 42:#P mkd -Stw D header.sh LivreTest_doc/header.sh.D.doc 43:#P grep -e '#D' header.sh | sed s/#D//g > LivreTest_doc/header.sh.D.doc 44:#P grep -n -E "#H|#P|#w" header.sh > LivreTest_doc/header.sh.HPw.doc 45:#P 47:#H vider (nettoyer) l'écran. 54:#H tester la présence du répertoire racine des commandes, si il n'existe pas, 55:#H le créer. 65:#H initialiser la variable Conversion avec le lien vers le fichier 66:#H données_de_conversion 69:#H si le programme de test de header.sh est actif, alors supprimer le fichier 70:#H 'données_de_conversions' 77:#H tester la présence du fichier des 'données_de_conversion', si il n'existe 78:#H pas; le créer. 121:#H créer la fonction header_syntax. 126: #w seulement avec la commande 'Annexer' 127: #w echo "ou $0 <livre> [-v] [-pb||-pc]" 128: #w echo "options -v:mode bavard, -pb ou -pc:versions personnalisées Wikibooks ou Commons." 132:#H tester la présence du premier paramètre de la ligne de commandes 146: exit 0 #P exit 0 : Fin d'affichage de la syntaxe 150:#H initialiser la variable "Projet" = répertoire de projet. 156:#H tester la présence du répertoire du projet, si il n'existe pas, le créer. 165:#H initialiser les variables 'Site' (nom du serveur) et 'SitePrefix'. 169:#H nettoyer l'écran, afficher les variables globales et le contenu du répertoire de projet. 198:#H entrer dans la répertoire de travail. </pre> {{Boîte déroulante début|titre=Code header.sh|styleFrame=width:100%;|fondtitre=#F0F0F0<!--|styleTitre=color:white;|style=headerbleu-->}} ;Référence de l'article pour cette section : [https://fr.wikibooks.org/w/index.php?title=Auto-%C3%A9diter_un_wikilivre/Auto-r%C3%A9f%C3%A9rencer/header.inc.sh&oldid=641583 Version du 25 mai 2020] ; Version actualisée : {{:Auto-éditer_un_wikilivre/Auto-référencer/header.inc.sh|Version actualisée}} {{Boîte déroulante fin}} {{Nouvelle page imprimée}} === Annexer (main) === ; (Appendix) '''Annexer''' ou '''annexer.sh''' est la page principale qui permet de produire la page « Annexe », elle utilise les commandes shell "header.sh, "lister", "télécharger", "ajouter_sclt", "ajouter_sclic" et "ajouter_sclip". ; Documentation : '''''mkd -Stw D annexer Bash_doc/annexer.D.doc''''', qui respecte les tabulations, ou :<br />'''''mkd -sStw D annexer > Bash_doc/annexer.D.doc''''', avec une présentation comme ci-dessous. la commande "annexer" est le programme principal de tests pour créer la page "Annexe" des livres de wikilivres. annexer (module de tests) analyse la ligne de commandes et initialise la variable $Verbose ou affiche la syntaxe à la demande interrogative '?' en premier paramètre. ce programme supprime tous les fichiers obsolètes du répertoire de travail "~/Annexe/<nom du livre>" et de ses sous répertoires, avec l'accord de l'utilisateur. les modules lister, télécharger, ajouter_sclt, ajouter_scli* sont exécutés dans l'ordre, puis pour finir, le fichier "Annexe" du livre est assemblé. à la fin de l'exécution de chaque module il est possible d'interrompre le programme par la validation de la ligne (retour chariot après #T) : #T exit -> sur deux lignes comme ci-après : #T exit l'extraction de la documentation peut se faire par la commande : mkd -Stw DOP annexer (D=Docu, O=organigramme, P=pour programmeurs) ; Organigramme : '''''mkd -nStw O annexer Bash_doc/annexer.O.doc''''' 47 analyse de la ligne de commandes : 48 si le premier paramètre est le caractère ? 50 alors : 52 afficher la syntaxe et quitter. 63 fin si 66 inclure le fichier d'entête header.sh 69 ## annexer ################ 71 initialiser les variables $Verbose et $Personal à 'false' 80 si ne nombre de paramètres est supérieur à 1 82 alors : 84 si le deuxième paramètre est '-v' 86 alors initialiser la variable $Verbose à 'true' (vrai). 89 fin si 91 si le deuxième paramètre est '-pb' 93 alors initialiser la variable $Personalwb à 'true' (vrai). 96 fin si 98 si le deuxième paramètre est '-pc' 100 alors initialiser la variable $Personalco à 'true' (vrai). 103 fin s 105 fin si 108 si le nombre de paramètres est égal à 3 110 alors : 112 si le troisième paramètre est '-v' 114 alors initialiser la variable $Verbose à 'true' (vrai). 117 fin si 119 si le troisième paramètre est '-pb' 121 alors, si la variable $Personalco n'est pas à validée, initialiser la variable $Personalwb à 'true' (vrai). 123 fin si 126 si le troisième paramètre est '-pc' 128 alors, si la variable $Personalwb n'est pas à validée, initialiser la variable $Personalco à 'true' (vrai). 130 fin si 132 fin si 135 si le nombre de paramètres est supérieur à 3 137 alors : signaler l'erreur et quitter. 142 fin si 156 afficher : 'effacer tous les fichiers obsolètes ? :' 157 '*.html *.str *.img *.lnk tmp temp *.tmp *.temp *.list ?' 161 attendre 'un' (un seul) caractère de réponse. 165 si la réponse au clavier est 'o' (oui !), 167 alors effacer les fichiers du répertoire de projet (nom du livre). 173 sinon, continuer. 175 fin si 181 se placer dans le répertoire des commandes(~/Annexer/.) 184 créer le fichier contenant la liste des articles à analyser. (./lister $1) 185 si la variable $Verbose et validée (à 'true'), 187 alors : exécuter la commande 'lister' en mode bavard. 190 sinon : exécuter 'lister' en mode silencieux, les observation seront dans 191 le fichier lister-cmd.txt 194 fin si 199 si le code de retour est supérieur à 0 201 alors afficher le nom du module de commande en erreur et quitter 'annexer' 202 avec retour à 1 206 fin si 212 se placer dans le répertoire des commandes 216 si le mode bavard est activé, 218 alors: exécuter la commande 'télécharger' en mode bavard. 221 sinon: exécuter la commande 'télécharger' en mode silencieux.. 224 fin si 229 si le code de retour est supérieur à 0 231 alors afficher le nom du module de commande en erreur et quitter 'annexer' 232 avec retour à 1 236 fin si 242 se placer dans le répertoire des commandes 245 créer la "page Annexe" et ajouter les sources, contributeurs, droits de 246 copie du texte des articles. 247 sclt signifie : s=source, c=contributeurs, l=licence, t=texte des articles 248 si le mode bavard est activé, 250 alors : exécuter la commande 'ajouter_sclt' en mode bavard. 253 sinon : exécuter la commande 'ajouter_sclt' en mode silencieux. 256 fin si 261 si le code de retour est supérieur à 0 263 alors afficher le nom du module de commande en erreur et quitter 'annexer' 264 avec retour à 1 268 fin si 274 se placer dans le répertoire des commandes 277 si la variable $Personal est invalide 'false' 279 alors: 281 exécuter ajouter_sclic 282 (ajouter les sources, licence, contributeurs des images avec la commande 283 globale conventionnelle ajouter_sclic 284 si le mode bavard est validé, 286 alors : ajouter_sclic en mode bavard 289 sinon : ajouter_sclic et copier les observations dans ajouter-sclic-cmd.txt 292 fin si 295 fin si 300 si le code de retour est supérieur '0' 302 alors afficher le nom du module de commande en erreur et quitter 'annexer' 303 avec retour à 1 307 fin si 313 se placer dans le répertoire des commandes 315 si l'option annexe' personnalisée est validée ($Personal=true) 317 alors: 319 exécuter ajouter_sclip 320 (ajouter les sources, licence, contributeurs des images avec la commande 321 globale conventionnelle ajouter_sclic 327 fin si 330 fin si 334 si le code de retour est différent de '0' 336 alors afficher le nom du module de commande en erreur et quitter 'annexer' 337 avec retour à 1 341 fin si 350 se placer dans le répertoire des commandes. 352 si l'option de la commande annexe '-pc' (personalco) est activée à 'vrai' 354 alors exécuter sclipco.inc 358 fin si 360 si le code de retour est différent de '0', 362 alors afficher le nom du module de commande en erreur et quitter 'annexer' 363 avec retour à 1 367 fin si 374 se placer dans le répertoire des commandes. 376 si l'option de la commande annexe '-pb' (personalwb) est activée à 'vrai' 378 alors exécuter sclipwb.inc 382 fin si 384 si le code de retour est différent de '0', 386 alors afficher le nom du module de commande en erreur et quitter 'annexer' 387 avec retour à 1 391 fin si 397 assembler la page 'Annexe' du livre. 400 copier sclt dans la page 'Annexe' du livre. 403 si la variable Personal est activée à 'true' 405 alors : ajouter le contenu du fichier $1.sclip au fichier $1.annexe 407 sinon : 409 ajouter $1.sclic à l'annexe 411 fin si 414 ajouter la licence (fr) à la page 'Annexe' {{Boîte déroulante début|titre=Code du programme maître ''annexer''|styleFrame=width:100%;|fondtitre=#F0F0F0<!--|styleTitre=color:white;<!|style=headerbleu-->}} ;Version de référence pour cet article du 20 mai 2020 :[https://fr.wikibooks.org/w/index.php?title=Auto-%C3%A9diter_un_wikilivre/Auto-r%C3%A9f%C3%A9rencer/annexer.sh&oldid=641588 Annexer.sh] ; Version actualisée : {{:Auto-éditer_un_wikilivre/Auto-référencer/annexer.sh}} {{Boîte déroulante fin}} ==== Tests unitaires du fichier de commandes ''annexer'' ==== ''<u>Faire un brouillon avec le micro-ordinateur sous linux</u> (ou autre système acceptant les shells bash).'' # Avec un micro-ordinateur doté d'un système d'exploitation unix ou linux. # Copier le code du fichier [[Auto-éditer_un_wikilivre/Auto-référencer#Annexer|annexer]] dans un éditeur de texte comme Notepadqq, Gedit, ou Bluefish. # Créer le répertoire ''Annexer'' avec l'éditeur, ou, sous console : '''mkdir ~/Annexer''' # Enregistrer le texte avec pour nom '''annexer''' dans le répertoire '''Annexer'''. # <u>Sous console</u>, entrer dans le répertoire Annexer : '''cd ~/Annexer''' # Copier le code de la commande '''header.sh''' dans '''~/Annexer/.''' # Rendre les commandes ''annexer'' et ''header.sh'' exécutables : '''chmod 777 annexer header.sh''' # Pour tester, lancer la commande '''./annexer LivreTest'''. # Observer le répertoire ''LivreTest'' : '''ls -l ~/Annexer/LivreTest''' qui doit être vide. # Copier et coller tous les codes des modules : header.sh, lister, télécharger, ajouter-sclt, ajouter_sclic, ajouter_sclip, <u>dans le répertoire des commandes ''Annexer''</u>. <br :>exemple : code ''header.sh'' dans le fichier ~/Annexer/hearder.sh, etc. # tous les fichiers shell doivent être exécutables <br />'''chmod 777 lister télécharger ajouter_sclt ajouter_sclic ajouter_sclip''' # Éditer et copier le contenu de la page '''''Contenus''''' de la version imprimable, dans le répertoire de travail du projet, '''''~/Annexer/<nom du livre>/.''''' avec pour nom '''''<nom du livre>.contenu''''' ou le contenu d'une page de '''''compilation''''', avec pour nom '''''<nom du livre>.compilé'''''.<br />'''ls -l ~/Annexer/<nom du livre>''' doit maintenant afficher un de ces deux fichiers. '''Note : '''Si, par exemple, vous lancez la commande '''''./annexer LivreTest''''' ou '''''./header.sh LivreTest''''' de n'importe répertoire, les répertoires '''''~/Annexer''''' et '''''~/annexer/LivreTest''''' seront automatiquement créés au bon endroit par l'entête ''header.sh''. Il suffira de copier le fichier de commandes ''annexer'' ou ''annexer.sh'' dans le répertoire de fichiers de commandes : <br />"'''mv ./annexer ~/Annexer/annexer'''" ou shell bash sous windows, "'''mv ./annexer.sh ~/Annexer/annexer.sh'''" ==== Annexe obtenue ==== <pre> = Annexe = == Références == <references /> {{Nouvelle page imprimée}} == Contenus == <small> https://fr.wikibooks.org/wiki/Utilisateur:Goelette_Cardabela/Sandbox/LivreTest https://fr.wikibooks.org/wiki/Utilisateur:Goelette_Cardabela/Sandbox/LivreTest/ArticleUn https://fr.wikibooks.org/wiki/Utilisateur:Goelette_Cardabela/Sandbox/LivreTest/ArticleDeux https://fr.wikibooks.org/wiki/Utilisateur:Goelette_Cardabela/Sandbox/LivreTest/ArticleTrois </small> === Source de cette édition === <small> https://fr.wikibooks.org/wiki/Utilisateur:Goelette_Cardabela/Sandbox/LivreTest </small> {{Nouvelle page imprimée}} == Sources licences et contributeurs des articles == <small>Les ''sources'' listées pour chaque article fournissent des informations de licence plus détaillées, y compris le statut des droits d'auteurs, les détenteurs de ces droits et les conditions de licence.</small> <small><small> '''ArticleUn''' , ''source : ''https://fr.wikibooks.org/w/index.php?oldid=632571 , ''licence : ''https://creativecommons.org/licenses/by-sa/3.0/ , ''auteur(s) : ''Goelette Cardabela '''ArticleDeux''' , ''source : ''https://fr.wikibooks.org/w/index.php?oldid=632572 , ''licence : ''https://creativecommons.org/licenses/by-sa/3.0/ , ''auteur(s) : ''Goelette Cardabela '''ArticleTrois''' , ''source : ''https://fr.wikibooks.org/w/index.php?oldid=632573 , ''licence : ''https://creativecommons.org/licenses/by-sa/3.0/ , ''auteur(s) : ''Goelette Cardabela </small></small> {{Nouvelle page imprimée}} == Sources des images licences et contributeurs == <small>Les ''sources'' listées pour chaque illustration fournissent des informations de licence plus détaillées, y compris le statut des droits d'auteurs, les détenteurs de ces droits et les conditions de licence.</small> <small><small> '''Illustration : '''Gabriel Garcia Marquez - Fresque.jpg , ''source : ''https://fr.wikibooks.org/w/index.php?title=File:Gabriel_Garcia_Marquez_-_Fresque.jpg , ''licence : ''CC BY-SA 4.0 , ''auteur(s) : ''User:Pohline_Blast_Clm '''Illustration : '''Commerce de communautés indigènes.JPG , ''source : ''https://fr.wikibooks.org/w/index.php?title=File:Commerce_de_communautés_indigènes.JPG , ''licence : ''CC BY-SA 3.0 , ''auteur(s) : ''User:Goelette.Cardabela '''Illustration : '''Fernando Botero (2018).jpg , ''source : ''https://fr.wikibooks.org/w/index.php?title=File:Fernando_Botero_(2018).jpg , ''licence : ''CC BY 3.0 , ''auteur(s) : ''- '''Illustration : '''Pano Plazo Botero.jpg , ''source : ''https://fr.wikibooks.org/w/index.php?title=File:Pano_Plazo_Botero.jpg , ''licence : ''Public domain , ''auteur(s) : ''User:Scabredon~commonswiki </small></small> {{Nouvelle page imprimée}} == Licence == https://creativecommons.org/licenses/by-sa/3.0/ {{Nouvelle page imprimée}} </pre> ===== Impression visuelle de cette annexe ===== [[Utilisateur:Goelette_Cardabela/Sandbox/LivreTest/Annexe_bis]] ; Comparer avec la versions manuelle ou semi-automatique : [[Utilisateur:Goelette_Cardabela/Sandbox/LivreTest/Annexe]] {{Nouvelle page imprimée}} === Lister (module) === ; (List) Créer une liste des liens vers les pages qui composent le livre. ; Documentation : L'objet de cette commande est de créer le fichier de liste $Projet/$1.list avec le fichier "contenu" prioritaire, sinon avec le fichier "compilé" si il existe. Le 23 avril; créer la liste de projet $Projet/$1.prj a été jugée nécessaire pour que l'utilisation des boucles de commandes s'exécutent dans l'ordre de présentation des textes et des images afin de créer la page "Annexe" du livre (ou de la page). Si le fichier "<livre>.contenu" (copie de la page "Contenus" de la version imprimable) n'existe pas le programme teste la présence du fichier de compilation "<livre>.compilé", et si celui-ci n'est pas présent le programme se termine avec un code de retour à 1. Lorsque le programme se termine normalement le code de retour est 0, le fichier examiné aura été protégé contre l'effacement, donc en lecture seule, et le fichier projet.list aura été créé. Le contenu des listes sont affichés pour être validés. ; Organigramme : ## lister ################# effacer tous les fichiers *.list, initialiser la variable de retour à 0 créer le fichier de liste $Projet/$1.list avec le fichier "contenu" prioritaire, sinon avec le fichier "compilé" s'il existe. si le fichier LivreTest.contenu existe, alors : s'assurer que le fichier sera en lecture seule, créer la liste des articles de la page avec la page de Contenus du livre. créer le fichier de projet avec la page de Contenus du livre. sinon, si le fichier LivreTest.compilé existe, alors : s'assurer que le fichier sera en lecture seule, créer la liste avec la page compilée. créer le fichier de projet avec la page compilée sinon afficher les raisons de l'échec et recommander la marche à suivre. fin si afficher le code de retour de la commande. afficher les listes pour contrôle et retourner la valeur 0 si tout est correct. {{Boîte déroulante début|titre=Code du module ''lister''|styleFrame=width:100%;|fondtitre=#F0F0F0<!--|styleTitre=color:white;<!|style=headerbleu-->}} ; Référence pour cet article : [https://fr.wikibooks.org/w/index.php?title=Auto-%C3%A9diter_un_wikilivre/Auto-r%C3%A9f%C3%A9rencer/lister.sh&oldid=641603 lister] ; Article actualisé :{{:Auto-éditer_un_wikilivre/Auto-référencer/lister.sh}} {{Boîte déroulante fin}} ==== Exemple de page ''Contenus'' du livre en test LivreTest ==== : LivreTest.contenu <pre> ; Article maître du livre [[Utilisateur:Goelette Cardabela/Sandbox/LivreTest|LivreTest]] ; Contenus [[Utilisateur:Goelette Cardabela/Sandbox/LivreTest/ArticleUn|ArticleUn]]<br /> [[Utilisateur:Goelette Cardabela/Sandbox/LivreTest/ArticleDeux|ArticleDeux]]<br /> [[Utilisateur:Goelette Cardabela/Sandbox/LivreTest/ArticleTrois|ArticleTrois]] {{Autocat}} </pre> La page ''Contenus'' d'une version imprimable contient l'Article maître du livre '''OU''' la liste des articles qui composent le livre. Dans ces tests nous incluons les deux versions qui nous permettrons de distinguer des présentations différentes de la page ''Annexe'' du livre. ==== Exemple de page du livre en test, LivreTest compilé ==== : LivreTest.compilé <pre> == LivreTest == === Tests de référencement === ; Article maître du livre :[[Utilisateur:Goelette Cardabela/Sandbox/LivreTest|LivreTest]] ; Contenus :[[Utilisateur:Goelette Cardabela/Sandbox/LivreTest/ArticleUn]] :[[Utilisateur:Goelette Cardabela/Sandbox/LivreTest/ArticleDeux]] :[[Utilisateur:Goelette Cardabela/Sandbox/LivreTest/ArticleTrois]] [[Catégorie:Compilations|LivreTest]] </pre> Nous faisons ici les mêmes remarques que pour la page ''Contenus'' de la version imprimable. La première ligne, qui est un lien vers la page principale n'existe pas, normalement, dans une version compilée. Si elle est présente dans de fichier, c'est pour la même raison de démonstration que précédemment: voir les différences de présentation de la page ''Annexe'' du livre. ==== Exemple de listes obtenues pour le livre ''LivreTest'' ==== : LivreTest.list <pre> https://fr.wikibooks.org/wiki/Utilisateur:Goelette Cardabela/Sandbox/LivreTest https://fr.wikibooks.org/wiki/Utilisateur:Goelette Cardabela/Sandbox/LivreTest/ArticleUn https://fr.wikibooks.org/wiki/Utilisateur:Goelette Cardabela/Sandbox/LivreTest/ArticleDeux https://fr.wikibooks.org/wiki/Utilisateur:Goelette Cardabela/Sandbox/LivreTest/ArticleTrois </pre> : LivreTest.prj <pre> LivreTest LivreTest/ArticleUn LivreTest/ArticleDeux LivreTest/ArticleTrois </pre> ==== Tests du module lister ==== Le but est d'obtenir un fichier qui content la liste des liens vers les pages d'un livre de wikilivres à documenter. Nous pouvons obtenir ces liens grâce aux pages « Contenus » des Versions imprimables et « Compilation » issue de la compilation d'une page. (Menu à gauche d'une page wikimedia.)<br /> Il est aussi possible d'éditer et d'enregistrer manuellement une telle liste. ===== Les lignes qui méritent notre attention ===== La ligne 65 dans l'édition du 26 avril 2020 :<br /> <small>{{bleu|Remarque : ''$Projet'' est un répertoire et ''$1.contenu'' est un fichier.}}</small> <syntaxhighlight lang="bash">cat $Projet/$1.contenu | sed "s/\[\[/$SitePrefix/g" | tr '|' '\n' | sed "s/\]\]//g" | grep "wiki" > $Projet/$1.list</syntaxhighlight> Cette ligne prend en compte le texte de la page '''''Contenus''''' de la '''''Version imprimable''''' du livre pour créer le fichier de liste. La ligne elle même signifie : <br /> <pre> &nbsp; ouvrir le flux du fichier '''''$Projet/$1.contenu''''' | filtrer et remplacer la chaîne "[[" par le préfixe du site $SitePréxixe (chaîne "https://fr.wikibooks.org/wiki/"), | filtrer et remplacer le caractère '|' par le caractère '\n' (retour-chariot), (si ce caractère '|' existe !), | filtrer et supprimer la chaîne "]]", (si cette chaîne existe !), | fitrer et ne retenir que la ligne qui contient la chaîne "wiki", &nbsp; > rediriger le flux vers la création du fichier '''''$Projet/$1.list'''''.</pre> La ligne 79 de la même édition : <syntaxhighlight lang="bash">cat $Projet/$1.compilé | sed "s/:\[\[/$SitePrefix/g" | tr '|' '\n' | sed "s/\]\]//g" | grep "wiki" > $Projet/$1.list</syntaxhighlight> Cette ligne prend en compte le texte de la page '''''Compilation''''' de la '''''Version compilée''''' du livre pour créer le fichier de liste. Le commentaire est le même que pour la ligne précédent à ceci près qu'au premier filtre on supprime aussi le caractère ':' du début de ligne des fichiers issus de la compilation. ===== Tests de la commande ===== # Copier le code du chapitre Lister dans un éditeur et enregistrer ce code dans le répertoire Annexe sous le nom « lister » ou « lister.sh » # Autoriser l'exécution du code par la commande '''chmod 777 ~/Annexe/lister''' # Copier le « Contenus » de la ''Version imprimable'' vu précédemment dans ce sous chapitre, # Enregistrer ce « Contenus » dans le fichier '''Annexe/LivreTest/LivreTest.contenus''' # Lancer la commande '''./lister LivreTest''' Vérifier que l'on obtient les fichier :'''~/Annexe/LivreTest/LivreTest.list''' : <pre> https://fr.wikibooks.org/wiki/Utilisateur:Goelette Cardabela/Sandbox/LivreTest https://fr.wikibooks.org/wiki/Utilisateur:Goelette Cardabela/Sandbox/LivreTest/ArticleUn https://fr.wikibooks.org/wiki/Utilisateur:Goelette Cardabela/Sandbox/LivreTest/ArticleDeux https://fr.wikibooks.org/wiki/Utilisateur:Goelette Cardabela/Sandbox/LivreTest/ArticleTrois</pre> Vérifier que l'on a modifié les autorisations du fichier LivreTest.contenus afin qu'il ne puisse pas être supprimé par mégarde lors des manipulations de fichiers. <br /> :'''~/Annexe/LivreTest/LivreTest.prj''' : <pre> LivreTest LivreTest/ArticleUn LivreTest/ArticleDeux LivreTest/ArticleTrois </pre> Vérifier avec la commande : ''~/Annexer$ ls -l ~/Annexer/LivreTest/LivreTest.contenu'', que le fichier LivreTest.contenu est en lecture seule pour tous les utilisateurs : -r--r--r--. -r--r--r-- 1 gc gc 353 avril 3 16:57 /home/gc/Annexer/LivreTest/LivreTest.contenu {{Nouvelle page imprimée}} === Télécharger (module) === ; (Download) :Télécharger le code source de la page ou la sous page grâce à la liste obtenue dans la section lister. ; Documentation : La commande ./télécharger <wikilivre> télécharge la page complète d'une "page" ou d'un "livre" de wikilivre. Elle crée les répertoires de travail avec la même hiérarchie que dans la page originale du livre, ou de sa version imprimable, ou de sa page de compilation. On procède par le téléchargement complet de la page et des sous-pages du livre. Viennent ensuite la création des répertoires de travail des pages qui composent le livre, puis on copie des pages html dans ces répertoires. Pendant tout ce processus des lichiers temporaires de liste sont créés en local: $Projet/$1.locale.list qui est une image locale de la structure du livre. $Projet/$1.mainPage. lien local vers l' "Article maître du livre" $Projet/$1.dirs : liste des sous-pages de l'article principal du livre. ; Organigramme : ## télécharger ############ télécharger dans le répertoire de travail, la structure complète du livre. Déplacer les pages html dans des sous-répertoires de travail pour documenter les pages et sous pages créer une liste locale vers les répertoires téléchargés $Projet/$1.locale.list Copier les fichiers html dans les répertoires respectifs. créer un fichier avec le nom de la page $Projet/$1.mainPage. initialiser la variable $mainPage créer un fichier des répertoires de travail à créer. copier les pages et sous pages html dans les répertoires respectifs. quitter le programme d'essai et passer à la création de la page "Annexe" des articles. {{Boîte déroulante début|titre=Code du module télécharger|styleFrame=width:100%;|fondtitre=#F0F0F0<!--|styleTitre=color:white;<!|style=headerbleu-->}} {{/télécharger}} {{Boîte déroulante fin}} ==== Test du module « télécharger » ==== Le but est de télécharger tous les fichiers html qui composent le livre grâce au fichier de liste obtenu précédemment. ===== Les lignes qui méritent notre attention ===== ligne48 de la version du 26 avril 2020 <Syntaxhighlight lang="bash"> wget -r -linf -k -p -E -i $1.list -o wget-log.txt echo "----------" </Syntaxhighlight> Cette ligne crée la '''structure complète''' des répertoires et fichiers, depuis la racine du site, jusqu'aux fichiers html qui composent le livre. {{Remarque| Il est à noter que les lignes du fichier de liste ''$1.list'' sont des liens internet vers des pages html bien que l'extension ''.html'' ne termine pas la ligne. {{Orange|Cette remarque est très importante car le dernier champ de chaque ligne n'est pas un répertoire, contrairement aux champs précèdents qui peuvent y faire penser.}} On peut utiliser cette ligne comme une ligne de texte ordinaire. Il faudra s'en souvenir, car nous utilisons le caractère '/' comme séparateur de champ qui fait penser à des répertoires. Des commandes comme ''cd'', ''cp'', et toute commandes qui a un rapport avec les répertoires peuvent ne pas vouloir s'exécuter.}} ; Exemple: lignes 80 à 96 de la version du 26avril 2020 <Syntaxhighlight lang="bash"> #O copier les pages et sous pages html dans les répertoires respectifs. while read line do echo "$line".html | sed "s/https:\/\///g" | tr '\n' ' ' > source read Source < source echo "Source = $Source" echo "$line" | awk -F"/" '{ print $NF }'| tr '\n' '/' > destination read dir < destination mkdir $dir echo "$line".html | awk -F"/" '{ print $NF }' >> destination read Destination < destination echo "Destination = $Destination" echo "Copier : cp ./$Source $Destination" cp -f "./$Source" "$Destination" done < $Projet/$1.list rm source ; rm destination </syntaxhighlight> :ligne 4 : On ajoute ''.html'' à la variable ''$ligne'' puis on copie dans le fichier ''source'' local, toute la ligne en supprimant ''https://''. :ligne 5 : On affecte la variable '''''S'''ource'' le texte enregistré dans le fichier '''''s'''ource'' :ligne 6 : On affiche à la console le nom de la variable $Source : :: Exemple pour la première ligne : ''fr.wikibooks.org/wiki/Utilisateur:Goelette Cardabela/Sandbox/LivreTest.html'' :ligne 8 : On copie le dernier champ de la ligne dans le fichier ''destination''. {{bleu|C'est du ''texte'' !}} :: Exemple pour la première ligne : ''LivreTest'' :ligne 10 : On en profite pour créer le répertoire correspondant à ce champ dans le répertoire courant. :: ''~/Annexer/LivreTest'' est le répertoire racine du projet, ''~/Annexer/LivreTest/LivreTest'' sera le répertoire de travail de la page principale. :ligne 11 : On ajoute à ce dernier champ l'extension ''.html'' que l'on ''concatène'' au fichier ''destination''. {{bleu|C'est une ''url'' !.}} :ligne 15 : On copie les fichiers ''html'' du répertoire ''source'' (local) vers le répertoire de ''destination'' (local). :: On obtient finalement le lien ''~/Annexer/LivreTest/LivreTest/LivreTest.html'' où la variable du projet ''$Projet'' est ''~/Annexer/LivreTest''. :: Il faudrait ajouter ''$Projet/'' devant ''source'' et ''destination'' pour être certain de copier dans le répertoire de travail racine. ===== Tests de la commande ''télécharger'' ===== Copier le code du chapitre Télécharger dans un éditeur et enregistrer ce code dans le répertoire Annexe sous le nom « télécharger » ou « télécharger.sh » Autoriser l'exécution du code par la commande chmod 777 ~/Annexe/télécharger Lancer la commande ./télécharger LivreTest On devrait obtenir : ;Structure complète du téléchargement avec la commande ''wget -r -linf -k -p -E -i $1.list -o wget-log-télécharger.txt'' ~/Annexer$ '''ls -R LivreTest/fr.wikibooks.org''' <pre>LivreTest/fr.wikibooks.org: robots.txt wiki LivreTest/fr.wikibooks.org/wiki: 'Utilisateur:Goelette Cardabela' 'LivreTest/fr.wikibooks.org/wiki/Utilisateur:Goelette Cardabela': Sandbox 'LivreTest/fr.wikibooks.org/wiki/Utilisateur:Goelette Cardabela/Sandbox': LivreTest LivreTest.html 'LivreTest/fr.wikibooks.org/wiki/Utilisateur:Goelette Cardabela/Sandbox/LivreTest': ArticleDeux.html ArticleTrois.html ArticleUn.html </pre> ;Liste des {{violet|répertoires}} créés avec la commande ''télécharger LivreTest''. $ '''ls -a -1 ~/Annexer$/LivreTest''' {{violet|<b>.<br /> ..<br /> ArticleDeux<br /> ArticleTrois<br /> ArticleUn<br /> fr.wikibooks.org<br /> LivreTest</b>}}<br /> LivreTest.compilé<br /> LivreTest.compilé.test<br /> LivreTest.contenu<br /> LivreTest.contenu.test<br /> LivreTest.dirs<br /> LivreTest.list<br /> LivreTest.locale.list<br /> LivreTest.mainPage<br /> LivreTest.prj<br /> wget-log-télécharger.txt {{Nouvelle page imprimée}} === Ajouter sclt (module) === ; (Adding sclt) or (Append sclt) Ajouter la section article, source, licence, contributeur(s). ; Documentation <pre> La commande ./ajouter-sclt <wikilivre> commence par créer la page $Projet/$1.sclt comme elle apparaîtra dans la première partie de la page "Annexe" du livre avec les titre en wikitexte et les sections : Références: toutes celles qui n'ont pas été affichées dans les pages. Contenus: liens établis vers la page du livre et les articles (sous-pages) Source de l'édition: lien vers la page qui a permis de créer l' "Annexe". Sources licences et contributeurs des articles: ne concerne que les articles, les sous-pages.</pre> ; Organigramme <pre> ## ajouter_sclt ########### but final: créer la page "Annexe" avec les pages Projet.sclt et Projet.scli. --- créer la page PageSclt=$Projet/$1.sclt et afficher son contenu. ajouter la balise <references /> ajouter le lien vers : la page du livre imprimable, et vers les articles. créer la section 'Article', 'Source', 'licence', 'Contributeur(?)' ajouter le texte : Les ''sources'' listées pour chaque article fournissent des informations de licence plus détaillées, y compris le statut des droits d'auteurs, les détenteurs de ces droits et les conditions de licence. ou, valider l'un ou l'autre de ces textes : Les textes sont disponibles avec leurs licences respectives, cependant d’autres termes peuvent s’appliquer.<br /> Voyez les termes d’utilisation pour plus de détails :<br /> https://wikimediafoundation.org/wiki/Conditions_d'utilisation Créer ou recréer le fichier de liste $Projet/$1.pj tant qu'il y a des lignes dans le fichier de liste, afficher la ligne lue, extraire et copier toutes les chaînes de caractères du fichier html $ligne.html dans le fichier $ligne.str et les dupliquer à l'écran créer les fichiers de documentation des pages : article, source, auteur(s).</pre> {{Boîte déroulante début|titre=Code du module ajouter_sclt|styleFrame=width:100%;|fondtitre=#F0F0F0<!--|styleTitre=color:white;|style=headerbleu-->}} {{/ajouter_sclt}} {{Boîte déroulante fin}} ==== Tests du module ajouter_sclt ==== Le but est de créer l'entête de la page Annexe et d'y ajouter la liste des ''articles avec les sources, licences, contributeurs''. Les numéros des pages n'est possibles que lorsque la version imprimable aura été créée, avec une post-indexation et une post-annexion. ===== Les lignes qui méritent notre attention ===== '''Remarque : '''Dans les explications du code on entend par '''''projet''''' le nom du projet entré en paramètre dans la commande ''./ajouter_sclt projet'' Lignes 117-119 de la version du 29 avril 2020 #O extraire et copier toutes les chaînes de caractères du fichier html #O $ligne.html dans le fichier $ligne.str et les dupliquer à l'écran mkd -pws '**' $Projet/$ligne/$ligne.html $Projet/$ligne/$ligne.tmp | tr ',' '\n' > $Projet/$ligne/$ligne.str '''mkd''' n'est pas inclus dans les distributions linux. les paquets et sources sont téléchargeable pour tous les systèmes d'exploitation.<br /> Pour toute informations complémentaires : [[w:mkd (commande unix)|mkd (commande unix)]], [[Mkd_(Extracteur_de_documents)]]<br /> Cette ligne de commandes extrait tous les commentaires avec une sortie dans un fichier ''projet.tmp'' ainsi que vers la ''sortie standard'' <small>''(l'écran par défaut)''</small> où elle est reprise pour être listée en colonne grâce au séparateur de chaînes ','. Lignes 124-130 #O article, if [ $ligne != $1 ] then echo "'''"$ligne"'''" >> $PageSclt fi echo "'''"$ligne"'''" > $Projet/$ligne/$ligne.article cat $Projet/$ligne/$ligne.article '''$ligne''' est la variable lue ligne par ligne du fichier de liste ''projet.pj'' dans une boucle ''tant qu'il y a des lignes à lire, faire ...''<br /> Cette ligne est aussi le nom de l''''article''' qui va être analysé. Si $ligne n'est pas le nom du livre (de l'article principal) le nom de l'article est ajouté à la page $PageSclt. Lignes 132-139 #O source, echo -n ", ''source : ''https://"$Site"/w/index.php?oldid=" > $Projet/$ligne/$ligne.RevisionId cat $Projet/$ligne/$ligne.str | grep -n -m 1 -i -e wgRevisionId | tr -d ':' | sed "s/\"/%/g" | cut -d'%' -f3 >> $Projet/$ligne/$ligne.RevisionId if [ $ligne != $1 ] then cat $Projet/$ligne/$ligne.RevisionId >> $PageSclt fi cat $Projet/$ligne/$ligne.RevisionId La deuxième ligne crée le fichier de ''.RevisionId'' dans lequel on écrit une chaîne de caractères sans retour à la ligne.<br /> La troisième ligne : &nbsp; cat ouvre le flux du fichier ''projet.str'' | retient la ligne qui contient wgRevisionId, | supprime le caractère ':' qu'il contient | remplace les caractères '"' par le caractère '%' | coupe la chaîne à l'endroit où se trouvent les caractères '%' et sélectionne le champ 3. >> la chaîne résultante est ajoutée au fichier ''projet.RevisionId'' Lignes 152-164 1 #O license : 2 echo -n ", ''licence : ''" > $Projet/$ligne/$ligne.license 3 #T cat $Projet/$ligne/$ligne.str | grep -n -m 1 -i -e license | sed "s/\"\//%\//g" | cut -d'%' -f4 >> $Projet/$ligne/$ligne.license 4 cat $Projet/$ligne/$ligne.str | grep -n -m 1 -i -e license | sed "s/\"\//%\//g" | tr '"' '%' | cut -d'%' -f4 >> $Projet/$ligne/$ligne.license 5 #T cat $Projet/$ligne/$ligne.str | grep -n -m 1 -i -e license | sed "s/\"\//%\//g" | cut -d'%' -f2 | sed "s/\/\//https:\/\//g" >> $Projet/$ligne/$ligne.license 6 if [ $ligne != $1 ] 7 then 8 cat $Projet/$ligne/$ligne.license >> $PageSclt 9 fi 10 cat $Projet/$ligne/$ligne.license 11 # 12 #P spécial pour bas de page fr ## 13 cat $Projet/$ligne/$ligne.str | grep -n -m 1 -i -e footer-info-copyright | sed "s/\"\//%\//g" | tr '"' '%' | cut -d'%' -f4 > $Projet/$ligne/$ligne.licence * La ligne 2 initialise dans le répertoire $Projet/$ligne/, le fichier $ligne.license de l'article $ligne. exemple : le répertoire de l'ArticleUn est ~/Annexer/LivreTest/ArticleUn/ dans lequel on va écrire ArticleUn.license * Les lignes 3 et 5 sont des commentaires de tests à l'usage des programmeurs.<br /> * La ligne 4 produit les fichier .license dans le répertoire de l'article correspondant.<br /> * La ligne 5 : &nbsp; cat ouvre le flux du fichier ''projet.str'', | retient la ligne qui contient ''license'', | sélectionne la chaîne "/ et la remplace par la chaîne %/, | supprime '%' et coupe la chaîne au caractère '%' puis sélectionne le deuxième tronçon (-f2), il existe aussi (-f2-3, -f2-4) etc. | remplacer les caractères // par https:// >> copier la chaîne dans le fichier ''projet.license'' * Les lignes 6 à 9 ajoutent la '''''license''''' à $PageSclt si la licence concerne un article et non la page principale du livre.<br /> * La ligne 10 affiche à l'écran le contenu du fichier qui vient d'être créé.<br /> * La ligne 13 : mêmes remarques que précédemment par sélection du bas de page en français avec '''''licence'''''. Lignes 155-159 #O auteur(s). echo -n ", ''auteur(s) : ''" > $Projet/$ligne/$ligne.auteur cat $Projet/$ligne/$ligne.str | grep -n -m 1 -i -e wgRelevantUserName | sed "s/\"/%/g" | cut -d'%' -f4 >> $Projet/$ligne/$ligne.auteur if [ $ligne != $1 ] then cat $Projet/$ligne/$ligne.auteur >> $PageSclt fi cat $Projet/$ligne/$ligne.auteur * mêmes remarques que pour les actions précédentes. ===== Tests de la commande ===== ; fichier obtenu avec la commande ~/Annexer/ajouter_sclt LivreTest '''cat LivreTest.sclt''' dans le répertoire du projet ''LivreTest'' <pre> = Annexe = == Références == <references /> {{Nouvelle page imprimée}} == Contenus == <small> https://fr.wikibooks.org/wiki/Utilisateur:Goelette_Cardabela/Sandbox/LivreTest https://fr.wikibooks.org/wiki/Utilisateur:Goelette_Cardabela/Sandbox/LivreTest/ArticleUn https://fr.wikibooks.org/wiki/Utilisateur:Goelette_Cardabela/Sandbox/LivreTest/ArticleDeux https://fr.wikibooks.org/wiki/Utilisateur:Goelette_Cardabela/Sandbox/LivreTest/ArticleTrois </small> === Source de cette édition === <small> https://fr.wikibooks.org/wiki/Utilisateur:Goelette_Cardabela/Sandbox/LivreTest </small> {{Nouvelle page imprimée}} == Sources licences et contributeurs des articles == Les ''sources'' listées pour chaque article fournissent des informations de licence plus détaillées, y compris le statut des droits d'auteurs, les détenteurs de ces droits et les conditions de licence. <div style="font-size:72.5%;"> '''ArticleUn''' , ''source : ''https://fr.wikibooks.org/w/index.php?oldid=632571 , ''licence : ''https://creativecommons.org/licenses/by-sa/3.0/ , ''auteur(s) : ''Goelette Cardabela '''ArticleDeux''' , ''source : ''https://fr.wikibooks.org/w/index.php?oldid=632572 , ''licence : ''https://creativecommons.org/licenses/by-sa/3.0/ , ''auteur(s) : ''Goelette Cardabela '''ArticleTrois''' , ''source : ''https://fr.wikibooks.org/w/index.php?oldid=632573 , ''licence : ''https://creativecommons.org/licenses/by-sa/3.0/ , ''auteur(s) : ''Goelette Cardabela </div> {{Nouvelle page imprimée}} </pre> ; Apparence provisoire un peu arrangée pour ne pas intervenir sur l'index des sections de cet article ... ---- <big>''' Annexe '''</big> ''' Références ''' <references /> {{Nouvelle page imprimée}} ''' Contenus ''' <div style="font-size:85%;"> https://fr.wikibooks.org/wiki/Utilisateur:Goelette_Cardabela/Sandbox/LivreTest https://fr.wikibooks.org/wiki/Utilisateur:Goelette_Cardabela/Sandbox/LivreTest/ArticleUn https://fr.wikibooks.org/wiki/Utilisateur:Goelette_Cardabela/Sandbox/LivreTest/ArticleDeux https://fr.wikibooks.org/wiki/Utilisateur:Goelette_Cardabela/Sandbox/LivreTest/ArticleTrois '''Source de cette édition''' https://fr.wikibooks.org/wiki/Utilisateur:Goelette_Cardabela/Sandbox/LivreTest </div> {{Nouvelle page imprimée}} ''' Sources licences et contributeurs des articles ''' Les ''sources'' listées pour chaque article fournissent des informations de licence plus détaillées, y compris le statut des droits d'auteurs, les détenteurs de ces droits et les conditions de licence. <div style="font-size:72.5%;"> '''ArticleUn''' , ''source : ''https://fr.wikibooks.org/w/index.php?oldid=632571 , ''licence : ''https://creativecommons.org/licenses/by-sa/3.0/ , ''auteur(s) : ''Goelette Cardabela '''ArticleDeux''' , ''source : ''https://fr.wikibooks.org/w/index.php?oldid=632572 , ''licence : ''https://creativecommons.org/licenses/by-sa/3.0/ , ''auteur(s) : ''Goelette Cardabela '''ArticleTrois''' , ''source : ''https://fr.wikibooks.org/w/index.php?oldid=632573 , ''licence : ''https://creativecommons.org/licenses/by-sa/3.0/ , ''auteur(s) : ''Goelette Cardabela </div> ---- {{Nouvelle page imprimée}} === {{50}} Ajouter scli ''(trois modules indépendants)'' === ; (Adding scli) or (Append scli) Ajouter la section image, source, license, contributeurs(s) à la page ''Annexe''. ==== Les fichier de commandes scli ==== ;On peut concevoir deux façon ce référencer les images: * '''La version globale : '''on extrait les images de la page principale. <div style="font-size:85%;">'''Illustration 1''' ''Source : ''..., ''Licence : ''..., ''Contributeur : ''... '''Illustration 2''' ''Source : ''..., ''Licence : ''..., ''Contributeur : ''... '''Illustration 3''' ''Source : ''..., ''Licence : ''..., ''Contributeur : ''... '''Illustration 4''' ''Source : ''..., ''Licence : ''..., ''Contributeur : ''... </div> * '''La version par article : '''les images sont extraites de chaque article, ce qui donne : '''Article 1 :''' <div style="font-size:85%;">'''Illustration 1.0''' ''Source : ''..., ''Licence : ''..., ''Contributeur : ''... '''Illustration 1.n''' ''Source : ''..., ''Licence : ''..., ''Contributeur : ''...</div> '''Article 2 :''' <div style="font-size:85%;">'''Illustration 2.0''' ''Source : ''..., ''Licence : ''..., ''Contributeur : ''... '''Illustration 2.n''' ''Source : ''..., ''Licence : ''..., ''Contributeur : ''... </div> {{Nouvelle page imprimée}} ===== {{100}} ''Version classique sclic (module)'' ===== <!--{{En cours}}--> ; Documentation programmeur <pre> ## ajouter_sclic ########## Remarques : à ce stade, Les fichiers $1.list, $1.prj, $1.pj, $1.sclt, $.mainPage sont cencés préexister dans le répertoire racine du projet $1. De même, les fichiers <Article>.str sont sensés préexister dans les répertoires <Article> correspondants. seront créés : dans le rétoire de travail racine ~/Annexe/$1/. : le fichier $1.sclic qui vient compléter le fichier $1.sclt afin de créerle fichier "Annexe", dans le sous-répertoire de travail ~/Annexe/$1/$1/. : $1.files, $1.pict, $1.illustrations, $1.links, html.list et les fichiers d'images .title, .source, .license, .auteur. </pre> ; Organigramme programmeur <pre> inclure le fichier d'entête header.sh ## ajouter_scli_classique ########### ligne de commande "ajouter_sclic <livre>" où "livre" = variable $1 PageScliC sera la variable d'identifiation du fichier "livre.sclic" placé dans le répertoire" de travail du projet : $Projet = ~/Annexe/$1/. se placer dans le sous-répertoire de travail "$Projet/$1/" rappel : $Projet = ~/Annexer/$1 d'où ss-rep = ~/Annexer/$1/$1/. créer la section 'Image', 'Source', 'licence', 'Contributeur(?)' ajouter le texte : style PediaPress ou personnalisé.; Organigramme inclure le fichier d'entête header.sh ## ajouter_scli_classique ########### ligne de commande "ajouter_sclic <livre>" où "livre" = variable $1 PageScliC sera la variable d'identifiation du fichier "livre.sclic" placé dans le répertoire" de travail du projet : $Projet = ~/Annexe/$1/. se placer dans le sous-répertoire de travail "$Projet/$1/" rappel : $Projet = ~/Annexer/$1 d'où ss-rep = ~/Annexer/$1/$1/. créer la section 'Image', 'Source', 'licence', 'Contributeur(?)' ajouter le texte : style PediaPress ou personnalisé. style PediaPress : Les ''sources'' listées pour chaque article fournissent des informations de licence plus détaillées, y compris le statut des droits d'auteurs, les détenteurs de ces droits et les conditions de licence. ou: (imprimer l'un ou l'autre de ces textes) style personnalisé : Les textes sont disponibles avec leurs licences respectives, cependant d’autres termes peuvent s’appliquer.<br /> Voyez les termes d’utilisation pour plus de détails :<br /> https://wikimediafoundation.org/wiki/Conditions_d'utilisation créer les fichiers de documentation des images de la page principale. ouvrir le flux $Projet/$1/$1.str de la page principale et sélectionner les chaînes de caractères contenant fichier:, file:, image:, dans le nouveau fichier $Projet/$1/$1.files télécharger les fichiers d'images depuis le serveur wikimedia. initialiser le fichier de liste html.list avec un texte vide. lister les fichiers d'images dans l'ordre d'impression ou de l'affichage, à laide de la liste $1.links. créer les fichiers de documentation des pages : tant qu'il y a des liens (locaux) dans le fichier d'images html.list afficher la ligne lue, sélectionner les chaînes du fichier d'image et les transférer dans images, sources, licence, auteur(s). terminer la page $PageScliC fin du tant qu'il y a des lignes terminer la page $PageScliC </pre> {{Boîte déroulante début|titre=Code ajouter_sclic|styleFrame=width:100%;|fondtitre=#F0F0F0<!--|styleTitre=color:white;|style=headerbleu-->}} {{/ajouter_sclic}} {{Boîte déroulante fin}} ===== Programme des tests du module ajouter_sclic ===== ===== Les lignes qui méritent notre attention ===== ===== Tests de la commande ajouter_sclic ===== ====== Fichiers obtenus avec la commande ~/Annexer/ajouter_sclic LivreTest ====== ;contenu du fichier /home/jpl/Annexer/LivreTest/LivreTest.pj : https://commons.wikimedia.org/wiki/File:Commerce_de_communautés_indigènes.JPG https://commons.wikimedia.org/wiki/File:Fernando_Botero_(2018).jpg https://commons.wikimedia.org/wiki/File:Gabriel_Garcia_Marquez_-_Fresque.jpg https://commons.wikimedia.org/wiki/File:Pano_Plazo_Botero.jpg ; fichier LivreTest.sclic <pre> == Sources des images licences et contributeurs == <small>Les ''sources'' listées pour chaque illustration fournissent des informations de licence plus détaillées, y compris le statut des droits d'auteurs, les détenteurs de ces droits et les conditions de licence.</small> <div style="font-size:72.5%;"> '''Illustration : '''Gabriel Garcia Marquez - Fresque.jpg , ''source : ''https://fr.wikibooks.org/w/index.php?title=File:Gabriel_Garcia_Marquez_-_Fresque.jpg , ''licence : ''CC BY-SA 4.0 , ''auteur(s) : ''User:Pohline_Blast_Clm '''Illustration : '''Commerce de communautés indigènes.JPG , ''source : ''https://fr.wikibooks.org/w/index.php?title=File:Commerce_de_communautés_indigènes.JPG , ''licence : ''CC BY-SA 3.0 , ''auteur(s) : ''User:Goelette.Cardabela '''Illustration : '''Fernando Botero (2018).jpg , ''source : ''https://fr.wikibooks.org/w/index.php?title=File:Fernando_Botero_(2018).jpg , ''licence : ''CC BY 3.0 , ''auteur(s) : ''- '''Illustration : '''Pano Plazo Botero.jpg , ''source : ''https://fr.wikibooks.org/w/index.php?title=File:Pano_Plazo_Botero.jpg , ''licence : ''Public domain , ''auteur(s) : ''User:Scabredon~commonswiki </div> {{Nouvelle page imprimée}} </pre> {{Nouvelle page imprimée}} ====={{0}} ''Version personnalisée par article sclip (module)'' ===== Cette commande est composée de trois parties : # Le module principal. Il prépare l'entête de la section ''Images, source, licence, auteur'' puis exécute l'un ou l'autre des modules de récupération des images. # Le module de récupération des images de Commons dans le sous-répertoire de la page du livre. # Le module de récupération des images sur le site Wikilivres. Chacun de ces modules peut être éprouvé séparément. Il n'est pas envisagé de détailler l'explication des lignes de codes, on peut considérer que la compréhension des codes de commandes bash est suffisamment assimilée à ce niveau de la programmation.<br /> Les explications éventuelles se trouvent au sein du code de programmation. {{Nouvelle page imprimée}} ====={{100}} Entête ajouter_sclip ===== {{RemarqueIndex|Ce module est devenu l'entête des modules sclipco.inc et sclipwb.inc pour faciliter l'écriture de la page principale ''Annexer'', il peut être éprouvé séparément comme tous les modules de ce programme.}} ; Documentation : ## ajouter_sclic ########## Le répertoire de travail est le sous répertoire du projet $Projet/$1/$1 plus précisément : ~/Annexer/<nom du livre>/<nom du livre> <nom du livre> pourrait être la sous-page 'Version imprimable' du livre et peut être considéré comme un 'Article'. Remarques : à ce stade, Les fichiers $1.list, $1.prj, $1.pj, $1.sclt, $.mainPage sont censés préexister dans le répertoire racine du projet $1 (nom du livre). De même, les fichiers <Article>.str sont sensés préexister dans les répertoires <Article> correspondants. Seront créés : * Dans le répertoire de travail racine ~/Annexe/$1/. : le fichier $1.sclic qui vient compléter le fichier $1.sclt afin de créer le fichier "Annexe", * dans le sous-répertoire de travail ~/Annexe/$1/$1/. : $1.files, $1.pict, $1.illustrations, $1.links, html.list et les fichiers d'images .str .title, .source, .license, .auteur. ## ajouter_sclip ########## Ce module est l'entête des programmes sclipco.inc et sclipwb.inc du programme Annexer : Si une des options -pc ou -pb de la ligne de commande 'annexer <livre>' est validée, le module ajouter_sclip est exécuté puis un des modules sclipco ou sclipwb est exécutés selon l'option choisie -pc ou -pb. (-pc pour images sur 'Commons', -pb pour images sur 'Wikilivres'.) Structure, organisation des fichiers : Les répertoires de travail sont les répertoires des 'Articles'. Le fichier $Projet/$ligne/$ligne.str a été créé avec la commande ajouter_sclt Remarques : 1.les images extraites avec le fichier de commandes ajouter_sclic peuvent être copiées dans les répertoires des articles correspondants lorsqu'ils sont identifiés dans leurs répertoires respectifs pour créer une option d'images téléchargées de 'Commons'. 2.le fichier de conversions url/html vers utf8 a été inclus dans l'entête header.sh depuis le 13 mai 2020 ; Documentation programmeur : <pre> 2:#P Nom du fichier de commandes : ajouter_sclip 3:#P Syntaxe : "ajouter_sclip <nom du livre>" 4:#P Exemple : "./ajouter_sclip LivreTest" à la console. 5:#P Date de création : 9 mai 2020 6:#P Modifié le : 15 mai 2020 par GC pour ajouter une version d'images depuis 7:#P wilimedia commons 8:#P Modifié le : 16 mai 2020 par GC pour séparer les fichier en trois parties 9:#P Partie 1 : entête des deux versions de téléchargement, 'ajouter_sclip'. 10:#P Partie 2 : fichier de téléchargement des images sur wikibooks, sclipwb.inc 11:#P Partie 3 : fichier de téléchargement des images sur coomons, sclipco.inc 12:#P Version sur WikiLivres le : 17 mai 2020 13:#P 14:#P LES FICHIERS DE COMMANDES 15:#P 16:#P## header.sh ############## 17:#P header.sh, a créé le répertoire des commandes si celui-ci ne préexistait pas 18:#P il a vérifié la validité ou invalidé de ligne de commande, initialisé 19:#P les variables $Projet, $Site, $SitePrefix, vérifié l'existence des 20:#P fichiers de liste "$Projet/$1".list et "$Projet/$1".prj, puis affiché le 21:#P contenu du répertoire de travail. 22:#P 23:#P## lister ################# 24:#P lister a créé le fichier de liste $Projet/$1.list par l'extraction du 25:#P fichier $Projet/$1.contenu, copie de la page "Contenus" de la version 26:#P imprimable du livre, ou du fichier $Projet/$1.compilé issu d'une 27:#P compilation destinée à la publication par PediaPress. 28:#P il crée aussi le fichier $Projet/$1.prj qui conserve l'ordre d'affichage 29:#P de la publication. 30:#P 31:#P## télécharger ############ 32:#P la commande aura téléchargé toutes les pages du livre et aura copié les 33:#P pages html dans des répertoires qui leurs sont dédiés pour y extraire 34:#P toute la documentation nécessaire à la création de la page "Annexe", et 35:#w à ce stade, pour les tests avec LivreTest; on dispose des répertoires 36:#w de travail : LivreTest, ArticleUn, ArticleDeux, ArticleTrois. 37:#P qui contiennent chacun le fichier html de la page ou de l'article qui le 38:#P concerne. 39:#P L'ensemble des commandes aura créé les fichiers de listes : 40:#P $Projet/$1.dirs, $Projet/$1.list, $Projet/$1.mainPage, $Projet/$1.prj 41:#P 42:#P## ajouter_sclt ########### 43:#P La commande ./ajouter-sclt <wikilivre> commence par créer la page 44:#P $Projet/$1.sclt comme elle apparaîtra dans la première partie de la page 45:#P "Annexe" du livre, avec les titres et les sections en wikitexte : 46:#P * Références: toutes celles qui n'ont pas été affichées dans les pages. 47:#P * Contenus: liens établis vers la page du livre et les articles. 48:#P (les sous-pages). 49:#P * Source de l'édition: lien vers la page qui a permis de créer l'Annexe. 50:#P * Sources licences et contributeurs des articles: ne concerne que les 51:#P articles, les sous-pages. 52:#P 53:#D## ajouter_sclic ########## 54:#D Le répertoire de travail est le sous répertoire du projet $Projet/$1/$1 55:#D plus précisément : ~/Annexer/<nom du livre>/<nom du livre> 56:#D <nom du livre> pourrait être la sous-page 'Version imprimable' du livre 57:#D et peut être considéré comme un 'Article'. 58:#D Remarques : 59:#D à ce stade, Les fichiers $1.list, $1.prj, $1.pj, $1.sclt, $.mainPage sont 60:#D censés préexister dans le répertoire racine du projet $1 (nom du livre). 61:#D De même, les fichiers <Article>.str sont sensés préexister dans les 62:#D répertoires <Article> correspondants. 63:#D Seront créés : 64:#D * Dans le répertoire de travail racine ~/Annexe/$1/. : 65:#D le fichier $1.sclic qui vient compléter le fichier $1.sclt afin de créer 66:#D le fichier "Annexe", 67:#D * dans le sous-répertoire de travail ~/Annexe/$1/$1/. : 68:#D $1.files, $1.pict, $1.illustrations, $1.links, html.list et 69:#D les fichiers d'images .str .title, .source, .license, .auteur. 70:#D 71:#D## ajouter_sclip ########## 72:#D Ce module est l'entête des programmes sclipco.inc et sclipwb.inc du 73:#D programme Annexer : 74:#D Si une des options -pc ou -pb de la ligne de commande 'annexer <livre>' 75:#D est validée, le module ajouter_sclip est exécuté puis un des modules 76:#D sclipco ou sclipwb est exécutés selon l'option choisie -pc ou -pb. 77:#D (-pc pour images sur 'Commons', -pb pour images sur 'Wikilivres'.) 78:#D Structure, organisation des fichiers : 79:#D Les répertoires de travail sont les répertoires des 'Articles'. 80:#D Le fichier $Projet/$ligne/$ligne.str a été créé avec la commande 81:#D ajouter_sclt 82:#D Remarques : 83:#D 1.les images extraites avec le fichier de commandes ajouter_sclic peuvent 84:#D être copiées dans les répertoires des articles correspondants lorsqu'ils 85:#D sont identifiés dans leurs répertoires respectifs pour créer une option 86:#D d'images téléchargées de 'Commons'. 87:#D 2.le fichier de conversions url/html vers utf8 a été inclus dans l'entête 88:#D header.sh depuis le 13 mai 2020 89:#D 90:#P Générer la documentation de cette page : 93:#P Générer la documentation programmeur : 96:#P Générer l'organigramme de cette commande : 99:#P </pre> ; Organigramme : <pre> 101:#O inclure le fichier d'entête header.sh 104:#O## ajouter_scli_p (personnalisé) ############ 106:#O ligne de commande "ajouter_sclip <livre>" où "livre" = variable $1 108:#O PageScliP sera la variable d'identifiation du fichier "livre.sclip" placé 109:#O dans le répertoire" de travail du projet : $Projet = ~/Annexe/$1/. 114:#O créer la section 'Image', 'Source', 'licence', 'Contributeur(?)' 116:#O ajouter le texte : style PediaPress ou personnalisé. 117:#O style PediaPress : 118:#O Les ''sources'' listées pour chaque article fournissent des informations 119:#O de licence plus détaillées, y compris le statut des droits d'auteurs, les 120:#O détenteurs de ces droits et les conditions de licence. 122:#O ou: (imprimer l'un ou l'autre de ces textes) 123:#O style personnalisé : 124:#O Les textes sont disponibles avec leurs licences respectives, cependant 125:#O d’autres termes peuvent s’appliquer.<br /> 126:#O Voyez les termes d’utilisation pour plus de détails :<br /> 127:#O https://wikimediafoundation.org/wiki/Conditions_d'utilisation </pre> {{Boîte déroulante début|titre=Code ajouter_sclip|styleFrame=width:100%;|fondtitre=#F0F0F0<!--|styleTitre=color:white;|style=headerbleu-->}} {{/ajouter_sclip}} {{Boîte déroulante fin}} {{Nouvelle page imprimée}} ====={{50}} Module sclipco.inc ===== {{Boîte déroulante début|titre=Code sclipco.inc|styleFrame=width:100%;|fondtitre=#F0F0F0<!--|styleTitre=color:white;|style=headerbleu-->}} {{/sclipco.inc}} {{Boîte déroulante fin}} {{Nouvelle page imprimée}} ====={{100}} Modude sclipwb.inc ===== {{Boîte déroulante début|titre=Code sclipwb.inc|styleFrame=width:100%;|fondtitre=#F0F0F0<!--|styleTitre=color:white;|style=headerbleu-->}} {{/sclipwb.inc}} {{Boîte déroulante fin}} {{Nouvelle page imprimée}} ==== Comparaison des annexes obtenues pour la page ''LivreTest'' ==== ===== Annexe classique avec sclic ===== {{RemarqueIndex|[[Utilisateur:Goelette_Cardabela/Sandbox/LivreTest/Annexe_bis|Annexe classique de LivreTest avec sclic]]<br />Cette présentation peut être utile pour une extension d' ''Index'', ''Table des matières'' et numérotation des pages avec OpenOffice.}} [https://fr.wikibooks.org/w/index.php?title=Utilisateur:Goelette_Cardabela/Sandbox/LivreTest/Annexe_bis&action=edit Éditer cette annexe.] {{Nouvelle page imprimée}} ===== Annexe personnalisée avec le téléchargement sur le serveur ''Commons'' ===== {{RemarqueIndex|[[Utilisateur:Goelette_Cardabela/Sandbox/LivreTest/Annexe_commons|Annexe pesonnalisée de LivreTest avec sclipco.inc]]<br />Cette présentation simple permet de repérer les illustrations en fonction des chapitres, sans numérotation des pages.}} [https://fr.wikibooks.org/w/index.php?title=Utilisateur:Goelette_Cardabela/Sandbox/LivreTest/Annexe_commons&action=edit Éditer cette annexe.] {{Nouvelle page imprimée}} ===== Annexe personnalisée avec le téléchargement sur le serveur ''Wikilivres'' ===== {{RemarqueIndex|[[Utilisateur:Goelette_Cardabela/Sandbox/LivreTest/Annexe_wikilivres|Annexe pesonnalisée de LivreTest avec sclipwb.inc]]<br />Cette présentation simple permet de repérer les illustrations en fonction des chapitres, sans numérotation des pages. On notera la différence avec la version ''Commons'' pour la résolution du nom d'auteur de l'image.}} [https://fr.wikibooks.org/w/index.php?title=Utilisateur:Goelette_Cardabela/Sandbox/LivreTest/Annexe_wikilivres&action=edit Éditer cette annexe.] {{Nouvelle page imprimée}} ===== Comparaison avec l'annexe manuelle ou semi-manuelle ===== {{RemarqueIndex|<br />[[Utilisateur:Goelette_Cardabela/Sandbox/LivreTest/Annexe|Visualiser l' Annexe manuelle ou semi-manuelle de LivreTest]], produite avec des [[Go%C3%A9lette_Cardabela/Sommaire#Canevas|cannevas.]]}} [https://fr.wikibooks.org/w/index.php?title=Utilisateur:Goelette_Cardabela/Sandbox/LivreTest/Annexe&action=edit Éditer cette version manuelle.] {{Nouvelle page imprimée}} == Tests unitaires et d'intégration == Les fichiers de commandes shell peuvent être éprouvés successivement, sous linux ou sous d'autres systèmes d'exploitation acceptant les commandes '''''shell bash''''' : Windows 10<ref>https://korben.info/installer-shell-bash-linux-windows-10.html</ref><ref>http://montefiore.ulg.ac.be/~nvecoven/ci/files/tuto_bash/tuto_bash.html</ref>, [[w:MinGw|MinGw]], [[w:Cygwin|Cygwin]], .... Pour effectuer ces tests il faut se placer dans le répertoire utilisateur et créer un répertoire qui regroupe les fichiers de commandes. Dans les exemples présentés : mkdir ~/Annexer '''Les fichiers de commandes :''' <br /> '''''header.sh, annexer, lister, télécharger, ajouter-sclt, ajouter-sclic, ajouter-sclip,''''' sont prévus pour être placés dans ce répertoire des commandes '''''~/Annexer'''''. Le fichier header.sh est non seulement un fichier de commandes, il est aussi un fichier d'entête pour tous les modules en tests unitaires. Les commandes peuvent être éprouvées avec tous les livres disponibles. Pour les essais de ces versions en tests, nous avons utilisé le livre « LivreTest ». La commande « annexer » permet le test d'intégration de tous les modules avec des points d'arrêt possibles après chaque module testé. Rendez-vous dans le chapitre [[Auto-%C3%A9diter_un_wikilivre/Auto-r%C3%A9f%C3%A9rencer#Annexer_(main)|Annexer]] pour effectuer ces test et/ou avoir plus d'informations. {{Nouvelle page imprimée}} == Copier et installer les fichiers de l'application et des tests == {{orange|<small>Ces versions, mises à jour, peuvent être différentes des premières versions exposées dans les chapitres de cet article.</small>}} Éditer la page originale<ref>[https://fr.wikibooks.org/wiki/Auto-%C3%A9diter_un_wikilivre/Auto-référencer/Annexer_(Version_orignale) Installer les fichiers de l'application originale en français]</ref> {{:Auto-éditer_un_wikilivre/Auto-référencer/Annexer (Version orignale)}} {{Nouvelle page imprimée}} == Post-référencer post-indexer un wikilivre == {{:Auto-éditer_un_wikilivre/Post-référencer}} == Références== <references /> {{Nouvelle page imprimée}} == Index des sections == Sections ↑ 1 Codes shell pour créer la page « Annexe » d'un wikilivre 1.1 Entête des modules 1.2 Annexer (main) 1.2.1 Tests unitaires du fichier de commandes annexer 1.2.2 Annexe obtenue 1.2.2.1 Impression visuelle de cette annexe 1.3 Lister (module) 1.3.1 Exemple de page Contenus du livre en test LivreTest 1.3.2 Exemple de page du livre en test, LivreTest compilé 1.3.3 Exemple de listes obtenues pour le livre LivreTest 1.3.4 Tests du module lister 1.3.4.1 Les lignes qui méritent notre attention 1.3.4.2 Tests de la commande 1.4 Télécharger (module) 1.4.1 Test du module « télécharger » 1.4.1.1 Les lignes qui méritent notre attention 1.4.1.2 Tests de la commande télécharger 1.5 Ajouter sclt (module) 1.5.1 Tests du module ajouter_sclt 1.5.1.1 Les lignes qui méritent notre attention 1.5.1.2 Tests de la commande 1.6 Ajouter scli (trois modules indépendants) 1.6.1 Les fichier de commandes scli 1.6.1.1 Version classique sclic (module) 1.6.1.2 Programme des tests du module ajouter_sclic 1.6.1.3 Les lignes qui méritent notre attention 1.6.1.4 Tests de la commande ajouter_sclic 1.6.1.4.1 Fichiers obtenus avec la commande ~/Annexer/ajouter_sclic LivreTest 1.6.1.5 Version personnalisée par article sclip (module) 1.6.1.6 Entête ajouter_sclip 1.6.1.7 Module sclipco.inc 1.6.1.8 Modude sclipwb.inc 1.6.2 Comparaison des annexes obtenues pour la page LivreTest 1.6.2.1 Annexe classique avec sclic 1.6.2.2 Annexe personnalisée avec le téléchargement sur le serveur Commons 1.6.2.3 Annexe personnalisée avec le téléchargement sur le serveur Wikilivres 1.6.2.4 Comparaison avec l'annexe manuelle ou semi-manuelle 2 Tests unitaires et d'intégration 3 Copier et installer les fichiers de l'application et des tests 4 Post-référencer post-indexer un wikilivre 5 Post indexer avec Open Office (OO) ou LibreOffice 5.1 Survol rapide de post indexation avec le LivreTest 5.1.1 Préparation du document avec OO 5.1.2 Copier le document dans OO 5.1.2.1 Créer l'« Index lexical » 5.1.2.2 Créer la « Table des matières » 6 Indexer un wikilivre 6.1 Préparer le « Modèle de livre » pour OO 6.2 Recopier le contenu WikiMedia (textes et images) dans OO 6.3 Corriger et compléter les pages 6.4 Documentation générale 6.5 Conseils pour les cadres et les formules mathématiques dans OO 6.6 Imprimer 7 Alternative à l'indexation avec OpenOffice ou LibreOffice 8 Références 9 Index des sections {{Nouvelle page imprimée}} {{AutoCat}} [[Catégorie:Shellscript]] h5fn6q4aimq41c8cdlv0pw6cf8sx83w Wikilivres:GUS2Wiki 4 78643 744144 743756 2025-06-05T11:49:09Z Alexis Jazz 81580 Updating gadget usage statistics from [[Special:GadgetUsage]] ([[phab:T121049]]) 744144 wikitext text/x-wiki {{#ifexist:Project:GUS2Wiki/top|{{/top}}|This page provides a historical record of [[Special:GadgetUsage]] through its page history. To get the data in CSV format, see wikitext. To customize this message or add categories, create [[/top]].}} Les données suivantes sont en cache et ont été mises à jour pour la dernière fois le 2025-06-04T07:12:03Z. {{PLURAL:5000|1=Un seul|5000}} résultat{{PLURAL:5000||s}} au maximum {{PLURAL:5000|est|sont}} disponible{{PLURAL:5000||s}} dans le cache. {| class="sortable wikitable" ! Gadget !! data-sort-type="number" | Nombre d’utilisateurs !! data-sort-type="number" | Utilisateurs actifs |- |AncreTitres || 33 || 1 |- |ArchiveLinks || 12 || 1 |- |Barre de luxe || 36 || 2 |- |BoutonsLiens || 42 || 1 |- |CategoryAboveAll || 18 || 0 |- |CategorySeparator || 23 || 1 |- |CoinsArrondis || 100 || 2 |- |CollapseSidebox || 36 || 2 |- |CouleurContributions || 32 || 0 |- |CouleursLiens || 25 || 0 |- |DeluxeAdmin || 5 || 1 |- |DeluxeEdit || 36 || 2 |- |DeluxeHistory || 44 || 2 |- |DeluxeImport || 19 || 1 |- |DeluxeRename || 17 || 2 |- |DeluxeSummary || 35 || 2 |- |DevTools || 17 || 2 |- |DirectPageLink || 25 || 2 |- |Emoticons || 44 || 1 |- |EmoticonsToolbar || 46 || 1 |- |FastRevert || 37 || 2 |- |FixArrayAltLines || 23 || 2 |- |FlecheHaut || 67 || 2 |- |GoogleTrans || 28 || 1 |- |HotCats || 81 || 4 |- |JournalDebug || 22 || 2 |- |JournalEnTable || 2 || 2 |- |LeftPaneSwitch || 5 || 2 |- |ListeABordure || 30 || 2 |- |LiveRC || 30 || 0 |- |LocalLiveClock || 27 || 2 |- |Logo || 41 || 0 |- |MobileView || 17 || 2 |- |NavigAdmin || 38 || 1 |- |OngletEditCount || 45 || 2 |- |OngletEditZeroth || 67 || 3 |- |OngletGoogle || 28 || 2 |- |OngletPurge || 55 || 3 |- |OptimizedSuivi || 18 || 0 |- |Popups || 59 || 1 |- |RenommageCategorie || 6 || 2 |- |RestaurationDeluxe || 12 || 1 |- |RevertDiff || 36 || 5 |- |ScriptAutoVersion || 17 || 2 |- |ScriptSidebox || 32 || 1 |- |ScriptToolbar || 43 || 1 |- |SisterProjects || 16 || 1 |- |SkinPreview || 4 || 2 |- |Smart patrol || 3 || 2 |- |SourceLanguage || 25 || 1 |- |SousPages || 56 || 4 |- |SpaceToolbar || 30 || 1 |- |TableUnicode || 56 || 1 |- |Tableau || 67 || 3 |- |TitreDeluxe || 56 || 2 |- |TitreHierarchique || 17 || 1 |- |UTCLiveClock || 27 || 1 |- |UnicodeEditRendering || 29 || 2 |- |WikEd || 29 || 0 |- |autonum || 1 || 0 |- |massblock || 3 || 1 |- |monBrouillon || 19 || 2 |- |perpagecustomization || 17 || 2 |- |recentchangesbox || 15 || 0 |- |searchFocus || 18 || 0 |- |searchbox || 30 || 3 |} * [[Spécial:GadgetUsage]] * [[m:Meta:GUS2Wiki/Script|GUS2Wiki]] <!-- data in CSV format: AncreTitres,33,1 ArchiveLinks,12,1 Barre de luxe,36,2 BoutonsLiens,42,1 CategoryAboveAll,18,0 CategorySeparator,23,1 CoinsArrondis,100,2 CollapseSidebox,36,2 CouleurContributions,32,0 CouleursLiens,25,0 DeluxeAdmin,5,1 DeluxeEdit,36,2 DeluxeHistory,44,2 DeluxeImport,19,1 DeluxeRename,17,2 DeluxeSummary,35,2 DevTools,17,2 DirectPageLink,25,2 Emoticons,44,1 EmoticonsToolbar,46,1 FastRevert,37,2 FixArrayAltLines,23,2 FlecheHaut,67,2 GoogleTrans,28,1 HotCats,81,4 JournalDebug,22,2 JournalEnTable,2,2 LeftPaneSwitch,5,2 ListeABordure,30,2 LiveRC,30,0 LocalLiveClock,27,2 Logo,41,0 MobileView,17,2 NavigAdmin,38,1 OngletEditCount,45,2 OngletEditZeroth,67,3 OngletGoogle,28,2 OngletPurge,55,3 OptimizedSuivi,18,0 Popups,59,1 RenommageCategorie,6,2 RestaurationDeluxe,12,1 RevertDiff,36,5 ScriptAutoVersion,17,2 ScriptSidebox,32,1 ScriptToolbar,43,1 SisterProjects,16,1 SkinPreview,4,2 Smart patrol,3,2 SourceLanguage,25,1 SousPages,56,4 SpaceToolbar,30,1 TableUnicode,56,1 Tableau,67,3 TitreDeluxe,56,2 TitreHierarchique,17,1 UTCLiveClock,27,1 UnicodeEditRendering,29,2 WikEd,29,0 autonum,1,0 massblock,3,1 monBrouillon,19,2 perpagecustomization,17,2 recentchangesbox,15,0 searchFocus,18,0 searchbox,30,3 --> oi4adikd2ijawx9uw2ien2jxh6riz6h Fonctionnement d'un ordinateur/Les optimisations du chargement des instructions 0 79799 744057 734092 2025-06-03T18:38:47Z Mewtow 31375 /* La file d'instruction et le cache de macro-opération */ 744057 wikitext text/x-wiki Les processeurs modernes disposent de plusieurs unités de calcul, de bancs de registres larges et de tout un tas d'optimisations permettent d’exécuter un grand nombre d'instructions par secondes. Les opérations de calcul, les accès mémoire : tout cela est très rapide. Mais rien de cela ne fonctionnerait si l'unité de chargement ne suivait pas le rythme. En soi, l'unité de chargement est simple : le ''program counter'', les circuits pour l'incrémenter et gérer les branchements, l'unité de prédiction de branchement, et de quoi communiquer avec le cache. On doit aussi ajouter le registre d'instruction. Difficile de trouver de quoi l'optimiser, à part rendre l'unité de prédiction plus efficace. Pourtant, les processeurs incorporent diverses optimisations qui rendent le tout beaucoup plus rapide. La plupart de ces optimisations consistent à ajouter des files d'attente ou des mémoires caches dans le ''front-end'', que ce soit après l'étape de chargement ou de décodage. Les caches en question sont situés en aval du cache d'instruction, ce qui en fait des sortes de cache de niveau 0. Les optimisations incluent le préchargement d'instruction, l'usage de files d'attente pour découpler divers circuits et quelques autres. Voyons lesquelles dans ce chapitre. ==La file d'instruction et le cache de macro-opération== L'unité de chargement contient de nombreux circuits fortement liés entre eux, et on peut découper le tout en plusieurs circuits. L'unité de calcul d'adresse émet les adresses des instructions à charger, qui sont consommées par le cache d'instruction, qui lui-même envoie les instructions lues dans le registre d'instruction ou la file d'instructions. L'unité de calcul d'adresse regroupe : l'unité de prédiction de branchement, le ''program counter'', le circuit pour incrémenter le ''program counter'', les MUX associés pour gérer les branchements. Le couplage de ces structures fait qu'au moindre défaut de cache d'instruction, l'ensemble stoppe. Par exemple, l'unité de chargement stoppe en cas de défaut de cache. Même chose si jamais une instruction multicycle s’exécute dans le pipeline et bloque toutes les étapes précédentes. Pourtant, il est en théorie possible, et même utile, que certaines structures prennent de l'avance même si d'autres sont bloquées. Par exemple, si le pipeline est bloqué en aval de l'unité de chargement, l'unité de chargement peut en théorie précharger à l'avance des instructions. Ou encore, en cas de défaut de cache d'instruction, l'unité de calcul d'adresse peut précalculer les adresses destinées au cache et les mettre en attente. Pour cela, l'unité de chargement incorpore un paquet de mémoires FIFOs, que nous voir en détail dans ce qui suit. ===Les files d'instruction=== Les processeurs modernes intègrent une '''file d'instruction''', une mémoire FIFO, placée entre le cache d'instruction et le décodeur d'instruction. Les instructions chargées par l'étape de chargement soient accumulées dans la '''file d'instructions''' et sont décodées quand l'unité de décodage est prête. La file d'attente permet de précharger des instructions dans la file d’instructions à l'avance, permettant ainsi de masquer certains accès au cache ou à la mémoire assez longs. L'idée est que les instructions s'accumulent dans la file d'instruction si le processeur exécute les instructions moins vite qu'il ne les charge. C'est généralement signe qu'il effectue une instruction multicycle et/ou qu'il effectue un accès à la mémoire. À l'inverse, la file d'attente se vide quand le processeur éxecute les instructions plus vite qu'il n'en charge. C'est généralement signe qu'un défaut de cache d'instruction est en cours. La présence d'une file d'attente fait que la première situation est compensée lors de la seconde. Les temps d'attentes liées aux instructions multicycles permettent de remplir la file d'attente, qui est ensuite vidée en cas de défaut de cache. Le processeur exécute en permanence des instructions, sans interruption. Alors que sans file d'attente, les défauts de cache entraineront des temps d'attente où le processeur s’exécuterait rien. La seule limite de cette optimisation est l'influence des branchements. Lorsqu'un branchement est décodé, ce tampon d’instructions est totalement vidé de son contenu. Ce n'est ni plus ni moins ce que faisait la ''prefetch input queue'' des anciens processeurs Intel, dont nous avions parlé dans le chapitre sur l'unité de chargement et le séquenceur. ===La macro-fusion=== La présence d'une file d'instruction et/ou d'une ''Prefetch Input Queue'' permet d'ajouter une optimisation très importante au processeur, qui ne seraient pas possibles sans elle. L'une d'entre elle est la '''macro-fusion''', une technique qui permet de fusionner une suite d'instructions consécutives en une seule micro-opération. Par exemple, il est possible de fusionner une multiplication suivie d'une addition en une seule instruction MAD (''multiply and add''), si les conditions adéquates sont réunies pour les opérandes. Comme autre exemple, il est possible de fusionner un calcul d'adresse suivi d'une lecture à l'adresse calculée en une seule micro-opération d'accès mémoire. Et enfin, il est possible de fusionner une instruction de test et une instruction de branchement en une seule micro-opération de comparaison-branchement. C'est surtout cette dernière qui est utilisée sur les processeurs Intel modernes. La macro-fusion est effectuée pendant le décodage, en décodant des instructions dans le tampon d'instruction. Le décodeur reconnait que plusieurs instructions dans le tampon d'instruction peuvent être fusionnées et fournit en sortie la micro-opération équivalent. L'avantage de cette technique est que le chemin de données est utilisé plus efficacement. Notons que la macro-fusion diminue le nombre d'instructions à stocker dans le ROB et dans les différentes mémoires intégrées aux processeur, qui stocke les micro-opérations. La technique est parfois couplée à un circuit de prédiction, qui détermine si une série d'instruction à fusionner va apparaitre sous peu. L'idée est que dans certains cas, le tampon d'instruction contient le début d'une suite d'instruction combinables. Suivant ce qui sera chargé après, la macro-fusion pourra se faire, ou non. Mais le processeur ne sait pas exactement quelles seront les instructions chargées juste après et il ne sait pas si la macro-fusion aura lieu. Dans ce cas, il peut utiliser un circuit de prédiction de macro-fusion, qui essaye de prédire si les instructions chargées sous peu autoriseront une macro-fusion ou non. Si c'est le cas, les instructions potentiellement fusionnables, le début de la série macro-fusionnable, est mise en attente dans le tampon d'instruction, en attendant les futures instructions. ===Le cache de macro-opérations=== Le cache de macro-opérations est un cache présent en aval de l'unité de chargement, à côté de la file d’instruction. Il mémorise les dernières instructions envoyées à l'unité de décodage, à savoir non pas les instructions préchargées, mais celles qui sont en cours de décodage ou d’exécution, celles qui ont quitté la file d'instruction. Il sert dans le cas où ces instructions sont ré-éxecutées, ce qui est souvent le cas avec des boucles de petite taille. A chaque cycle d'horloge, ce cache est consulté, de manière à vérifier si l'instruction voulue est dans ce cache ou non. Cela évite un accès au cache d'instruction. Son implémentation est simple : il s'agit d'un petit cache adressé par le ''program counter''. Si l'instruction a été chargée il y a peu, l'instruction machine est mémorisée dans une ligne de cache, le tag de cette ligne n'est autre que son adresse, le ''program counter'' associé. L'accès au cache de macro-opérations est de un seul cycle, pas plus. [[File:Cache de macro-ops.png|centre|vignette|upright=2|Cache de macro-ops]] L'intérêt n'est pas évident, mais disons que l'accès à ce cache gaspille moins d'énergie qu’accéder au cache d'instruction. C'est là l'intérêt principal, même s'il se peut qu'on puisse avoir un gain en performance. Le gain en question vient du fait que l'accès est plus rapide dans ce cache, ce qui n'est le cas que dans des conditions précise : si le cache d'instruction est pipeliné et a un temps d'accès de plusieurs cycles. ==La file de micro-opérations et le cache de micro-opérations== [[File:File d'instruction.png|vignette|upright=1|File d'instruction]] Sur les processeurs modernes, la sortie du décodeur est reliée à une mémoire FIFO semblable à la file d'instruction, mais placée juste après le décodeur. Elle mémorise les micro-opérations émises par le décodeur et les met en attente tant que le reste du pipeline n'est pas prêt. Nous l’appellerons la '''file de micro-opérations''', par simplicité. Le schéma ci-contre indique que la file de micro-opérations est située en sortie de l’unité de décodage, avant l'unité d'émission et avant l'unité de renommage de registres (que nous aborderons dans quelques chapitres). La file de micro-opérations permet aux décodeurs de faire leur travail même si le reste du pipeline n'est pas prêt. Par exemple, imaginons que le processeur ne peut pas émettre de nouvelle instruction, soit car toutes les ALUs sont occupées, soit car il y a un accès mémoire qui bloque le pipeline, peu importe. Sans file de micro-opérations, tout ce qui précède l'unité d'émission devrait être totalement bloqué tant que l'instruction ne peut pas être émise. Mais avec une file de micro-opérations, le pipeline peut continuer à charger et décoder des instructions, et accumuler des instructions décodées dans la file de micro-opérations. En clair, la file de micro-opérations met en attente les instructions quand des bulles de pipeline sont émises. Et à l'inverse, elle permet d'émettre des instructions quand les unités de décodage/chargement sont bloquées. Le cas classique est celui d'un défaut de cache dans le cache d'instruction. Des instructions ne peuvent plus être chargée et décodées durant quelques cycles. Sans file de micro-opérations, le processeur ne peut plus rien faire durant quelques cycles. Mais avec une file de micro-opérations, il peut en profiter pour émettre les instructions en attente dans la file de micro-opérations. En clair, si l'unité d'émission a mis en attente des instructions, le processeur se rattrape au prochain défaut de cache d'instruction. Une autre situation où le décodeur bloque est le cas où certaines instructions mettent du temps à être décodées. C'est notamment le cas de certaines instructions complexes, dont le décodage prend facilement 2 à 3 cycles d'horloge, voire plus. Le pire est le décodage des instructions microcodées, qui peut demander plusieurs cycles. Or, le pipeline demande qu'on décode une instruction par cycle pour éviter de bloquer le pipeline. Mais ce temps de décodage peut être masqué si des micro-opérations sont en attente dans la file, elles sont exécutées pendant le décodage long. La file de micro-opération est souvent complétée par plusieurs circuits, dont un circuit de micro-fusion, un cache de micro-opérations et le ''loop stream detector''. Voyons ces circuits dans ce qui suit. [[File:File de micro-opérations et cache de micro-ops - Copie.png|centre|vignette|upright=2.5|File de micro-opérations et cache de micro-ops - Copie]] ===La micro-fusion=== La présence d'une file de micro-opération permet d'effectuer une optimisation appelée la '''micro-fusion'''. Elle remplace deux micro-opérations simples consécutives en une seule micro-opération complexe équivalente. Par exemple, sur certains processeurs, le chemin de données est capable d'effectuer une lecture/écriture en adressage base+index en une seule micro-opération. Mais le jeu d'instruction est une architecture Load-store où le calcul d'adresse et l'accès mémoire se font en deux instructions séparées. Dans ce cas, la micro-fusion peut faire son travail et fusionner le calcul d'adresse avec l'accès mémoire. C'est une optimisation compatible avec la macro-fusion, les deux se ressemblant beaucoup. On peut se demander pourquoi les deux existent ensemble. La raison est historique, et tient au design des processeurs x86. Les premiers processeurs x86 avaient un chemin de données simple, avec les décodeurs qui allaient avec. Sur de tels processeurs, le calcul d'adresse et l'accès mémoire étaient séparés en deux instructions. Puis, avec l'évolution de la technologie, le chemin de données est devenu capable de faire les deux en une seule micro-opération. Pour compenser cela, Intel et AMD auraient pu changer leurs décodeurs en profondeur. A la place, ils ont préféré utiliser la technique de la micro-fusion, par simplicité. ===Le ''Loop Stream Detector''=== Les boucles sont une opportunité d'optimisation très intéressante sur les CPU avec une file de micro-opérations. L'idée est que lors d'une boucle, des instructions sont chargées, décodées et exécutées plusieurs fois de suite. Mais à, chaque répétition d'une instruction, le chargement et le décodage donnent toujours le même résultat, seule l'exécution n'est pas la même (les registres renommés sont aussi différents, mais passons). L'idée est simplement de mémoriser les N dernières instructions décodées et de les ré-exécuter si besoin. Ainsi, on évite de charger/décoder une même instruction machine plusieurs fois, mais de réutiliser les micro-opérations déjà décodées. L'implémentation la plus simple conserve les N dernières instructions décodées dans la file d'instruction, qui se comporte alors comme une sorte de pseudo-cache FIFO. Un circuit annexe, appelé le ''Loop Stream Detector'' (LSD), détecte lesboucles dans la file de micro-opérations et optimise leur exécution. Avec un LSD, la file d'instruction ne supprime pas les micro-opérations une fois qu'elles sont émises. Elle mémorise là où se trouve la dernière micro-opération émise, mais conserve celles qui ont déjà été émises. Si une boucle adéquate est détectée par le ''Loop Stream Detector'', les micro-opérations de la boucle sont lues dans la file de micro-opération et sont injectées directement dans la suite du pipeline. De plus, les unités de chargement et de décodage sont désactivées pendant l’exécution de la boucle, ce qui réduit la consommation d'énergie du CPU. L'optimisation accélère les petites boucles, à condition qu'elles s'exécutent de la même manière à chaque exécution. De telles boucles exécutent une suite de N instructions, qui reste identique à chaque itération de la boucle. Le cas le plus simple est celui d'une boucle dans laquelle il n'y a pas de branchements. Pour les boucles normales, le processeur reprend une exécution normale quand on quitte la boucle ou quand son exécution change, par exemple quand un if...else, un return ou tout autre changement de flot de contrôle a lieu. Vu que toutes ces situations impliquent un branchement qui n'a pas été pris comme avant, le processeur n'utilise plus le ''Loop Stream Detector'' en cas de mauvaise prédiction de branchement. L'optimisation vise surtout à désactiver les décodeurs et l'unité de chargement lors de l'exécution d'une boucle. La désactivation peut être du ''clock gating'', voire du ''power gating'', être partielle ou totale. Dans le pire des cas, les unités de chargement peuvent continuer à charger des instructions en avance dans une file d'instruction, mais les décodeurs peuvent être désactivés. Dans le meilleur des cas, la totalité de ce qui précède la file de micro-opération est désactivé tant que la boucle s’exécute normalement. Y compris le cache de micro-opération. [[File:Loop Stream Detector.png|centre|vignette|upright=2|Loop Stream Detector]] Les CPU Intel modernes disposent d'un ''loop stream detector'', les CPU AMD en avaient sur les microarchitectures Zen 4 mais il a disparu sur la microarchitecture Zen 5. Quelques CPU ARM avaient aussi un ''loop stream detector'', notamment le Cortex A15. Évidemment, la taille des boucles optimisées ainsi est limitée par la taille de la file de micro-opération, ce qui fait que l'optimisation ne fonctionne que pour des boucles de petite taille. De plus, toute la file de micro-opération n'est pas gérée par le ''loop stream detector''. Par exemple, les processeurs avec une file de micro-opération de 64 micro-opération peuvent gérer des boucles de maximum 32 à 40 micro-opérations. Pour donner quelques chiffres, les processeurs ARM Cortex A15 géraient des boucles de maximum 32 micro-opérations. Mais les contraintes principales portent sur la détection des boucles. Le ''Loop Stream Detector'' ne peut pas détecter toutes les boucles qui existent, et certaines boucles ne sont pas détectées. Par exemple, le ''Loop Stream Detector' ne peut pas détecter les boucles si un appel de fonction a lieu dans la boucle. Il y a aussi des contraintes quant au nombre de branchements à l'intérieur de la boucle et le nombre d'accès mémoire. Il faut noter que le ''loop stream detector'' a été désactivé par des mises à jour de microcode sur quelques architectures, comme sur la microarchitecture Zen 4 d'AMD ou les CPU de microarchitecture Skylake et Kaby Lake d'Intel. Pour la microarchitecture Skylake , les raisons officielles pour cette désactivation sont un bug lié à l'interaction avec l'''hyperthreading''. Il est vraisemblable que des bugs ou des problèmes de sécurité aient amené à la désactivation sur les autres architectures. ===Le cache de micro-opérations=== Le '''cache de micro-opérations''' a le même but que le ''Loop Stream Detector'', à savoir optimiser l'exécution des boucles. La différence avec le ''Loop Stream Detector'' est qu'il y a un cache séparé de la file de micro-opérations, qui mémorise des micro-opérations décodées, dans le cas où elles soient réutilisées par la suite. La première itération d'une boucle décode les instructions en micro-opérations, qui sont accumulées dans le cache de micro-opérations. Les itérations suivantes de la boucle vont chercher les micro-opérations adéquates dans le cache de micro-opération : on n'a pas à décoder l'instruction une nouvelle fois. Intuitivement, vous vous dites que son implémentation la plus simple mémorise les N dernières micro-opérations exécutées par le processeur, ce qui en fait un cache FIFO. Mais la réalité est que c'est déjà ce qui est fait par le couple LSD + file de micro-opération. Le cache de micro-opérations a une politique de remplacement des lignes de cache plus complexe que le FIFO, typiquement une politique LRU ou LFU approximée. De plus, le cache de micro-opération est séparé de la file de micro-opération. Et il est alimenté non pas par l'unité de décodage, mais par la file de micro-opérations. Ce sont les micro-opérations qui quittent la file de micro-opérations qui sont insérées dans le cache, pas celles qui quittent directement le décodeur. Les avantages sont les mêmes qu'avec un ''Loop Stream Detector'' : une consommation énergétique réduite, des performances légèrement améliorées. Le décodeur et l'unité de chargement sont inutiles en cas de succès dans le cache de micro-opération, ce qui fait qu'ils sont désactivés, éteints, ou du moins subissent un ''clock-gating'' temporaire. Ils ne consomment pas d'énergie, seul le cache de micro-opération utilise de l'électricité. L'avantage en termes de performance est plus faible, assez variable suivant la situation, mais aussi bien le cache de micro-opérations que le LSD ne font pas de mal. La différence avec le cache de micro-opération est que la boucle doit s’exécuter à l'identique avec un ''Loop Stream Detector'', pas avec un cache de micro-opérations. Prenons l'exemple d'une boucle contenant quelques instructions suivies par un IF...ELSE. Il arrive qu'une itération de la boucle exécute le IF, alors que d'autres exécutent le ELSE. Dans ce cas, le ''Loop Stream Detector'' ne sera pas activé, car la boucle ne s’exécute pas pareil d'une itération à l'autre. Par contre, avec un cache de macro/micro-opération, on pourra lire les instructions précédant le IF...ELSE dedans. Le cache de micro-opération est donc plus efficace que le ''Loop Stream Detector'', mais pour un cout en transistor plus élevé. Le cache de micro-opérations et le ''Loop Stream Detector'' font la même chose, mais certains processeurs implémentaient les deux. L'avantage est que le cache de micro-opération peut être désactivé si jamais le LSD détecte une boucle dans la file d'instruction, ce qui réduit encore plus la consommation énergétique. En pratique, l'impact sur la consommation énergétique est très difficile à mesurer, mais il rajoute de la complexité pour la conception du processeur. [[File:File de micro-opérations et cache de micro-ops.png|centre|vignette|upright=2|File de micro-opérations et cache de micro-ops]] Le cache de micro-opération associe, pour chaque instruction machine, une ou plusieurs micro-opérations. Avec l'implémentation la plus simple, une ligne de cache est associée à une instruction machine. Par exemple, sur les processeurs Intel de microarchitecture Skylake, chaque ligne de cache était associée à une instruction machine et pouvait contenir de 1 à 6 micro-opérations. La suite de micro-opérations correspondant à une instruction devait tenir toute entière dans une ligne de cache, ce qui fait que les instructions décodées en plus de 6 micro-opérations ne pouvaient pas rentrer dans ce cache. L'accès au cache de micro-opération se fait lors de l'étape de chargement. Le cache de micro-opérations est adressé en envoyant le ''program counter'' sur son entrée d'adresse, en parallèle du cache d'instruction. Le cache de micro-opération est une voie de chargement parallèle au ''front-end'' proprement dit. En clair, il y a une voie qui regroupe cache d'instruction, file d'instruction et décodeur, et une seconde voie qui se résume au cache de micro-opération. Les deux voies sont accédées en parallèle. En cas de succès dans le cache de micro-opération, les micro-opérations adéquates sont lues directement depuis le cache de micro-opération. Il existe deux méthodes différentes pour encoder les micro-opérations dans le cache de micro-opérations. La première est la plus intuitive : on mémorise les micro-opérations dans la ligne de cache, directement. Elle est utilisée sur les processeurs AMD, et sans doute sur les processeurs Intel récents. Mais les anciens processeurs Intel, comme ceux des architectures Sandy Bridge et Netburst, utilisent une autre méthode. Une ligne de cache mémorise non pas les micro-opération directement, mais un pointeur vers le ''control store'', qui indique à quelle adresse dans le micro-code se situe la micro-opération. La micro-opération est donc lue depuis le micro-code lors de l'émission. Il faut noter que pour des raisons de performance, le cache de micro-opérations est virtuellement tagué, ce qui fait qu'il est invalidé en cas de changement de programme. Sur l'architecture Sandy Bridge, il est carrément inclus dans le cache L1, les deux sont des caches inclusifs l'un avec l'autre. Les premières implémentations étaient très limitées. Les micro-opérations devaient être séquentielles dans le code, le cache était consulté seulement après un branchement et non à chaque émission d'instruction, pour limiter la consommation d'énergie an détriment des performances. Ces limitations ne sont pas présentes sur les architectures récentes. Aussi bien le cache de macro-opérations que le cache de micro-opérations optimisent l'exécution des boucles, mais ils ne sont pas au même endroit dans le pipeline : avant et après l'unité de décodage. Et le premier mémorise des instructions machines, l'autre des micro-opérations décodées. Les avantages et inconvénients sont totalement différents. Niveau capacité des deux caches, l'encodage des instructions machines est plus compact que la ou les micro-instructions équivalente, ce qui est un avantage pour le cache de macro-opérations à capacité équivalente. Par contre, le cache de micro-opérations permet de désactiver les décodeurs en cas de succès de cache, vu que les instructions ne doivent plus être décodées et renommées. Le gain est d'autant plus important si les instructions ont un encodage complexe, ou si les instructions sont à longueur variable, ce qui rend leur décodage complexe et donc lent. Globalement, plus le décodage est complexe et/ou long, plus le cache de micro-opérations fait des merveilles. ==Le préchargement d'instructions et la ''Fetch Target Queue''== Les processeurs modernes incorporent une optimisation assez intéressante : ils découplent l'unité de prédiction de branchement et le ''program counter'' de l'accès au cache d'instruction. Pour cela, ils incorporent une mémoire FIFO entre l'unité de prédiction de branchement et le cache d'instruction. Les premiers articles scientifiques, qui ont proposé cette solution, l'ont appelée la '''''Fetch Target Queue''''', abréviée FTQ. Elle accumule les adresses à lire/écrire dans le cache d'instruction, peu importe que ces adresses viennent du ''program counter'' ou de l'unité de prédiction de branchement. [[File:Fetch target queue.png|centre|vignette|upright=2.5|Fetch target queue]] Elle se remplit quand le cache d'instruction est bloqué, soit à cause d'un défaut de cache, soit à cause d'un pipeline bloqué en amont de l'unité de chargement. Par exemple, si le cache d'instruction est bloqué par un défaut de cache, l'unité de prédiction de branchement peut accumuler des prédictions à l'avance dans la FTQ, qui sont ensuite consommées par le cache d'instruction une fois qu'il est redevenu disponible. De même, si l'unité de prédiction de branchement est bloquée par un évènement quelconque, le cache d'instruction peut consommer les prédictions faites à l'avance. Une utilisation assez originale de la FTQ s'est vu sur les processeurs AMD d'architectures bulldozer. Sur cette architecture, les cœurs étaient regroupés par paquets de deux, et les deux cœurs partageaient certains circuits. Notamment, l'unité de prédiction de branchement était partagée entre les deux cœurs ! Pourtant, chaque cœur disposait de sa propre FTQ ! Un avantage de la FTQ tient dans le fait que les caches d'instructions sont pipelinés, sur le même modèle que les processeurs. On peut leur envoyer une demande de lecture/écriture par cycle, alors que chaque lecture/écriture prendra plusieurs cycles à s'effectuer. L'accès au cache d'instruction a donc une certaine latence, qui est partiellement masquée par la FTQ au point où elle ne s'exprime qu'en cas de défaut de cache assez important. Par exemple, si l'accès au cache d'instruction prend 4 cycles, une FTQ qui met en attente 4 adresses camouflera le temps d'accès au cache, tant qu'il n'y a pas de mauvaise prédiction de branchement. La FTQ est aussi très utile avec les unités de branchement modernes, qui peuvent mettre plusieurs cycles pour fournir une prédiction. Prendre de l'avance avec une FTQ amorti partiellement le temps de calcul des prédictions. : Si le cache d'instruction est multiport et accepte plusieurs accès simultanés, il peut consommer plusieurs entrées dans la FTQ à la fois. Mais l'avantage principal de la FTQ est qu'elle permet l'implémentation d'une optimisation très importante. Il y a quelques chapitres, nous avions parlé des techniques de '''préchargement d'instruction''', qui permettent de charger à l'avance des instructions dans le cache d'instruction. Nous avions volontairement laissé de côté le préchargement des instructions, pour tout un tas de raisons. Et la raison est justement que la prédiction de branchement et le préchargement des instructions sont fortement liés sur les processeurs modernes. Il est maintenant possible d'aborder le préchargement pour les instructions, d’où cette section. Notons que par préchargement des instructions, on peut parler de deux formes de préchargement, fortement différentes. La première correspond au préchargement normal, à savoir le préchargement des instructions dans le cache d'instruction L1, à partir du cache L2. Il s'agit donc d'un préchargement dans le cache d'instruction. Mais il existe aussi une autre forme de préchargement, qui consiste à précharger à l'avance des instructions dans la file d'instruction et qui a été abordée dans la section sur la ''prefetch input queue''. Les deux formes de préchargement n'ont pas lieu au même endroit dans la hiérarchie mémoire : l'une précharge du cache L2 vers le L1i, l'autre du cache L1i vers la file d'instruction (ou dans le cache de macro-opération). Mais les algorithmes utilisés pour sont sensiblement les mêmes. Aussi, nous allons les voir en même temps. Pour faire la distinction, nous parlerons de préchargement L2-L1i pour la première, de préchargement interne pour l'autre. ===Les algorithmes de préchargement d'instructions=== Les techniques basiques de préchargement consistent à charger des instructions qui suivent la dernière ligne de cache accédée. Quand on charge des instructions dans le cache d’instruction, les instructions qui suivent sont chargées automatiquement, ligne de cache par ligne de cache. il s'agit due préchargement séquentiel, la technique la plus simple de préchargement, qui profite de la localité spatiale. Elle est utilisée pour précharger des instructions du cache L2 vers le cache L1i, mais aussi pour le préchargement interne dans la file d'instructions. [[File:Branchements et préchargement séquentiel.png|centre|vignette|upright=2|Branchements et préchargement séquentiel.]] Mais un ''prefetcher'' purement séquentiel gère mal les branchements. Si un branchement est pris, les instructions de destination ne sont pas chargées, si elles ne sont pas dans la ligne de cache suivante. Pour le préchargement L2-L1i, cela ne pose pas de problèmes majeurs, au-delà de la pollution du cache L1i par des instructions inutiles. Mais pour le préchargement interne, c'est autre chose. Les instructions préchargées par erreurs doivent être supprimées pour éviter qu'elles soient décodées et exécutées, ce qui fait que la file d’instruction doit être invalidée. Il existe des techniques de préchargement plus élaborées qui marchent mieux en présence de branchements. Elles utilisent toutes une collaboration de l'unité de prédiction de branchement. Elles accèdent au ''Branch Target Buffer'', pour détecter les branchements, leur destination, etc. Le tout peut se coupler à la technique du prédécodage. Avec cette dernière, le prédécodage décode en partie les instructions lors de leur chargement dans le cache, et détecte les branchements et leur adresse de destination à ce moment-là. Ces informations sont alors mémorisées dans une table à part, ou dans le BTB. Mais la plupart des designs utilisent le BTB, par souci de simplicité. Il existe globalement deux à trois techniques principales, que nous allons voir dans ce qui suit. La première technique prédit si le branchement est pris ou non, et agit différemment si le branchement est pris ou non. Si le branchement est pris, elle précharge les instructions à partir de l'adresse de destination des branchements pris. Sinon, elle précharge les instructions suivantes avec préchargement séquentiel. Il s'agit du '''''target line prefetching''''' [[File:Target line prefetching.png|centre|vignette|upright=2|Target line prefetching.]] Une autre technique ne prédit pas les branchements et précharge à la fois les instructions suivantes avec le ''next-line prefetching'', et la ligne de cache de destination du branchement avec le ''target line prefetching''. Comme ça, peu importe que le branchement soit pris ou non, les instructions adéquates seront préchargées quand même. On appelle cette technique le '''préchargement du mauvais chemin''' (''wrong path prefetching''). [[File:Préchargement du mauvais chemin.png|centre|vignette|upright=2|Préchargement du mauvais chemin.]] Le ''target line prefetching'' est plus complexe à implémenter, car il demande de prédire les branchements. Mais elle a l'avantage de ne pas précharger inutilement deux lignes de cache par branchement, seulement une seule. Par contre, le préchargement est inutile en cas de mauvaise prédiction de branchement : non seulement on a préchargé une ligne de cache inutilement, mais en plus, la ligne de cache adéquate n'a pas été chargée. On n'a pas ce problème avec le préchargement du mauvais chemin, qui garantit que la ligne de cache adéquate est toujours préchargée. ===L'implémentation du préchargement interne, dans la file d'instruction=== Le préchargement dans la file d'instruction est généralement de type séquentiel, mais certains processeurs font autrement. Déjà, il faut remarquer que le ''target line prefetching'' correspond en réalité à la prédiction de branchement classique. L'adresse de destination est prédite, et on charge les instructions adéquates dans la file d'instruction. La prédiction de branchement, associée à une file d'instruction, est donc une forme de préchargement. Il fallait y penser. Enfin, des processeurs assez rares utilisaient le préchargement du mauvais chemin. Le préchargement du mauvais chemin demande d'utiliser deux files d'instructions séparées. L'une dans laquelle on précharge de manière séquentielle, l'autre dans laquelle on utilise la prédiction de branchement pour faire du ''target line prefetching''. Une fois que l'on sait si la prédiction de branchement était correcte, on est certain qu'une des deux files contiendra les instructions valides. Le contenu de la file adéquate est conservé, alors que l'autre est intégralement invalidée. Le choix de la bonne file se fait avec un multiplexeur. C'est approximativement la technique qui était implémentée sur le processeur de mainframe IBM 370/165, par exemple, et sur quelques modèles IBM similaires. Le problème est que cette méthode demande de charger deux instructions à chaque cycle. Cela demande donc d'utiliser un cache d'instruction multiport, avec un port par file d'instruction. Le cout en circuit d'un cache double port n'est pas négligeable. Et le gain en performance est assez faible. Le préchargement dans la file d’instruction permet d'économiser quelques cycles lors de l'accès au cache d'instruction, guère plus. Le gain est maximal lorsque les instructions préchargées ont généré un défaut de cache, qui a rapatrié les instructions adéquates pendant que le processeur exécutait les mauvaises instructions, avant que la mauvaise prédiction de branchement soit détectée. Dans ce cas, le défaut de cache a eu lieu pendant la mauvaise prédiction et sa réparation, et non après. ====La gestion des branchements successifs==== Un autre défaut de cette méthode est la présence de branchements successifs. Par exemple, si jamais on rencontre un branchement, le flux d'instructions se scinde en deux : un où le branchement est pris, un autre où il ne l'est pas. Chacun de ces flux peut lui-même contenir un branchement, et se scinder lui aussi. Et ainsi de suite. Et le processeur doit gérer cette situation en termes de préchargement. [[File:Exécution stricte 04.png|centre|vignette|upright=2|Exécution stricte]] Plusieurs solutions existent. La méthode la plus simple stoppe le chargement du flux en attendant que le premier branchement soit terminé. Cette solution est intuitive, mais est celle où on a les gains en performance les plus faibles. Elle est couramment implémentée d'une manière assez particulière, qui ne correspond pas tout à fait à un stop du chargement, mais qui utilise les lignes de cache. L'unité de préchargement est conçue pour copier des lignes de cache entières dans la file d'instruction. Le processeur (pré-)charge deux lignes de cache : celle du bon chemin, celle du mauvais chemin. Il les précharge dans deux files d'instructions, qui contiennent généralement une ligne de cache grand maximum. Le temps que l'on ait chargé les deux files d'instruction, le résultat du branchement est connu et on sait laquelle est la bonne. L'autre possibilité est d'utiliser la prédiction de branchement pour ce flux, afin de poursuivre le chargement de manière spéculative. Elle donne de bonnes performances, mais demande des unités de prédiction de branchement spéciales, dans le cas où les deux flux tombent sur un branchement en même temps. Cette technique est indirectement liée au cache de traces que nous verrons dans le chapitre sur les processeurs superscalaires. Nous n'en parlons pas ici, car ce genre de techniques est plus liée aux processeurs superscalaires qu'un processeur avec un pipeline normal. Une autre possibilité consiste à scinder ce flux en deux et charger les deux sous-flux. Cette dernière est impraticable car elle demande des caches avec un grand nombre de ports et la présence de plusieurs files d'instructions, qui sont utilisées assez rarement. [[File:Exécution stricte 01.png|centre|vignette|upright=2|Exécution stricte, seconde.]] ====Les processeurs à exécution de chemins multiples==== L'idée précédente peut en théorie être améliorée, afin de non seulement charger les instructions en provenance des deux chemins (celui du branchement pris, et celui du branchement non pris), mais aussi de les exécuter : c'est ce qu'on appelle l''''exécution stricte''' (''eager execution''). Bien sûr, on n’est pas limité à un seul branchement, mais on peut poursuivre un peu plus loin. Quelques papiers de recherche ont étudié l'idée, mais ses défauts font qu'elle n'a jamais été utilisée dans un processeur en dehors de prototypes destinés à la recherche. Le gros problème de l'exécution stricte est qu'on est limité par le nombre d'unités de calculs, de registres, etc. Autant ce serait une technique idéale sur des processeurs avec un nombre illimité de registres ou d'unités de calcul, autant ce n'est pas le cas dans le monde réel. Au bout d'un certain nombre d’embranchements, le processeur finit par ne plus pouvoir poursuivre l’exécution, par manque de ressources matérielles et doit soit stopper, soit recourir à la prédiction de branchement. Il y a le même problème avec le préchargement interne simple, quand on utilise le préchargement du mauvais chemin, comme vu juste au-dessus. ===L'implémentation matérielle du préchargement de cache L2-L1i=== Pour comprendre comment s'effectue le préchargement L2-L1i, il faut regarder comment l'unité de chargement communique avec les caches. L'unité de prédiction de branchement est généralement regroupée avec le ''program counter'' et les circuits associés (les incrémenteurs/MUX associés), pour former l'unité de chargement proprement dite. L'unité de chargement émet des adresses consommées par le cache d'instruction, qui lui-même envoie les instructions lues dans le registre d'instruction ou la file d'instructions. Le couplage de ces structures fait qu'au moindre défaut de cache d'instruction, l'ensemble stoppe. Et notamment, l'unité de prédiction de branchement stoppe en cas de défaut de cache. Même chose si jamais une instruction multicycle s’exécute dans le pipeline et bloque toutes les étapes précédentes. Les pertes de performance ne sont pas très importantes, mais elles existent. Et le préchargement se manifeste dans ces situations. Le préchargement d'instructions consiste à découpler ces structures de manière à ce qu'elles fonctionnent plus ou moins indépendamment. Le but est qu'en plus des accès normaux au cache d'instruction, l'unité de chargement envoie des informations au cache L2 ou L1i en avance, pour effectuer le préchargement. L'unité de chargement doit alors prendre de l'avance sur le cache, pour effectuer les accès au cache L2 en avance, tout en maintenant l'état normal pour effectuer les accès normaux. C'est donc plus ou moins l'unité de chargement qui s'occupe du préchargement, ou du moins les deux sont très liées. ====L'anticipation du ''program counter''==== Avec la solution la plus simple, on a une unité de chargement qui s'occupe des accès au cache d'instruction, et une unité de préchargement qui prend de l'avance sur l'unité de chargement, et communique avec le cache L2. La technique la plus basique se base sur un ''Lookahead program counter'', un second ''program counter'' qui ne fonctionne que lors d'un défaut de cache d'instruction. Il est initialisé avec le ''program counter'' lors d'un défaut de cache, puis il est incrémenté à chaque cycle et les branchements sont prédits, ce qui fait qu'il est mis à jour comme si l’exécution du programme se poursuivait, alors que le reste du processeur est mis en attente. La technique initiale utilisait ce second ''program counter'' pour accéder à une table de prédiction, qui associe à chaque valeur du ''program counter'', l'adresse des données chargées par l'instruction associée. Les adresses fournies à chaque cycle par cette table sont alors envoyées aux unités de préchargement pour qu'elles fassent leur travail. La technique permettait donc de précharger des données en cas de défaut de cache, mais pas d'instructions. Il ne s'agissait pas d'une technique de préchargement des instructions, mais de préchargement de données. La technique a ensuite été adaptée pour le chargement des instructions par Chen, Lee et Mudge. Leur idée utilisait deux unités de prédiction de branchements : une couplée à l'unité de chargement, l'autre pour le préchargement. La première utilisait le ''program counter'' normal, l'autre se déclenchait en cas de défaut de cache et utilisait un ''lookahead program counter''. Les adresses générées par le ''lookahead program counter'' étaient envoyée au cache d'instruction, sur un port de lecture séparé. La ligne de cache lue était alors prédécodée pour détecter les branchements, qui étaient prédits, et rebelote. Il est possible d'adapter la méthode pour que les adresses soient accumulées dans une mémoire FIFO, et étaient consommée par le cache d'instruction L2 pour le préchargement si la ligne de cache associée n'était pas dans le cache d’instruction. Les techniques modernes n'utilisent plus de seconde unité de prédiction de branchement, mais conservent un ''lookahead program counter''. Par contre, le BTB dispose de plusieurs ports : un pour la prédiction de branchement normale, l'autre pour le préchargement. L'unité de préchargement et l'unité de chargement accèdent toutes deux au BTB quand elles ont besoin de faire leurs prédictions, en parallèle. Typiquement, le BTB est accédé à chaque cycle pour la prédiction de branchement, à un rythme plus faible pour le préchargement. ====Le ''Fetch Directed Instruction Prefetching''==== Les processeurs modernes semblent utiliser un algorithme connu sous le nom de '''''Fetch Directed Instruction Prefetching'''''. Il utilise les adresses contenues dans la FTQ pour précharger les instructions adéquates du cache L2 vers le cache L1 d'instruction (L1i). L'unité de préchargement est placée en aval de la FTQ, elle lit son contenu, détecte quelles adresses correspondent à des lignes de cache à précharger, et envoie celles-ci au cache L2. Le préchargement du L2 vers le L1i a lieu quand le cache L2 est inutilisé, ou du moins quand il peut accepter une nouvelle lecture (dans le cas d'un cache multiport et/ou pipeliné). [[File:Fetch directed instruction prefetching.png|centre|vignette|upright=2.5|Fetch directed instruction prefetching]] On peut améliorer légèrement le design précédent sur plusieurs points. Pour éviter de polluer le cache L1 avec des lignes de caches préchargées à tort, il est possible d'ajouter un équivalent des ''stream buffer'' vus dans le chapitre sur le préchargement. Il s'agit d'une autre mémoire FIFO qui mémorise les lignes de cache préchargées. Les lignes de cache préchargées ne sont pas placées dans le cache L1i, mais dans cette file d'attente. Lors d'un accès au L1i, la file d'attente est consultée en parallèle. Si l'instruction voulue est dans la file d'attente, elle est lue depuis la file, et la ligne de cache associée est copiée dans le cache L1i. Mais c'est là une possibilité facultative. Un autre point est que l'unité de préchargement doit attendre que le cache L2 puisse accepter une nouvelle lecture pour lancer le préchargement d'une autre ligne de cache. Pour corriger cela, on ajoute une file d'attente entre le cache L2 et l'unité de préchargement, qui est évidemment une mémoire FIFO. Son utilité dépend des temps de lectures du cache L2, ainsi que de la taille de la FTQ. Elle n'est pas toujours nécessaire, certains processeurs ont un cache L2 assez lent pour qu'on ne puisse précharger qu'une seule ligne de cache avant que la FTQ soit complétement vide. Ces deux optimisations sont facultatives, mais elles étaient présentes dans l'article originel qui a proposé la technique. L'unité de préchargement doit détecter quelles sont les adresses de la FTQ qui ne sont pas déjà chargées dans le L1i. En effet, il est inutile de précharger une ligne de cache si celle-ci est déjà dans le cache L1i. L'unité de préchargement doit donc filtrer au mieux les adresses de la FTQ en deux classes : celles qui correspondent à une ligne de cache déjà dans le L1i, celles qui doivent être préchargées. Pour cela, l'unité de préchargement utilise la technique dit du '''''Cache Probe Filtering'''''. L'idée part du principe que le cache d'instruction L1 est multiport. Les ports du cache d'instruction ne sont pas toujours utilisés en même temps et il arrive qu'il y ait un port de lecture de libre. Le CPF utilise alors ce port inutilisé pour vérifier si la prochaine ligne de cache à précharger est dans le cache ou non. Si c'est le cas, on aura un succès de cache : la ligne de cache est oubliée, elle ne sera pas préchargée. Si ce n'est pas le cas on aura un défaut de cache : la ligne sera préchargée. Notez que l'on a pas besoin de lire la ligne en question, juste de vérifier les tags du cache. Dans ce cas, on peut ajouter des signaux de commande spécifiques pour le CPF, qui font une demi-lecture, qui ne vérifie que les tags, mais ne lit pas la donnée. On peut par exemple ajouter un port spécifique pour le CPF, purement en lecture et qui ne permet que de vérifier les tags. Ce port en plus a un cout en circuits plus faible qu'un port de lecture normal, mais ce n'est pas gratuit du tout. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=La prédiction de branchement | prevText=La prédiction de branchement | next=L'émission dans l'ordre des instructions | nextText=L'émission dans l'ordre des instructions }} </noinclude> {{AutoCat}} pa26y1hewfslhudlv8j8awpixdlvinc 744081 744057 2025-06-03T19:37:19Z Mewtow 31375 /* La macro-fusion */ 744081 wikitext text/x-wiki Les processeurs modernes disposent de plusieurs unités de calcul, de bancs de registres larges et de tout un tas d'optimisations permettent d’exécuter un grand nombre d'instructions par secondes. Les opérations de calcul, les accès mémoire : tout cela est très rapide. Mais rien de cela ne fonctionnerait si l'unité de chargement ne suivait pas le rythme. En soi, l'unité de chargement est simple : le ''program counter'', les circuits pour l'incrémenter et gérer les branchements, l'unité de prédiction de branchement, et de quoi communiquer avec le cache. On doit aussi ajouter le registre d'instruction. Difficile de trouver de quoi l'optimiser, à part rendre l'unité de prédiction plus efficace. Pourtant, les processeurs incorporent diverses optimisations qui rendent le tout beaucoup plus rapide. La plupart de ces optimisations consistent à ajouter des files d'attente ou des mémoires caches dans le ''front-end'', que ce soit après l'étape de chargement ou de décodage. Les caches en question sont situés en aval du cache d'instruction, ce qui en fait des sortes de cache de niveau 0. Les optimisations incluent le préchargement d'instruction, l'usage de files d'attente pour découpler divers circuits et quelques autres. Voyons lesquelles dans ce chapitre. ==La file d'instruction et le cache de macro-opération== L'unité de chargement contient de nombreux circuits fortement liés entre eux, et on peut découper le tout en plusieurs circuits. L'unité de calcul d'adresse émet les adresses des instructions à charger, qui sont consommées par le cache d'instruction, qui lui-même envoie les instructions lues dans le registre d'instruction ou la file d'instructions. L'unité de calcul d'adresse regroupe : l'unité de prédiction de branchement, le ''program counter'', le circuit pour incrémenter le ''program counter'', les MUX associés pour gérer les branchements. Le couplage de ces structures fait qu'au moindre défaut de cache d'instruction, l'ensemble stoppe. Par exemple, l'unité de chargement stoppe en cas de défaut de cache. Même chose si jamais une instruction multicycle s’exécute dans le pipeline et bloque toutes les étapes précédentes. Pourtant, il est en théorie possible, et même utile, que certaines structures prennent de l'avance même si d'autres sont bloquées. Par exemple, si le pipeline est bloqué en aval de l'unité de chargement, l'unité de chargement peut en théorie précharger à l'avance des instructions. Ou encore, en cas de défaut de cache d'instruction, l'unité de calcul d'adresse peut précalculer les adresses destinées au cache et les mettre en attente. Pour cela, l'unité de chargement incorpore un paquet de mémoires FIFOs, que nous voir en détail dans ce qui suit. ===Les files d'instruction=== Les processeurs modernes intègrent une '''file d'instruction''', une mémoire FIFO, placée entre le cache d'instruction et le décodeur d'instruction. Les instructions chargées par l'étape de chargement soient accumulées dans la '''file d'instructions''' et sont décodées quand l'unité de décodage est prête. La file d'attente permet de précharger des instructions dans la file d’instructions à l'avance, permettant ainsi de masquer certains accès au cache ou à la mémoire assez longs. L'idée est que les instructions s'accumulent dans la file d'instruction si le processeur exécute les instructions moins vite qu'il ne les charge. C'est généralement signe qu'il effectue une instruction multicycle et/ou qu'il effectue un accès à la mémoire. À l'inverse, la file d'attente se vide quand le processeur éxecute les instructions plus vite qu'il n'en charge. C'est généralement signe qu'un défaut de cache d'instruction est en cours. La présence d'une file d'attente fait que la première situation est compensée lors de la seconde. Les temps d'attentes liées aux instructions multicycles permettent de remplir la file d'attente, qui est ensuite vidée en cas de défaut de cache. Le processeur exécute en permanence des instructions, sans interruption. Alors que sans file d'attente, les défauts de cache entraineront des temps d'attente où le processeur s’exécuterait rien. La seule limite de cette optimisation est l'influence des branchements. Lorsqu'un branchement est décodé, ce tampon d’instructions est totalement vidé de son contenu. Ce n'est ni plus ni moins ce que faisait la ''prefetch input queue'' des anciens processeurs Intel, dont nous avions parlé dans le chapitre sur l'unité de chargement et le séquenceur. ===La macro-fusion=== La présence d'une file d'instruction permet d'ajouter une optimisation très importante au processeur, qui ne seraient pas possibles sans elle. L'une d'entre elle est la '''macro-fusion''', une technique qui permet de fusionner une suite d'instructions consécutives en une seule micro-opération. Par exemple, il est possible de fusionner une multiplication suivie d'une addition en une seule instruction MAD (''multiply and add''), si les conditions adéquates sont réunies pour les opérandes. Comme autre exemple, il est possible de fusionner un calcul d'adresse suivi d'une lecture à l'adresse calculée en une seule micro-opération d'accès mémoire. Et enfin, il est possible de fusionner une instruction de test et une instruction de branchement en une seule micro-opération de comparaison-branchement. C'est surtout cette dernière qui est utilisée sur les processeurs Intel modernes. La macro-fusion est effectuée pendant le décodage, en décodant des instructions dans le tampon d'instruction. Le décodeur reconnait que plusieurs instructions dans le tampon d'instruction peuvent être fusionnées et fournit en sortie la micro-opération équivalent. L'avantage de cette technique est que le chemin de données est utilisé plus efficacement. Notons que la macro-fusion diminue le nombre d'instructions à stocker dans le ROB et dans les différentes mémoires intégrées aux processeur, qui stocke les micro-opérations. La technique est parfois couplée à un circuit de prédiction, qui détermine si une série d'instruction à fusionner va apparaitre sous peu. L'idée est que dans certains cas, le tampon d'instruction contient le début d'une suite d'instruction combinables. Suivant ce qui sera chargé après, la macro-fusion pourra se faire, ou non. Mais le processeur ne sait pas exactement quelles seront les instructions chargées juste après et il ne sait pas si la macro-fusion aura lieu. Dans ce cas, il peut utiliser un circuit de prédiction de macro-fusion, qui essaye de prédire si les instructions chargées sous peu autoriseront une macro-fusion ou non. Si c'est le cas, les instructions potentiellement fusionnables, le début de la série macro-fusionnable, est mise en attente dans le tampon d'instruction, en attendant les futures instructions. ===Le cache de macro-opérations=== Le cache de macro-opérations est un cache présent en aval de l'unité de chargement, à côté de la file d’instruction. Il mémorise les dernières instructions envoyées à l'unité de décodage, à savoir non pas les instructions préchargées, mais celles qui sont en cours de décodage ou d’exécution, celles qui ont quitté la file d'instruction. Il sert dans le cas où ces instructions sont ré-éxecutées, ce qui est souvent le cas avec des boucles de petite taille. A chaque cycle d'horloge, ce cache est consulté, de manière à vérifier si l'instruction voulue est dans ce cache ou non. Cela évite un accès au cache d'instruction. Son implémentation est simple : il s'agit d'un petit cache adressé par le ''program counter''. Si l'instruction a été chargée il y a peu, l'instruction machine est mémorisée dans une ligne de cache, le tag de cette ligne n'est autre que son adresse, le ''program counter'' associé. L'accès au cache de macro-opérations est de un seul cycle, pas plus. [[File:Cache de macro-ops.png|centre|vignette|upright=2|Cache de macro-ops]] L'intérêt n'est pas évident, mais disons que l'accès à ce cache gaspille moins d'énergie qu’accéder au cache d'instruction. C'est là l'intérêt principal, même s'il se peut qu'on puisse avoir un gain en performance. Le gain en question vient du fait que l'accès est plus rapide dans ce cache, ce qui n'est le cas que dans des conditions précise : si le cache d'instruction est pipeliné et a un temps d'accès de plusieurs cycles. ==La file de micro-opérations et le cache de micro-opérations== [[File:File d'instruction.png|vignette|upright=1|File d'instruction]] Sur les processeurs modernes, la sortie du décodeur est reliée à une mémoire FIFO semblable à la file d'instruction, mais placée juste après le décodeur. Elle mémorise les micro-opérations émises par le décodeur et les met en attente tant que le reste du pipeline n'est pas prêt. Nous l’appellerons la '''file de micro-opérations''', par simplicité. Le schéma ci-contre indique que la file de micro-opérations est située en sortie de l’unité de décodage, avant l'unité d'émission et avant l'unité de renommage de registres (que nous aborderons dans quelques chapitres). La file de micro-opérations permet aux décodeurs de faire leur travail même si le reste du pipeline n'est pas prêt. Par exemple, imaginons que le processeur ne peut pas émettre de nouvelle instruction, soit car toutes les ALUs sont occupées, soit car il y a un accès mémoire qui bloque le pipeline, peu importe. Sans file de micro-opérations, tout ce qui précède l'unité d'émission devrait être totalement bloqué tant que l'instruction ne peut pas être émise. Mais avec une file de micro-opérations, le pipeline peut continuer à charger et décoder des instructions, et accumuler des instructions décodées dans la file de micro-opérations. En clair, la file de micro-opérations met en attente les instructions quand des bulles de pipeline sont émises. Et à l'inverse, elle permet d'émettre des instructions quand les unités de décodage/chargement sont bloquées. Le cas classique est celui d'un défaut de cache dans le cache d'instruction. Des instructions ne peuvent plus être chargée et décodées durant quelques cycles. Sans file de micro-opérations, le processeur ne peut plus rien faire durant quelques cycles. Mais avec une file de micro-opérations, il peut en profiter pour émettre les instructions en attente dans la file de micro-opérations. En clair, si l'unité d'émission a mis en attente des instructions, le processeur se rattrape au prochain défaut de cache d'instruction. Une autre situation où le décodeur bloque est le cas où certaines instructions mettent du temps à être décodées. C'est notamment le cas de certaines instructions complexes, dont le décodage prend facilement 2 à 3 cycles d'horloge, voire plus. Le pire est le décodage des instructions microcodées, qui peut demander plusieurs cycles. Or, le pipeline demande qu'on décode une instruction par cycle pour éviter de bloquer le pipeline. Mais ce temps de décodage peut être masqué si des micro-opérations sont en attente dans la file, elles sont exécutées pendant le décodage long. La file de micro-opération est souvent complétée par plusieurs circuits, dont un circuit de micro-fusion, un cache de micro-opérations et le ''loop stream detector''. Voyons ces circuits dans ce qui suit. [[File:File de micro-opérations et cache de micro-ops - Copie.png|centre|vignette|upright=2.5|File de micro-opérations et cache de micro-ops - Copie]] ===La micro-fusion=== La présence d'une file de micro-opération permet d'effectuer une optimisation appelée la '''micro-fusion'''. Elle remplace deux micro-opérations simples consécutives en une seule micro-opération complexe équivalente. Par exemple, sur certains processeurs, le chemin de données est capable d'effectuer une lecture/écriture en adressage base+index en une seule micro-opération. Mais le jeu d'instruction est une architecture Load-store où le calcul d'adresse et l'accès mémoire se font en deux instructions séparées. Dans ce cas, la micro-fusion peut faire son travail et fusionner le calcul d'adresse avec l'accès mémoire. C'est une optimisation compatible avec la macro-fusion, les deux se ressemblant beaucoup. On peut se demander pourquoi les deux existent ensemble. La raison est historique, et tient au design des processeurs x86. Les premiers processeurs x86 avaient un chemin de données simple, avec les décodeurs qui allaient avec. Sur de tels processeurs, le calcul d'adresse et l'accès mémoire étaient séparés en deux instructions. Puis, avec l'évolution de la technologie, le chemin de données est devenu capable de faire les deux en une seule micro-opération. Pour compenser cela, Intel et AMD auraient pu changer leurs décodeurs en profondeur. A la place, ils ont préféré utiliser la technique de la micro-fusion, par simplicité. ===Le ''Loop Stream Detector''=== Les boucles sont une opportunité d'optimisation très intéressante sur les CPU avec une file de micro-opérations. L'idée est que lors d'une boucle, des instructions sont chargées, décodées et exécutées plusieurs fois de suite. Mais à, chaque répétition d'une instruction, le chargement et le décodage donnent toujours le même résultat, seule l'exécution n'est pas la même (les registres renommés sont aussi différents, mais passons). L'idée est simplement de mémoriser les N dernières instructions décodées et de les ré-exécuter si besoin. Ainsi, on évite de charger/décoder une même instruction machine plusieurs fois, mais de réutiliser les micro-opérations déjà décodées. L'implémentation la plus simple conserve les N dernières instructions décodées dans la file d'instruction, qui se comporte alors comme une sorte de pseudo-cache FIFO. Un circuit annexe, appelé le ''Loop Stream Detector'' (LSD), détecte lesboucles dans la file de micro-opérations et optimise leur exécution. Avec un LSD, la file d'instruction ne supprime pas les micro-opérations une fois qu'elles sont émises. Elle mémorise là où se trouve la dernière micro-opération émise, mais conserve celles qui ont déjà été émises. Si une boucle adéquate est détectée par le ''Loop Stream Detector'', les micro-opérations de la boucle sont lues dans la file de micro-opération et sont injectées directement dans la suite du pipeline. De plus, les unités de chargement et de décodage sont désactivées pendant l’exécution de la boucle, ce qui réduit la consommation d'énergie du CPU. L'optimisation accélère les petites boucles, à condition qu'elles s'exécutent de la même manière à chaque exécution. De telles boucles exécutent une suite de N instructions, qui reste identique à chaque itération de la boucle. Le cas le plus simple est celui d'une boucle dans laquelle il n'y a pas de branchements. Pour les boucles normales, le processeur reprend une exécution normale quand on quitte la boucle ou quand son exécution change, par exemple quand un if...else, un return ou tout autre changement de flot de contrôle a lieu. Vu que toutes ces situations impliquent un branchement qui n'a pas été pris comme avant, le processeur n'utilise plus le ''Loop Stream Detector'' en cas de mauvaise prédiction de branchement. L'optimisation vise surtout à désactiver les décodeurs et l'unité de chargement lors de l'exécution d'une boucle. La désactivation peut être du ''clock gating'', voire du ''power gating'', être partielle ou totale. Dans le pire des cas, les unités de chargement peuvent continuer à charger des instructions en avance dans une file d'instruction, mais les décodeurs peuvent être désactivés. Dans le meilleur des cas, la totalité de ce qui précède la file de micro-opération est désactivé tant que la boucle s’exécute normalement. Y compris le cache de micro-opération. [[File:Loop Stream Detector.png|centre|vignette|upright=2|Loop Stream Detector]] Les CPU Intel modernes disposent d'un ''loop stream detector'', les CPU AMD en avaient sur les microarchitectures Zen 4 mais il a disparu sur la microarchitecture Zen 5. Quelques CPU ARM avaient aussi un ''loop stream detector'', notamment le Cortex A15. Évidemment, la taille des boucles optimisées ainsi est limitée par la taille de la file de micro-opération, ce qui fait que l'optimisation ne fonctionne que pour des boucles de petite taille. De plus, toute la file de micro-opération n'est pas gérée par le ''loop stream detector''. Par exemple, les processeurs avec une file de micro-opération de 64 micro-opération peuvent gérer des boucles de maximum 32 à 40 micro-opérations. Pour donner quelques chiffres, les processeurs ARM Cortex A15 géraient des boucles de maximum 32 micro-opérations. Mais les contraintes principales portent sur la détection des boucles. Le ''Loop Stream Detector'' ne peut pas détecter toutes les boucles qui existent, et certaines boucles ne sont pas détectées. Par exemple, le ''Loop Stream Detector' ne peut pas détecter les boucles si un appel de fonction a lieu dans la boucle. Il y a aussi des contraintes quant au nombre de branchements à l'intérieur de la boucle et le nombre d'accès mémoire. Il faut noter que le ''loop stream detector'' a été désactivé par des mises à jour de microcode sur quelques architectures, comme sur la microarchitecture Zen 4 d'AMD ou les CPU de microarchitecture Skylake et Kaby Lake d'Intel. Pour la microarchitecture Skylake , les raisons officielles pour cette désactivation sont un bug lié à l'interaction avec l'''hyperthreading''. Il est vraisemblable que des bugs ou des problèmes de sécurité aient amené à la désactivation sur les autres architectures. ===Le cache de micro-opérations=== Le '''cache de micro-opérations''' a le même but que le ''Loop Stream Detector'', à savoir optimiser l'exécution des boucles. La différence avec le ''Loop Stream Detector'' est qu'il y a un cache séparé de la file de micro-opérations, qui mémorise des micro-opérations décodées, dans le cas où elles soient réutilisées par la suite. La première itération d'une boucle décode les instructions en micro-opérations, qui sont accumulées dans le cache de micro-opérations. Les itérations suivantes de la boucle vont chercher les micro-opérations adéquates dans le cache de micro-opération : on n'a pas à décoder l'instruction une nouvelle fois. Intuitivement, vous vous dites que son implémentation la plus simple mémorise les N dernières micro-opérations exécutées par le processeur, ce qui en fait un cache FIFO. Mais la réalité est que c'est déjà ce qui est fait par le couple LSD + file de micro-opération. Le cache de micro-opérations a une politique de remplacement des lignes de cache plus complexe que le FIFO, typiquement une politique LRU ou LFU approximée. De plus, le cache de micro-opération est séparé de la file de micro-opération. Et il est alimenté non pas par l'unité de décodage, mais par la file de micro-opérations. Ce sont les micro-opérations qui quittent la file de micro-opérations qui sont insérées dans le cache, pas celles qui quittent directement le décodeur. Les avantages sont les mêmes qu'avec un ''Loop Stream Detector'' : une consommation énergétique réduite, des performances légèrement améliorées. Le décodeur et l'unité de chargement sont inutiles en cas de succès dans le cache de micro-opération, ce qui fait qu'ils sont désactivés, éteints, ou du moins subissent un ''clock-gating'' temporaire. Ils ne consomment pas d'énergie, seul le cache de micro-opération utilise de l'électricité. L'avantage en termes de performance est plus faible, assez variable suivant la situation, mais aussi bien le cache de micro-opérations que le LSD ne font pas de mal. La différence avec le cache de micro-opération est que la boucle doit s’exécuter à l'identique avec un ''Loop Stream Detector'', pas avec un cache de micro-opérations. Prenons l'exemple d'une boucle contenant quelques instructions suivies par un IF...ELSE. Il arrive qu'une itération de la boucle exécute le IF, alors que d'autres exécutent le ELSE. Dans ce cas, le ''Loop Stream Detector'' ne sera pas activé, car la boucle ne s’exécute pas pareil d'une itération à l'autre. Par contre, avec un cache de macro/micro-opération, on pourra lire les instructions précédant le IF...ELSE dedans. Le cache de micro-opération est donc plus efficace que le ''Loop Stream Detector'', mais pour un cout en transistor plus élevé. Le cache de micro-opérations et le ''Loop Stream Detector'' font la même chose, mais certains processeurs implémentaient les deux. L'avantage est que le cache de micro-opération peut être désactivé si jamais le LSD détecte une boucle dans la file d'instruction, ce qui réduit encore plus la consommation énergétique. En pratique, l'impact sur la consommation énergétique est très difficile à mesurer, mais il rajoute de la complexité pour la conception du processeur. [[File:File de micro-opérations et cache de micro-ops.png|centre|vignette|upright=2|File de micro-opérations et cache de micro-ops]] Le cache de micro-opération associe, pour chaque instruction machine, une ou plusieurs micro-opérations. Avec l'implémentation la plus simple, une ligne de cache est associée à une instruction machine. Par exemple, sur les processeurs Intel de microarchitecture Skylake, chaque ligne de cache était associée à une instruction machine et pouvait contenir de 1 à 6 micro-opérations. La suite de micro-opérations correspondant à une instruction devait tenir toute entière dans une ligne de cache, ce qui fait que les instructions décodées en plus de 6 micro-opérations ne pouvaient pas rentrer dans ce cache. L'accès au cache de micro-opération se fait lors de l'étape de chargement. Le cache de micro-opérations est adressé en envoyant le ''program counter'' sur son entrée d'adresse, en parallèle du cache d'instruction. Le cache de micro-opération est une voie de chargement parallèle au ''front-end'' proprement dit. En clair, il y a une voie qui regroupe cache d'instruction, file d'instruction et décodeur, et une seconde voie qui se résume au cache de micro-opération. Les deux voies sont accédées en parallèle. En cas de succès dans le cache de micro-opération, les micro-opérations adéquates sont lues directement depuis le cache de micro-opération. Il existe deux méthodes différentes pour encoder les micro-opérations dans le cache de micro-opérations. La première est la plus intuitive : on mémorise les micro-opérations dans la ligne de cache, directement. Elle est utilisée sur les processeurs AMD, et sans doute sur les processeurs Intel récents. Mais les anciens processeurs Intel, comme ceux des architectures Sandy Bridge et Netburst, utilisent une autre méthode. Une ligne de cache mémorise non pas les micro-opération directement, mais un pointeur vers le ''control store'', qui indique à quelle adresse dans le micro-code se situe la micro-opération. La micro-opération est donc lue depuis le micro-code lors de l'émission. Il faut noter que pour des raisons de performance, le cache de micro-opérations est virtuellement tagué, ce qui fait qu'il est invalidé en cas de changement de programme. Sur l'architecture Sandy Bridge, il est carrément inclus dans le cache L1, les deux sont des caches inclusifs l'un avec l'autre. Les premières implémentations étaient très limitées. Les micro-opérations devaient être séquentielles dans le code, le cache était consulté seulement après un branchement et non à chaque émission d'instruction, pour limiter la consommation d'énergie an détriment des performances. Ces limitations ne sont pas présentes sur les architectures récentes. Aussi bien le cache de macro-opérations que le cache de micro-opérations optimisent l'exécution des boucles, mais ils ne sont pas au même endroit dans le pipeline : avant et après l'unité de décodage. Et le premier mémorise des instructions machines, l'autre des micro-opérations décodées. Les avantages et inconvénients sont totalement différents. Niveau capacité des deux caches, l'encodage des instructions machines est plus compact que la ou les micro-instructions équivalente, ce qui est un avantage pour le cache de macro-opérations à capacité équivalente. Par contre, le cache de micro-opérations permet de désactiver les décodeurs en cas de succès de cache, vu que les instructions ne doivent plus être décodées et renommées. Le gain est d'autant plus important si les instructions ont un encodage complexe, ou si les instructions sont à longueur variable, ce qui rend leur décodage complexe et donc lent. Globalement, plus le décodage est complexe et/ou long, plus le cache de micro-opérations fait des merveilles. ==Le préchargement d'instructions et la ''Fetch Target Queue''== Les processeurs modernes incorporent une optimisation assez intéressante : ils découplent l'unité de prédiction de branchement et le ''program counter'' de l'accès au cache d'instruction. Pour cela, ils incorporent une mémoire FIFO entre l'unité de prédiction de branchement et le cache d'instruction. Les premiers articles scientifiques, qui ont proposé cette solution, l'ont appelée la '''''Fetch Target Queue''''', abréviée FTQ. Elle accumule les adresses à lire/écrire dans le cache d'instruction, peu importe que ces adresses viennent du ''program counter'' ou de l'unité de prédiction de branchement. [[File:Fetch target queue.png|centre|vignette|upright=2.5|Fetch target queue]] Elle se remplit quand le cache d'instruction est bloqué, soit à cause d'un défaut de cache, soit à cause d'un pipeline bloqué en amont de l'unité de chargement. Par exemple, si le cache d'instruction est bloqué par un défaut de cache, l'unité de prédiction de branchement peut accumuler des prédictions à l'avance dans la FTQ, qui sont ensuite consommées par le cache d'instruction une fois qu'il est redevenu disponible. De même, si l'unité de prédiction de branchement est bloquée par un évènement quelconque, le cache d'instruction peut consommer les prédictions faites à l'avance. Une utilisation assez originale de la FTQ s'est vu sur les processeurs AMD d'architectures bulldozer. Sur cette architecture, les cœurs étaient regroupés par paquets de deux, et les deux cœurs partageaient certains circuits. Notamment, l'unité de prédiction de branchement était partagée entre les deux cœurs ! Pourtant, chaque cœur disposait de sa propre FTQ ! Un avantage de la FTQ tient dans le fait que les caches d'instructions sont pipelinés, sur le même modèle que les processeurs. On peut leur envoyer une demande de lecture/écriture par cycle, alors que chaque lecture/écriture prendra plusieurs cycles à s'effectuer. L'accès au cache d'instruction a donc une certaine latence, qui est partiellement masquée par la FTQ au point où elle ne s'exprime qu'en cas de défaut de cache assez important. Par exemple, si l'accès au cache d'instruction prend 4 cycles, une FTQ qui met en attente 4 adresses camouflera le temps d'accès au cache, tant qu'il n'y a pas de mauvaise prédiction de branchement. La FTQ est aussi très utile avec les unités de branchement modernes, qui peuvent mettre plusieurs cycles pour fournir une prédiction. Prendre de l'avance avec une FTQ amorti partiellement le temps de calcul des prédictions. : Si le cache d'instruction est multiport et accepte plusieurs accès simultanés, il peut consommer plusieurs entrées dans la FTQ à la fois. Mais l'avantage principal de la FTQ est qu'elle permet l'implémentation d'une optimisation très importante. Il y a quelques chapitres, nous avions parlé des techniques de '''préchargement d'instruction''', qui permettent de charger à l'avance des instructions dans le cache d'instruction. Nous avions volontairement laissé de côté le préchargement des instructions, pour tout un tas de raisons. Et la raison est justement que la prédiction de branchement et le préchargement des instructions sont fortement liés sur les processeurs modernes. Il est maintenant possible d'aborder le préchargement pour les instructions, d’où cette section. Notons que par préchargement des instructions, on peut parler de deux formes de préchargement, fortement différentes. La première correspond au préchargement normal, à savoir le préchargement des instructions dans le cache d'instruction L1, à partir du cache L2. Il s'agit donc d'un préchargement dans le cache d'instruction. Mais il existe aussi une autre forme de préchargement, qui consiste à précharger à l'avance des instructions dans la file d'instruction et qui a été abordée dans la section sur la ''prefetch input queue''. Les deux formes de préchargement n'ont pas lieu au même endroit dans la hiérarchie mémoire : l'une précharge du cache L2 vers le L1i, l'autre du cache L1i vers la file d'instruction (ou dans le cache de macro-opération). Mais les algorithmes utilisés pour sont sensiblement les mêmes. Aussi, nous allons les voir en même temps. Pour faire la distinction, nous parlerons de préchargement L2-L1i pour la première, de préchargement interne pour l'autre. ===Les algorithmes de préchargement d'instructions=== Les techniques basiques de préchargement consistent à charger des instructions qui suivent la dernière ligne de cache accédée. Quand on charge des instructions dans le cache d’instruction, les instructions qui suivent sont chargées automatiquement, ligne de cache par ligne de cache. il s'agit due préchargement séquentiel, la technique la plus simple de préchargement, qui profite de la localité spatiale. Elle est utilisée pour précharger des instructions du cache L2 vers le cache L1i, mais aussi pour le préchargement interne dans la file d'instructions. [[File:Branchements et préchargement séquentiel.png|centre|vignette|upright=2|Branchements et préchargement séquentiel.]] Mais un ''prefetcher'' purement séquentiel gère mal les branchements. Si un branchement est pris, les instructions de destination ne sont pas chargées, si elles ne sont pas dans la ligne de cache suivante. Pour le préchargement L2-L1i, cela ne pose pas de problèmes majeurs, au-delà de la pollution du cache L1i par des instructions inutiles. Mais pour le préchargement interne, c'est autre chose. Les instructions préchargées par erreurs doivent être supprimées pour éviter qu'elles soient décodées et exécutées, ce qui fait que la file d’instruction doit être invalidée. Il existe des techniques de préchargement plus élaborées qui marchent mieux en présence de branchements. Elles utilisent toutes une collaboration de l'unité de prédiction de branchement. Elles accèdent au ''Branch Target Buffer'', pour détecter les branchements, leur destination, etc. Le tout peut se coupler à la technique du prédécodage. Avec cette dernière, le prédécodage décode en partie les instructions lors de leur chargement dans le cache, et détecte les branchements et leur adresse de destination à ce moment-là. Ces informations sont alors mémorisées dans une table à part, ou dans le BTB. Mais la plupart des designs utilisent le BTB, par souci de simplicité. Il existe globalement deux à trois techniques principales, que nous allons voir dans ce qui suit. La première technique prédit si le branchement est pris ou non, et agit différemment si le branchement est pris ou non. Si le branchement est pris, elle précharge les instructions à partir de l'adresse de destination des branchements pris. Sinon, elle précharge les instructions suivantes avec préchargement séquentiel. Il s'agit du '''''target line prefetching''''' [[File:Target line prefetching.png|centre|vignette|upright=2|Target line prefetching.]] Une autre technique ne prédit pas les branchements et précharge à la fois les instructions suivantes avec le ''next-line prefetching'', et la ligne de cache de destination du branchement avec le ''target line prefetching''. Comme ça, peu importe que le branchement soit pris ou non, les instructions adéquates seront préchargées quand même. On appelle cette technique le '''préchargement du mauvais chemin''' (''wrong path prefetching''). [[File:Préchargement du mauvais chemin.png|centre|vignette|upright=2|Préchargement du mauvais chemin.]] Le ''target line prefetching'' est plus complexe à implémenter, car il demande de prédire les branchements. Mais elle a l'avantage de ne pas précharger inutilement deux lignes de cache par branchement, seulement une seule. Par contre, le préchargement est inutile en cas de mauvaise prédiction de branchement : non seulement on a préchargé une ligne de cache inutilement, mais en plus, la ligne de cache adéquate n'a pas été chargée. On n'a pas ce problème avec le préchargement du mauvais chemin, qui garantit que la ligne de cache adéquate est toujours préchargée. ===L'implémentation du préchargement interne, dans la file d'instruction=== Le préchargement dans la file d'instruction est généralement de type séquentiel, mais certains processeurs font autrement. Déjà, il faut remarquer que le ''target line prefetching'' correspond en réalité à la prédiction de branchement classique. L'adresse de destination est prédite, et on charge les instructions adéquates dans la file d'instruction. La prédiction de branchement, associée à une file d'instruction, est donc une forme de préchargement. Il fallait y penser. Enfin, des processeurs assez rares utilisaient le préchargement du mauvais chemin. Le préchargement du mauvais chemin demande d'utiliser deux files d'instructions séparées. L'une dans laquelle on précharge de manière séquentielle, l'autre dans laquelle on utilise la prédiction de branchement pour faire du ''target line prefetching''. Une fois que l'on sait si la prédiction de branchement était correcte, on est certain qu'une des deux files contiendra les instructions valides. Le contenu de la file adéquate est conservé, alors que l'autre est intégralement invalidée. Le choix de la bonne file se fait avec un multiplexeur. C'est approximativement la technique qui était implémentée sur le processeur de mainframe IBM 370/165, par exemple, et sur quelques modèles IBM similaires. Le problème est que cette méthode demande de charger deux instructions à chaque cycle. Cela demande donc d'utiliser un cache d'instruction multiport, avec un port par file d'instruction. Le cout en circuit d'un cache double port n'est pas négligeable. Et le gain en performance est assez faible. Le préchargement dans la file d’instruction permet d'économiser quelques cycles lors de l'accès au cache d'instruction, guère plus. Le gain est maximal lorsque les instructions préchargées ont généré un défaut de cache, qui a rapatrié les instructions adéquates pendant que le processeur exécutait les mauvaises instructions, avant que la mauvaise prédiction de branchement soit détectée. Dans ce cas, le défaut de cache a eu lieu pendant la mauvaise prédiction et sa réparation, et non après. ====La gestion des branchements successifs==== Un autre défaut de cette méthode est la présence de branchements successifs. Par exemple, si jamais on rencontre un branchement, le flux d'instructions se scinde en deux : un où le branchement est pris, un autre où il ne l'est pas. Chacun de ces flux peut lui-même contenir un branchement, et se scinder lui aussi. Et ainsi de suite. Et le processeur doit gérer cette situation en termes de préchargement. [[File:Exécution stricte 04.png|centre|vignette|upright=2|Exécution stricte]] Plusieurs solutions existent. La méthode la plus simple stoppe le chargement du flux en attendant que le premier branchement soit terminé. Cette solution est intuitive, mais est celle où on a les gains en performance les plus faibles. Elle est couramment implémentée d'une manière assez particulière, qui ne correspond pas tout à fait à un stop du chargement, mais qui utilise les lignes de cache. L'unité de préchargement est conçue pour copier des lignes de cache entières dans la file d'instruction. Le processeur (pré-)charge deux lignes de cache : celle du bon chemin, celle du mauvais chemin. Il les précharge dans deux files d'instructions, qui contiennent généralement une ligne de cache grand maximum. Le temps que l'on ait chargé les deux files d'instruction, le résultat du branchement est connu et on sait laquelle est la bonne. L'autre possibilité est d'utiliser la prédiction de branchement pour ce flux, afin de poursuivre le chargement de manière spéculative. Elle donne de bonnes performances, mais demande des unités de prédiction de branchement spéciales, dans le cas où les deux flux tombent sur un branchement en même temps. Cette technique est indirectement liée au cache de traces que nous verrons dans le chapitre sur les processeurs superscalaires. Nous n'en parlons pas ici, car ce genre de techniques est plus liée aux processeurs superscalaires qu'un processeur avec un pipeline normal. Une autre possibilité consiste à scinder ce flux en deux et charger les deux sous-flux. Cette dernière est impraticable car elle demande des caches avec un grand nombre de ports et la présence de plusieurs files d'instructions, qui sont utilisées assez rarement. [[File:Exécution stricte 01.png|centre|vignette|upright=2|Exécution stricte, seconde.]] ====Les processeurs à exécution de chemins multiples==== L'idée précédente peut en théorie être améliorée, afin de non seulement charger les instructions en provenance des deux chemins (celui du branchement pris, et celui du branchement non pris), mais aussi de les exécuter : c'est ce qu'on appelle l''''exécution stricte''' (''eager execution''). Bien sûr, on n’est pas limité à un seul branchement, mais on peut poursuivre un peu plus loin. Quelques papiers de recherche ont étudié l'idée, mais ses défauts font qu'elle n'a jamais été utilisée dans un processeur en dehors de prototypes destinés à la recherche. Le gros problème de l'exécution stricte est qu'on est limité par le nombre d'unités de calculs, de registres, etc. Autant ce serait une technique idéale sur des processeurs avec un nombre illimité de registres ou d'unités de calcul, autant ce n'est pas le cas dans le monde réel. Au bout d'un certain nombre d’embranchements, le processeur finit par ne plus pouvoir poursuivre l’exécution, par manque de ressources matérielles et doit soit stopper, soit recourir à la prédiction de branchement. Il y a le même problème avec le préchargement interne simple, quand on utilise le préchargement du mauvais chemin, comme vu juste au-dessus. ===L'implémentation matérielle du préchargement de cache L2-L1i=== Pour comprendre comment s'effectue le préchargement L2-L1i, il faut regarder comment l'unité de chargement communique avec les caches. L'unité de prédiction de branchement est généralement regroupée avec le ''program counter'' et les circuits associés (les incrémenteurs/MUX associés), pour former l'unité de chargement proprement dite. L'unité de chargement émet des adresses consommées par le cache d'instruction, qui lui-même envoie les instructions lues dans le registre d'instruction ou la file d'instructions. Le couplage de ces structures fait qu'au moindre défaut de cache d'instruction, l'ensemble stoppe. Et notamment, l'unité de prédiction de branchement stoppe en cas de défaut de cache. Même chose si jamais une instruction multicycle s’exécute dans le pipeline et bloque toutes les étapes précédentes. Les pertes de performance ne sont pas très importantes, mais elles existent. Et le préchargement se manifeste dans ces situations. Le préchargement d'instructions consiste à découpler ces structures de manière à ce qu'elles fonctionnent plus ou moins indépendamment. Le but est qu'en plus des accès normaux au cache d'instruction, l'unité de chargement envoie des informations au cache L2 ou L1i en avance, pour effectuer le préchargement. L'unité de chargement doit alors prendre de l'avance sur le cache, pour effectuer les accès au cache L2 en avance, tout en maintenant l'état normal pour effectuer les accès normaux. C'est donc plus ou moins l'unité de chargement qui s'occupe du préchargement, ou du moins les deux sont très liées. ====L'anticipation du ''program counter''==== Avec la solution la plus simple, on a une unité de chargement qui s'occupe des accès au cache d'instruction, et une unité de préchargement qui prend de l'avance sur l'unité de chargement, et communique avec le cache L2. La technique la plus basique se base sur un ''Lookahead program counter'', un second ''program counter'' qui ne fonctionne que lors d'un défaut de cache d'instruction. Il est initialisé avec le ''program counter'' lors d'un défaut de cache, puis il est incrémenté à chaque cycle et les branchements sont prédits, ce qui fait qu'il est mis à jour comme si l’exécution du programme se poursuivait, alors que le reste du processeur est mis en attente. La technique initiale utilisait ce second ''program counter'' pour accéder à une table de prédiction, qui associe à chaque valeur du ''program counter'', l'adresse des données chargées par l'instruction associée. Les adresses fournies à chaque cycle par cette table sont alors envoyées aux unités de préchargement pour qu'elles fassent leur travail. La technique permettait donc de précharger des données en cas de défaut de cache, mais pas d'instructions. Il ne s'agissait pas d'une technique de préchargement des instructions, mais de préchargement de données. La technique a ensuite été adaptée pour le chargement des instructions par Chen, Lee et Mudge. Leur idée utilisait deux unités de prédiction de branchements : une couplée à l'unité de chargement, l'autre pour le préchargement. La première utilisait le ''program counter'' normal, l'autre se déclenchait en cas de défaut de cache et utilisait un ''lookahead program counter''. Les adresses générées par le ''lookahead program counter'' étaient envoyée au cache d'instruction, sur un port de lecture séparé. La ligne de cache lue était alors prédécodée pour détecter les branchements, qui étaient prédits, et rebelote. Il est possible d'adapter la méthode pour que les adresses soient accumulées dans une mémoire FIFO, et étaient consommée par le cache d'instruction L2 pour le préchargement si la ligne de cache associée n'était pas dans le cache d’instruction. Les techniques modernes n'utilisent plus de seconde unité de prédiction de branchement, mais conservent un ''lookahead program counter''. Par contre, le BTB dispose de plusieurs ports : un pour la prédiction de branchement normale, l'autre pour le préchargement. L'unité de préchargement et l'unité de chargement accèdent toutes deux au BTB quand elles ont besoin de faire leurs prédictions, en parallèle. Typiquement, le BTB est accédé à chaque cycle pour la prédiction de branchement, à un rythme plus faible pour le préchargement. ====Le ''Fetch Directed Instruction Prefetching''==== Les processeurs modernes semblent utiliser un algorithme connu sous le nom de '''''Fetch Directed Instruction Prefetching'''''. Il utilise les adresses contenues dans la FTQ pour précharger les instructions adéquates du cache L2 vers le cache L1 d'instruction (L1i). L'unité de préchargement est placée en aval de la FTQ, elle lit son contenu, détecte quelles adresses correspondent à des lignes de cache à précharger, et envoie celles-ci au cache L2. Le préchargement du L2 vers le L1i a lieu quand le cache L2 est inutilisé, ou du moins quand il peut accepter une nouvelle lecture (dans le cas d'un cache multiport et/ou pipeliné). [[File:Fetch directed instruction prefetching.png|centre|vignette|upright=2.5|Fetch directed instruction prefetching]] On peut améliorer légèrement le design précédent sur plusieurs points. Pour éviter de polluer le cache L1 avec des lignes de caches préchargées à tort, il est possible d'ajouter un équivalent des ''stream buffer'' vus dans le chapitre sur le préchargement. Il s'agit d'une autre mémoire FIFO qui mémorise les lignes de cache préchargées. Les lignes de cache préchargées ne sont pas placées dans le cache L1i, mais dans cette file d'attente. Lors d'un accès au L1i, la file d'attente est consultée en parallèle. Si l'instruction voulue est dans la file d'attente, elle est lue depuis la file, et la ligne de cache associée est copiée dans le cache L1i. Mais c'est là une possibilité facultative. Un autre point est que l'unité de préchargement doit attendre que le cache L2 puisse accepter une nouvelle lecture pour lancer le préchargement d'une autre ligne de cache. Pour corriger cela, on ajoute une file d'attente entre le cache L2 et l'unité de préchargement, qui est évidemment une mémoire FIFO. Son utilité dépend des temps de lectures du cache L2, ainsi que de la taille de la FTQ. Elle n'est pas toujours nécessaire, certains processeurs ont un cache L2 assez lent pour qu'on ne puisse précharger qu'une seule ligne de cache avant que la FTQ soit complétement vide. Ces deux optimisations sont facultatives, mais elles étaient présentes dans l'article originel qui a proposé la technique. L'unité de préchargement doit détecter quelles sont les adresses de la FTQ qui ne sont pas déjà chargées dans le L1i. En effet, il est inutile de précharger une ligne de cache si celle-ci est déjà dans le cache L1i. L'unité de préchargement doit donc filtrer au mieux les adresses de la FTQ en deux classes : celles qui correspondent à une ligne de cache déjà dans le L1i, celles qui doivent être préchargées. Pour cela, l'unité de préchargement utilise la technique dit du '''''Cache Probe Filtering'''''. L'idée part du principe que le cache d'instruction L1 est multiport. Les ports du cache d'instruction ne sont pas toujours utilisés en même temps et il arrive qu'il y ait un port de lecture de libre. Le CPF utilise alors ce port inutilisé pour vérifier si la prochaine ligne de cache à précharger est dans le cache ou non. Si c'est le cas, on aura un succès de cache : la ligne de cache est oubliée, elle ne sera pas préchargée. Si ce n'est pas le cas on aura un défaut de cache : la ligne sera préchargée. Notez que l'on a pas besoin de lire la ligne en question, juste de vérifier les tags du cache. Dans ce cas, on peut ajouter des signaux de commande spécifiques pour le CPF, qui font une demi-lecture, qui ne vérifie que les tags, mais ne lit pas la donnée. On peut par exemple ajouter un port spécifique pour le CPF, purement en lecture et qui ne permet que de vérifier les tags. Ce port en plus a un cout en circuits plus faible qu'un port de lecture normal, mais ce n'est pas gratuit du tout. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=La prédiction de branchement | prevText=La prédiction de branchement | next=L'émission dans l'ordre des instructions | nextText=L'émission dans l'ordre des instructions }} </noinclude> {{AutoCat}} m320e057kfkff4frmhhdt0zxpsj9052 Les cartes graphiques/La mémoire unifiée et la mémoire vidéo dédiée 0 80571 744045 744007 2025-06-03T14:29:34Z Mewtow 31375 /* Historique de la mémoire virtuelle sur les GPU */ 744045 wikitext text/x-wiki Pour rappel, il existe deux types de cartes graphiques : les cartes dédiées et les cartes intégrées. Les '''cartes graphiques dédiées''' sont des cartes graphiques branchées sur des connecteurs/ports de la carte mère. A l'opposé, tous les processeurs modernes intègrent une carte graphique, appelée '''carte graphique intégrée''', ou encore '''IGP''' (''Integrated Graphic Processor''). En somme, les cartes dédiées sont opposées à celles intégrées dans les processeurs modernes. La différence a un impact sur la mémoire vidéo. Les cartes graphiques dédiées ont souvent de la mémoire vidéo intégrée à la carte graphique. Il y a des exceptions, mais on en parlera plus tard. Les cartes graphiques intégrées au processeur n'ont pas de mémoire vidéo dédiée, vu qu'on ne peut pas intégrer beaucoup de mémoire vidéo dans un processeur. La conséquence est qu'il existe deux grandes manières d'organiser la mémoire à laquelle la carte graphique a accès. * La première est celle de la '''mémoire vidéo dédiée''', à savoir que la carte graphique dispose de sa propre mémoire rien qu'à elle, séparée de la mémoire RAM de l'ordinateur. On fait alors la distinction entre ''RAM système'' et ''RAM vidéo''. Si les premières cartes graphiques n'avaient que quelques mégaoctets de RAM dédiée, elles disposent actuellement de plusieurs gigas-octets de RAM. * A l'opposé, on trouve la '''mémoire unifiée''', avec une seule mémoire RAM est partagée entre le processeur et la carte graphique. Le terme "unifiée" sous-entend que l'on a unifié la mémoire vidéo et la mémoire système (la RAM). [[File:Répartition de la mémoire entre RAM système et carte graphique.png|centre|vignette|upright=2.5|Répartition de la mémoire entre RAM système et carte graphique]] Dans la grosse majorité des cas, les cartes vidéos dédiées ont une mémoire dédiée, alors que les cartes graphiques intégrées doivent utiliser la mémoire unifiée. Mais outre les cartes dédiées et intégrées, il faut aussi citer les cartes graphiques soudées sur la carte mère. Elles étaient utilisées sur les consoles de jeu vidéos assez anciennes, elles sont encore utilisées sur certains PC portables puissants, destinés aux ''gamers''. Pour ces dernières, il est possible d'utiliser aussi bien de la mémoire dédiée que de la mémoire unifiée. D'anciennes consoles de jeu avaient une carte graphique soudée sur la carte mère, qu'on peut facilement repérer à l’œil nu, avec une mémoire unifiée. C'est notamment le cas sur la Nintendo 64, pour ne citer qu'elle. D'autres avaient leur propre mémoire vidéo dédiée. L'usage d'une carte vidéo dédiée se marie très bien avec une mémoire vidéo dédiée, mais il existe de nombreux cas où une carte vidéo dédiée est associée à de la mémoire unifiée. Comme exemple, la toute première carte graphique AGP, l'Intel 740, ne possédait pas de mémoire vidéo proprement dite, juste un simple ''framebuffer''. Tout le reste, texture comme géométrie, était placé en mémoire système et la carte graphique allait lire/écrire les données directement en mémoire RAM système ! Les performances sont généralement ridicules, pour des raisons très diverses, mais les cartes de ce type sont peu chères. Outre l'économie liée à l'absence de mémoire vidéo, les cartes graphiques de ce type sont peu puissantes, l'usage de la mémoire unifiée simplifie leur conception, etc. Par exemple, l'Intel 740 a eu un petit succès sur les ordinateurs d'entrée de gamme. ==Le partage de la mémoire unifiée== Avec la mémoire unifiée, la quantité de mémoire système disponible pour la carte graphique est généralement réglable avec un réglage dans le BIOS. On peut ainsi choisir d'allouer 64, 128 ou 256 mégaoctets de mémoire système pour la carte vidéo, sur un ordinateur avec 4 gigaoctets de RAM. L'interprétation de ce réglage varie grandement selon les cartes mères ou l'IGP. Pour les GPU les plus anciens, ce réglage implique que la RAM sélectionnée est réservée uniquement à la carte graphique, même si elle n'en utilise qu'une partie. La répartition entre mémoire vidéo et système est alors statique, fixée une fois pour toutes. Dans ce cas, la RAM allouée à la carte graphique est généralement petite par défaut. Les concepteurs de carte mère ne veulent pas qu'une trop quantité de RAM soit perdu et inutilisable pour les applications. Ils brident donc la carte vidéo et ne lui allouent que peu de RAM. Heureusement, les GPU modernes sont plus souples. Ils fournissent deux réglages : une quantité de RAM minimale, totalement dédiée au GPU, et une quantité de RAM maximale que le GPU ne peut pas dépasser. Par exemple, il est possible de régler le GPU de manière à ce qu'il ait 64 mégaoctets rien que pour lui, mais qu'il puisse avoir accès à maximum 1 gigaoctet s'il en a besoin. Cela fait au total 960 mégaoctets (1024-64) qui peut être alloués au choix à la carte graphique ou au reste des programmes en cours d’exécution, selon les besoins. Il est possible d'allouer de grandes quantités de RAM au GPU, parfois la totalité de la mémoire système. [[File:Partage de la mémoire unifiée entre CPU et GPU.png|centre|vignette|upright=2|Répartition de la mémoire entre RAM système et carte graphique]] ==Le partage de la mémoire système : la mémoire virtuelle des GPUs dédiés== Après avoir vu la mémoire unifiée, voyons maintenant la mémoire dédiée. Intuitivement, on se dit que la carte graphique n'a accès qu'à la mémoire vidéo dédiée et ne peut pas lire de données dans la mémoire système, la RAM de l'ordinateur. Cependant, ce n'est pas le cas. Et ce pour plusieurs raisons. La raison principale est que des données doivent être copiées de la mémoire RAM vers la mémoire vidéo. Les copies en question se font souvent via ''Direct Memory Access'', ce qui fait que les GPU intègrent un contrôleur DMA dédié. Et ce contrôleur DMA lit des données en RAM système pour les copier en RAM vidéo. La seconde raison est que les cartes graphiques intègrent presque toutes des technologies pour lire directement des données en RAM, sans forcément les copier en mémoire vidéo. Les technologies en question permettent à la carte graphique d'adresser plus de RAM qu'en a la mémoire vidéo. Par exemple, si la carte vidéo a 4 giga-octets de RAM, la carte graphique peut être capable d'en adresser 8 : 4 gigas en RAM vidéo, et 4 autres gigas en RAM système. Les technologies de ce genre ressemblent beaucoup à la mémoire virtuelle des CPU, avec cependant quelques différences. La mémoire virtuelle permet à un processeur d'utiliser plus de RAM qu'il n'y en a d'installée dans l'ordinateur. Par exemple, elle permet au CPU de gérer 4 gigas de RAM sur un ordinateur qui n'en contient que trois, le gigaoctet de trop étant en réalité simulé par un fichier sur le disque dur. La technique est utilisée par tous les processeurs modernes. La mémoire virtuelle des GPUs dédiés fait la même chose, sauf que le surplus d'adresses n'est pas stockés sur le disque dur dans un fichier pagefile, mais est dans la RAM système. Pour le dire autrement, ces cartes dédiées peuvent utiliser la mémoire système si jamais la mémoire vidéo est pleine. [[File:Mémoire virtuelle des cartes graphiques dédiées.png|centre|vignette|upright=2|Mémoire virtuelle des cartes graphiques dédiées]] ===La ''IO-Memory Management Unit'' (IOMMU)=== Pour que la carte graphique ait accès à la mémoire système, elle intègre un circuit appelé la '''''Graphics address remapping table''''', abrévié en GART. Cela vaut aussi bien pour les cartes graphiques utilisant le bus AGP que pour celles en PCI-Express. La GART est techniquement une une ''Memory Management Unit'' (MMU), à savoir un circuit spécialisé qui prend en charge la mémoire virtuelle. La dite MMU étant intégrée dans un périphérique d'entrée-sortie (IO), ici la carte graphique, elle est appelée une IOMMU. L'espace d'adressage est l'ensemble des adresses géré par le processeur ou la carte graphique. En théorie, l'espace d'adressage du processeur et de la carte graphique sont séparés, mais des standards comme l''''''Heterogeneous System Architecture''''' permettent au processeur et à une carte graphique de partager le même espace d'adressage. Une adresse mémoire est alors la même que ce soit pour le processeur ou la carte graphique. {|class="wikitable" |- ! !! Mémoire vidéo dédiée !! Mémoire vidéo unifiée |- ! Sans HSA | [[File:Desktop computer bus bandwidths.svg|400px|Desktop computer bus bandwidths]] | [[File:Integrated graphics with distinct memory allocation.svg|400px|Integrated graphics with distinct memory allocation]] |- ! Avec HSA | [[File:HSA-enabled virtual memory with distinct graphics card.svg|400px|HSA-enabled virtual memory with distinct graphics card]] | [[File:HSA-enabled integrated graphics.svg|400px|HSA-enabled integrated graphics]] |} ===Historique de la mémoire virtuelle sur les GPU=== La technologie existait déjà sur certaines cartes graphiques au format PCI, mais la documentation est assez rare. La carte graphique NV1 de NVIDIA, leur toute première carte graphique, disposait déjà de ce système de mémoire virtuelle. La carte graphique communiquait avec le processeur grâce à la fonctionnalité ''Direct Memory Access'' et intégrait donc un contrôleur DMA. Le ''driver'' de la carte graphique programmait le contrôleur DMA en utilisant les adresses fournies par les applications/logiciels. Et il s'agissait d'adresses virtuelles, non d'adresses physiques en mémoire RAM. Pour résoudre ce problème, le contrôleur DMA intégrait une MMU, une unité de traduction d'adresse, qui traduisait les adresses virtuelles fournies par les applications en adresse physique en mémoire système. : Le fonctionnement de cette IOMMU est décrite dans le brevet "US5758182A : DMA controller translates virtual I/O device address received directly from application program command to physical i/o device address of I/O device on device bus", des inventeurs David S. H. Rosenthal et Curtis Priem. [[File:Microarchitecture du GPU NV1 de NVIDIA.png|centre|vignette|upright=2|Microarchitecture du GPU NV1 de NVIDIA]] La technologie s'est démocratisée avec le bus AGP, dont la fonctionnalité dite d'''AGP texturing'' permettait de lire ou écrire directement dans la mémoire RAM, sans passer par le processeur. D'ailleurs, la carte graphique Intel i740 n'avait pas de mémoire vidéo et se débrouillait uniquement avec la mémoire système. L'arrivée du bus PCI-Express ne changea pas la donne, si ce n'est que le bus était plus rapide, ce qui améliorait les performances. Au début, seules les cartes graphiques PCI-Express d'entrée de gamme pouvaient accéder à certaines portions de la mémoire RAM grâce à des technologies adaptées, comme le TurboCache de NVIDIA ou l'HyperMemory d'AMD. Mais la technologie s'est aujourd'hui étendue. De nos jours, toutes les cartes vidéos modernes utilisent la RAM système en plus de la mémoire vidéo, mais seulement en dernier recours, soit quand la mémoire vidéo est quasiment pleine, soit pour faciliter les échanges de données avec le processeur. C'est typiquement le pilote de la carte graphique qui décide ce qui va dans la mémoire vidéo et la mémoire système, et il fait au mieux de manière à avoir les performances optimales. ==Les échanges entre processeur et mémoire vidéo== Quand on charge un niveau de jeux vidéo, on doit notamment charger la scène, les textures, et d'autres choses dans la mémoire RAM, puis les envoyer à la carte graphique. Ce processus se fait d'une manière fortement différente selon que l'on a une mémoire unifiée ou une mémoire vidéo dédiée. ===Avec la mémoire unifiée=== Avec la mémoire unifié, les échanges de données entre processeur et carte graphique sont fortement simplifiés et aucune copie n'est nécessaire. La carte vidéo peut y accéder directement, en lisant leur position initiale en RAM. Une partie de la RAM est visible seulement pour le CPU, une autre seulement pour le GPU, le reste est partagé. Les échanges de données entre CPU et GPU se font en écrivant/lisant des données dans la RAM partagée entre CPU et GPU. Pas besoin de faire de copie d'une mémoire à une autre : la donnée a juste besoin d'être placée au bon endroit. Le chargement des textures, du tampon de commandes ou d'autres données du genre, est donc très rapide, presque instantané. Par contre, le débit de la RAM unifiée est partagé entre la carte graphique et le processeur. Alors qu'avec une mémoire dédiée, tout le débit de la mémoire vidéo aurait été dédié au GPU, le CPU ayant quant à lui accès à tout le débit de la RAM système. De plus, le partage du débit n'est pas chose facile. Les deux se marchent sur les pieds. La carte graphique doit parfois attendre que le processeur lui laisse l'accès à la RAM et inversement. Divers circuits d'arbitrage s'occupent de répartir équitablement les accès à RAM entre les deux, mais cela ne permet que d'avoir un compromis imparfait qui peut réduire les performances. Le seul moyen pour réduire la casse est d'ajouter des mémoires caches entre le GPU et la RAM, mais l'efficacité des caches est relativement limitée pour le rendu 3D. [[File:Echanges de données entre CPU et GPU avec une mémoire unifiée.png|centre|vignette|upright=2|Échanges de données entre CPU et GPU avec une mémoire unifiée]] Un autre défaut survient sur les cartes dédiées à mémoire unifiée, par exemple l'Intel 740. Pour lire en mémoire RAM, elles doivent passer par l'intermédiaire du bus AGP, PCI ou PCI-Express. Et ce bus est très lent, bien plus que ne le serait une mémoire vidéo normale. Aussi, les performances sont exécrables. J'insiste sur le fait que l'on parle des cartes graphiques dédiées, mais pas des cartes graphiques soudées des consoles de jeu. D'ailleurs, de telles cartes dédiées incorporent un ''framebuffer'' directement dans la carte graphique. Il n'y a pas le choix, le VDC de la carte graphique doit accéder à une mémoire suffisamment rapide pour alimenter l'écran. Ils ne peuvent pas prendre le risque d'aller lire la RAM, dont le temps de latence est élevé, et qui peut potentiellement être réservée par le processeur pendant l’affichage d'une image à l'écran. ===Avec une mémoire vidéo dédiée=== Avec une mémoire vidéo dédiée, on doit copier les données adéquates dans la mémoire vidéo, ce qui implique des transferts de données passant par le bus PCI-Express. Le processeur voit une partie de la mémoire vidéo, dans laquelle il peut lire ou écrire comme bon lui semble. Le reste de la mémoire vidéo est invisible du point de vue du processeur, mais manipulable par le GPU à sa guise. Il est possible pour le CPU de copier des données dans la portion invisible de la mémoire vidéo, mais cela se fait de manière indirecte en passant par le GPU d'abord. Il faut typiquement envoyer une commande spéciale au GPU, pour lui dire de charger une texture en mémoire vidéo, par exemple. Le GPU effectue alors une copie de la mémoire système vers la mémoire vidéo, en utilisant un contrôleur DMA intégré au GPU. [[File:Interaction du GPU avec la mémoire vidéo et la RAM système sur une carte graphique dédiée.png|centre|vignette|upright=2|Échanges de données entre CPU et GPU avec une mémoire vidéo dédiée]] La gestion de la mémoire vidéo est prise en charge par le pilote de la carte graphique, sur le processeur. Elle a tendance à allouer les textures et d'autres données de grande taille dans la mémoire vidéo invisible, le reste étant placé ailleurs. Les copies DMA vers la mémoire vidéo invisible sont adaptées à des copies de grosses données comme les textures, mais elles marchent mal pour des données assez petites. Or, les jeux vidéos ont tendance à générer à la volée de nombreuses données de petite taille, qu'il faut copier en mémoire vidéo. Et c'est sans compter sur des ressources du pilote de périphériques, qui doivent être copiées en mémoire vidéo, comme le tampon de commande ou d'autres ressources. Et celles-ci ne peuvent pas forcément être copiées dans la mémoire vidéo invisible. Si la mémoire vidéo visible par le CPU est trop petite, les données précédentes sont copiées dans la mémoire visible par le CPU, en mémoire système, mais leur accès par le GPU est alors très lent. Aussi, plus la portion visible de la mémoire vidéo est grande, plus simple est la gestion de la mémoire vidéo par le pilote graphique. Et de ce point de vue, les choses ont évolué récemment. Pour accéder à un périphérique PCI-Express, il faut configurer des registres spécialisés, appelés les ''Base Address Registers'' (BARs). La configuration des registres précise quelle portion de mémoire vidéo est adressable par le processeur, quelle est sa taille, sa position en mémoire vidéo, etc. Avant 2008, les BAR permettaient d’accéder à seulement 256 mégaoctets, pas plus. La gestion de la mémoire vidéo était alors difficile. Les échanges entre portion visible et invisible de la mémoire vidéo étaient complexes, demandaient d’exécuter des commandes spécifiques au GPU et autres. Après 2008, la spécification du PCI-Express ajouta un support de la technologie ''resizable bar'', qui permet au processeur d’accéder directement à plus de 256 mégaoctets de mémoire vidéo, voire à la totalité de la mémoire vidéo. De nombreux fabricants de cartes graphiques commencent à incorporer cette technologie, qui demande quelques changements au niveau du système d'exploitation, des pilotes de périphériques et du matériel. {{NavChapitre | book=Les cartes graphiques | prev=La microarchitecture des processeurs de shaders | prevText=La microarchitecture des processeurs de shaders | next=La hiérarchie mémoire d'un GPU | netxText=La hiérarchie mémoire d'un GPU }}{{autocat}} 2wd36e573lnpf01ki229alhtbj59hvc 744052 744045 2025-06-03T16:46:51Z Mewtow 31375 /* La IO-Memory Management Unit (IOMMU) */ 744052 wikitext text/x-wiki Pour rappel, il existe deux types de cartes graphiques : les cartes dédiées et les cartes intégrées. Les '''cartes graphiques dédiées''' sont des cartes graphiques branchées sur des connecteurs/ports de la carte mère. A l'opposé, tous les processeurs modernes intègrent une carte graphique, appelée '''carte graphique intégrée''', ou encore '''IGP''' (''Integrated Graphic Processor''). En somme, les cartes dédiées sont opposées à celles intégrées dans les processeurs modernes. La différence a un impact sur la mémoire vidéo. Les cartes graphiques dédiées ont souvent de la mémoire vidéo intégrée à la carte graphique. Il y a des exceptions, mais on en parlera plus tard. Les cartes graphiques intégrées au processeur n'ont pas de mémoire vidéo dédiée, vu qu'on ne peut pas intégrer beaucoup de mémoire vidéo dans un processeur. La conséquence est qu'il existe deux grandes manières d'organiser la mémoire à laquelle la carte graphique a accès. * La première est celle de la '''mémoire vidéo dédiée''', à savoir que la carte graphique dispose de sa propre mémoire rien qu'à elle, séparée de la mémoire RAM de l'ordinateur. On fait alors la distinction entre ''RAM système'' et ''RAM vidéo''. Si les premières cartes graphiques n'avaient que quelques mégaoctets de RAM dédiée, elles disposent actuellement de plusieurs gigas-octets de RAM. * A l'opposé, on trouve la '''mémoire unifiée''', avec une seule mémoire RAM est partagée entre le processeur et la carte graphique. Le terme "unifiée" sous-entend que l'on a unifié la mémoire vidéo et la mémoire système (la RAM). [[File:Répartition de la mémoire entre RAM système et carte graphique.png|centre|vignette|upright=2.5|Répartition de la mémoire entre RAM système et carte graphique]] Dans la grosse majorité des cas, les cartes vidéos dédiées ont une mémoire dédiée, alors que les cartes graphiques intégrées doivent utiliser la mémoire unifiée. Mais outre les cartes dédiées et intégrées, il faut aussi citer les cartes graphiques soudées sur la carte mère. Elles étaient utilisées sur les consoles de jeu vidéos assez anciennes, elles sont encore utilisées sur certains PC portables puissants, destinés aux ''gamers''. Pour ces dernières, il est possible d'utiliser aussi bien de la mémoire dédiée que de la mémoire unifiée. D'anciennes consoles de jeu avaient une carte graphique soudée sur la carte mère, qu'on peut facilement repérer à l’œil nu, avec une mémoire unifiée. C'est notamment le cas sur la Nintendo 64, pour ne citer qu'elle. D'autres avaient leur propre mémoire vidéo dédiée. L'usage d'une carte vidéo dédiée se marie très bien avec une mémoire vidéo dédiée, mais il existe de nombreux cas où une carte vidéo dédiée est associée à de la mémoire unifiée. Comme exemple, la toute première carte graphique AGP, l'Intel 740, ne possédait pas de mémoire vidéo proprement dite, juste un simple ''framebuffer''. Tout le reste, texture comme géométrie, était placé en mémoire système et la carte graphique allait lire/écrire les données directement en mémoire RAM système ! Les performances sont généralement ridicules, pour des raisons très diverses, mais les cartes de ce type sont peu chères. Outre l'économie liée à l'absence de mémoire vidéo, les cartes graphiques de ce type sont peu puissantes, l'usage de la mémoire unifiée simplifie leur conception, etc. Par exemple, l'Intel 740 a eu un petit succès sur les ordinateurs d'entrée de gamme. ==Le partage de la mémoire unifiée== Avec la mémoire unifiée, la quantité de mémoire système disponible pour la carte graphique est généralement réglable avec un réglage dans le BIOS. On peut ainsi choisir d'allouer 64, 128 ou 256 mégaoctets de mémoire système pour la carte vidéo, sur un ordinateur avec 4 gigaoctets de RAM. L'interprétation de ce réglage varie grandement selon les cartes mères ou l'IGP. Pour les GPU les plus anciens, ce réglage implique que la RAM sélectionnée est réservée uniquement à la carte graphique, même si elle n'en utilise qu'une partie. La répartition entre mémoire vidéo et système est alors statique, fixée une fois pour toutes. Dans ce cas, la RAM allouée à la carte graphique est généralement petite par défaut. Les concepteurs de carte mère ne veulent pas qu'une trop quantité de RAM soit perdu et inutilisable pour les applications. Ils brident donc la carte vidéo et ne lui allouent que peu de RAM. Heureusement, les GPU modernes sont plus souples. Ils fournissent deux réglages : une quantité de RAM minimale, totalement dédiée au GPU, et une quantité de RAM maximale que le GPU ne peut pas dépasser. Par exemple, il est possible de régler le GPU de manière à ce qu'il ait 64 mégaoctets rien que pour lui, mais qu'il puisse avoir accès à maximum 1 gigaoctet s'il en a besoin. Cela fait au total 960 mégaoctets (1024-64) qui peut être alloués au choix à la carte graphique ou au reste des programmes en cours d’exécution, selon les besoins. Il est possible d'allouer de grandes quantités de RAM au GPU, parfois la totalité de la mémoire système. [[File:Partage de la mémoire unifiée entre CPU et GPU.png|centre|vignette|upright=2|Répartition de la mémoire entre RAM système et carte graphique]] ==Le partage de la mémoire système : la mémoire virtuelle des GPUs dédiés== Après avoir vu la mémoire unifiée, voyons maintenant la mémoire dédiée. Intuitivement, on se dit que la carte graphique n'a accès qu'à la mémoire vidéo dédiée et ne peut pas lire de données dans la mémoire système, la RAM de l'ordinateur. Cependant, ce n'est pas le cas. Et ce pour plusieurs raisons. La raison principale est que des données doivent être copiées de la mémoire RAM vers la mémoire vidéo. Les copies en question se font souvent via ''Direct Memory Access'', ce qui fait que les GPU intègrent un contrôleur DMA dédié. Et ce contrôleur DMA lit des données en RAM système pour les copier en RAM vidéo. La seconde raison est que les cartes graphiques intègrent presque toutes des technologies pour lire directement des données en RAM, sans forcément les copier en mémoire vidéo. Les technologies en question permettent à la carte graphique d'adresser plus de RAM qu'en a la mémoire vidéo. Par exemple, si la carte vidéo a 4 giga-octets de RAM, la carte graphique peut être capable d'en adresser 8 : 4 gigas en RAM vidéo, et 4 autres gigas en RAM système. Les technologies de ce genre ressemblent beaucoup à la mémoire virtuelle des CPU, avec cependant quelques différences. La mémoire virtuelle permet à un processeur d'utiliser plus de RAM qu'il n'y en a d'installée dans l'ordinateur. Par exemple, elle permet au CPU de gérer 4 gigas de RAM sur un ordinateur qui n'en contient que trois, le gigaoctet de trop étant en réalité simulé par un fichier sur le disque dur. La technique est utilisée par tous les processeurs modernes. La mémoire virtuelle des GPUs dédiés fait la même chose, sauf que le surplus d'adresses n'est pas stockés sur le disque dur dans un fichier pagefile, mais est dans la RAM système. Pour le dire autrement, ces cartes dédiées peuvent utiliser la mémoire système si jamais la mémoire vidéo est pleine. [[File:Mémoire virtuelle des cartes graphiques dédiées.png|centre|vignette|upright=2|Mémoire virtuelle des cartes graphiques dédiées]] L'espace d'adressage est l'ensemble des adresses géré par le processeur ou la carte graphique. En théorie, l'espace d'adressage du processeur et de la carte graphique sont séparés, mais des standards comme l''''''Heterogeneous System Architecture''''' permettent au processeur et à une carte graphique de partager le même espace d'adressage. Une adresse mémoire est alors la même que ce soit pour le processeur ou la carte graphique. {|class="wikitable" |- ! !! Mémoire vidéo dédiée !! Mémoire vidéo unifiée |- ! Sans HSA | [[File:Desktop computer bus bandwidths.svg|400px|Desktop computer bus bandwidths]] | [[File:Integrated graphics with distinct memory allocation.svg|400px|Integrated graphics with distinct memory allocation]] |- ! Avec HSA | [[File:HSA-enabled virtual memory with distinct graphics card.svg|400px|HSA-enabled virtual memory with distinct graphics card]] | [[File:HSA-enabled integrated graphics.svg|400px|HSA-enabled integrated graphics]] |} ===La ''IO-Memory Management Unit'' (IOMMU)=== Pour que la carte graphique ait accès à la mémoire système, elle intègre un circuit appelé la '''''Graphics address remapping table''''', abrévié en GART. Cela vaut aussi bien pour les cartes graphiques utilisant le bus AGP que pour celles en PCI-Express. La GART est techniquement une une ''Memory Management Unit'' (MMU), à savoir un circuit spécialisé qui prend en charge la mémoire virtuelle. La dite MMU étant intégrée dans un périphérique d'entrée-sortie (IO), ici la carte graphique, elle est appelée une IO-MMU (''Input Output-MMU''). Le GPU utilise la technique dite de la pagination, à savoir que l'espace d'adressage est découpée en pages de taille fixe, généralement 4 kilo-octets. La traduction des adresses virtuelles en adresses physique se fait au niveau de la page. Une adresse est coupée en deux parts : un numéro de page, et la position de la donnée dans la page. La position dans la page ne change pas lors de la traduction d'adresse, mais le numéro de page est lui traduit. Le numéro de page virtuel est remplacé par un numéro de page physique lors de la traduction. Pour remplacer le numéro de page virtuel en numéro physique, il faut utiliser une table de translation, appelée la '''table des pages''', qui associe un numéro de page logique à un numéro de page physique. Le système d'exploitation dispose de sa table des pages, qui n'est pas accesible au GPU. Par contre, le GPU dispose d'une sorte de mini-table des pages, qui contient les associations page virtuelle-physique utiles pour traiter les commandes GPU, et rien d'autre. En clair, une sorte de sous-ensemble de la table des pages de l'OS, mais spécifique au GPU. La mini-table des pages est gérée par le pilote de périphérique, qui remplit la mini-table des pages. La mini-table des pages est mémorisée dans une mémoire intégrée au GPU, et précisément dans la MMU. ===Historique de la mémoire virtuelle sur les GPU=== La technologie existait déjà sur certaines cartes graphiques au format PCI, mais la documentation est assez rare. La carte graphique NV1 de NVIDIA, leur toute première carte graphique, disposait déjà de ce système de mémoire virtuelle. La carte graphique communiquait avec le processeur grâce à la fonctionnalité ''Direct Memory Access'' et intégrait donc un contrôleur DMA. Le ''driver'' de la carte graphique programmait le contrôleur DMA en utilisant les adresses fournies par les applications/logiciels. Et il s'agissait d'adresses virtuelles, non d'adresses physiques en mémoire RAM. Pour résoudre ce problème, le contrôleur DMA intégrait une MMU, une unité de traduction d'adresse, qui traduisait les adresses virtuelles fournies par les applications en adresse physique en mémoire système. : Le fonctionnement de cette IOMMU est décrite dans le brevet "US5758182A : DMA controller translates virtual I/O device address received directly from application program command to physical i/o device address of I/O device on device bus", des inventeurs David S. H. Rosenthal et Curtis Priem. [[File:Microarchitecture du GPU NV1 de NVIDIA.png|centre|vignette|upright=2|Microarchitecture du GPU NV1 de NVIDIA]] La technologie s'est démocratisée avec le bus AGP, dont la fonctionnalité dite d'''AGP texturing'' permettait de lire ou écrire directement dans la mémoire RAM, sans passer par le processeur. D'ailleurs, la carte graphique Intel i740 n'avait pas de mémoire vidéo et se débrouillait uniquement avec la mémoire système. L'arrivée du bus PCI-Express ne changea pas la donne, si ce n'est que le bus était plus rapide, ce qui améliorait les performances. Au début, seules les cartes graphiques PCI-Express d'entrée de gamme pouvaient accéder à certaines portions de la mémoire RAM grâce à des technologies adaptées, comme le TurboCache de NVIDIA ou l'HyperMemory d'AMD. Mais la technologie s'est aujourd'hui étendue. De nos jours, toutes les cartes vidéos modernes utilisent la RAM système en plus de la mémoire vidéo, mais seulement en dernier recours, soit quand la mémoire vidéo est quasiment pleine, soit pour faciliter les échanges de données avec le processeur. C'est typiquement le pilote de la carte graphique qui décide ce qui va dans la mémoire vidéo et la mémoire système, et il fait au mieux de manière à avoir les performances optimales. ==Les échanges entre processeur et mémoire vidéo== Quand on charge un niveau de jeux vidéo, on doit notamment charger la scène, les textures, et d'autres choses dans la mémoire RAM, puis les envoyer à la carte graphique. Ce processus se fait d'une manière fortement différente selon que l'on a une mémoire unifiée ou une mémoire vidéo dédiée. ===Avec la mémoire unifiée=== Avec la mémoire unifié, les échanges de données entre processeur et carte graphique sont fortement simplifiés et aucune copie n'est nécessaire. La carte vidéo peut y accéder directement, en lisant leur position initiale en RAM. Une partie de la RAM est visible seulement pour le CPU, une autre seulement pour le GPU, le reste est partagé. Les échanges de données entre CPU et GPU se font en écrivant/lisant des données dans la RAM partagée entre CPU et GPU. Pas besoin de faire de copie d'une mémoire à une autre : la donnée a juste besoin d'être placée au bon endroit. Le chargement des textures, du tampon de commandes ou d'autres données du genre, est donc très rapide, presque instantané. Par contre, le débit de la RAM unifiée est partagé entre la carte graphique et le processeur. Alors qu'avec une mémoire dédiée, tout le débit de la mémoire vidéo aurait été dédié au GPU, le CPU ayant quant à lui accès à tout le débit de la RAM système. De plus, le partage du débit n'est pas chose facile. Les deux se marchent sur les pieds. La carte graphique doit parfois attendre que le processeur lui laisse l'accès à la RAM et inversement. Divers circuits d'arbitrage s'occupent de répartir équitablement les accès à RAM entre les deux, mais cela ne permet que d'avoir un compromis imparfait qui peut réduire les performances. Le seul moyen pour réduire la casse est d'ajouter des mémoires caches entre le GPU et la RAM, mais l'efficacité des caches est relativement limitée pour le rendu 3D. [[File:Echanges de données entre CPU et GPU avec une mémoire unifiée.png|centre|vignette|upright=2|Échanges de données entre CPU et GPU avec une mémoire unifiée]] Un autre défaut survient sur les cartes dédiées à mémoire unifiée, par exemple l'Intel 740. Pour lire en mémoire RAM, elles doivent passer par l'intermédiaire du bus AGP, PCI ou PCI-Express. Et ce bus est très lent, bien plus que ne le serait une mémoire vidéo normale. Aussi, les performances sont exécrables. J'insiste sur le fait que l'on parle des cartes graphiques dédiées, mais pas des cartes graphiques soudées des consoles de jeu. D'ailleurs, de telles cartes dédiées incorporent un ''framebuffer'' directement dans la carte graphique. Il n'y a pas le choix, le VDC de la carte graphique doit accéder à une mémoire suffisamment rapide pour alimenter l'écran. Ils ne peuvent pas prendre le risque d'aller lire la RAM, dont le temps de latence est élevé, et qui peut potentiellement être réservée par le processeur pendant l’affichage d'une image à l'écran. ===Avec une mémoire vidéo dédiée=== Avec une mémoire vidéo dédiée, on doit copier les données adéquates dans la mémoire vidéo, ce qui implique des transferts de données passant par le bus PCI-Express. Le processeur voit une partie de la mémoire vidéo, dans laquelle il peut lire ou écrire comme bon lui semble. Le reste de la mémoire vidéo est invisible du point de vue du processeur, mais manipulable par le GPU à sa guise. Il est possible pour le CPU de copier des données dans la portion invisible de la mémoire vidéo, mais cela se fait de manière indirecte en passant par le GPU d'abord. Il faut typiquement envoyer une commande spéciale au GPU, pour lui dire de charger une texture en mémoire vidéo, par exemple. Le GPU effectue alors une copie de la mémoire système vers la mémoire vidéo, en utilisant un contrôleur DMA intégré au GPU. [[File:Interaction du GPU avec la mémoire vidéo et la RAM système sur une carte graphique dédiée.png|centre|vignette|upright=2|Échanges de données entre CPU et GPU avec une mémoire vidéo dédiée]] La gestion de la mémoire vidéo est prise en charge par le pilote de la carte graphique, sur le processeur. Elle a tendance à allouer les textures et d'autres données de grande taille dans la mémoire vidéo invisible, le reste étant placé ailleurs. Les copies DMA vers la mémoire vidéo invisible sont adaptées à des copies de grosses données comme les textures, mais elles marchent mal pour des données assez petites. Or, les jeux vidéos ont tendance à générer à la volée de nombreuses données de petite taille, qu'il faut copier en mémoire vidéo. Et c'est sans compter sur des ressources du pilote de périphériques, qui doivent être copiées en mémoire vidéo, comme le tampon de commande ou d'autres ressources. Et celles-ci ne peuvent pas forcément être copiées dans la mémoire vidéo invisible. Si la mémoire vidéo visible par le CPU est trop petite, les données précédentes sont copiées dans la mémoire visible par le CPU, en mémoire système, mais leur accès par le GPU est alors très lent. Aussi, plus la portion visible de la mémoire vidéo est grande, plus simple est la gestion de la mémoire vidéo par le pilote graphique. Et de ce point de vue, les choses ont évolué récemment. Pour accéder à un périphérique PCI-Express, il faut configurer des registres spécialisés, appelés les ''Base Address Registers'' (BARs). La configuration des registres précise quelle portion de mémoire vidéo est adressable par le processeur, quelle est sa taille, sa position en mémoire vidéo, etc. Avant 2008, les BAR permettaient d’accéder à seulement 256 mégaoctets, pas plus. La gestion de la mémoire vidéo était alors difficile. Les échanges entre portion visible et invisible de la mémoire vidéo étaient complexes, demandaient d’exécuter des commandes spécifiques au GPU et autres. Après 2008, la spécification du PCI-Express ajouta un support de la technologie ''resizable bar'', qui permet au processeur d’accéder directement à plus de 256 mégaoctets de mémoire vidéo, voire à la totalité de la mémoire vidéo. De nombreux fabricants de cartes graphiques commencent à incorporer cette technologie, qui demande quelques changements au niveau du système d'exploitation, des pilotes de périphériques et du matériel. {{NavChapitre | book=Les cartes graphiques | prev=La microarchitecture des processeurs de shaders | prevText=La microarchitecture des processeurs de shaders | next=La hiérarchie mémoire d'un GPU | netxText=La hiérarchie mémoire d'un GPU }}{{autocat}} kn4j3nom9b44fo6mwhk1bq3e5ir25ny 744053 744052 2025-06-03T16:53:10Z Mewtow 31375 /* Le partage de la mémoire système : la mémoire virtuelle des GPUs dédiés */ 744053 wikitext text/x-wiki Pour rappel, il existe deux types de cartes graphiques : les cartes dédiées et les cartes intégrées. Les '''cartes graphiques dédiées''' sont des cartes graphiques branchées sur des connecteurs/ports de la carte mère. A l'opposé, tous les processeurs modernes intègrent une carte graphique, appelée '''carte graphique intégrée''', ou encore '''IGP''' (''Integrated Graphic Processor''). En somme, les cartes dédiées sont opposées à celles intégrées dans les processeurs modernes. La différence a un impact sur la mémoire vidéo. Les cartes graphiques dédiées ont souvent de la mémoire vidéo intégrée à la carte graphique. Il y a des exceptions, mais on en parlera plus tard. Les cartes graphiques intégrées au processeur n'ont pas de mémoire vidéo dédiée, vu qu'on ne peut pas intégrer beaucoup de mémoire vidéo dans un processeur. La conséquence est qu'il existe deux grandes manières d'organiser la mémoire à laquelle la carte graphique a accès. * La première est celle de la '''mémoire vidéo dédiée''', à savoir que la carte graphique dispose de sa propre mémoire rien qu'à elle, séparée de la mémoire RAM de l'ordinateur. On fait alors la distinction entre ''RAM système'' et ''RAM vidéo''. Si les premières cartes graphiques n'avaient que quelques mégaoctets de RAM dédiée, elles disposent actuellement de plusieurs gigas-octets de RAM. * A l'opposé, on trouve la '''mémoire unifiée''', avec une seule mémoire RAM est partagée entre le processeur et la carte graphique. Le terme "unifiée" sous-entend que l'on a unifié la mémoire vidéo et la mémoire système (la RAM). [[File:Répartition de la mémoire entre RAM système et carte graphique.png|centre|vignette|upright=2.5|Répartition de la mémoire entre RAM système et carte graphique]] Dans la grosse majorité des cas, les cartes vidéos dédiées ont une mémoire dédiée, alors que les cartes graphiques intégrées doivent utiliser la mémoire unifiée. Mais outre les cartes dédiées et intégrées, il faut aussi citer les cartes graphiques soudées sur la carte mère. Elles étaient utilisées sur les consoles de jeu vidéos assez anciennes, elles sont encore utilisées sur certains PC portables puissants, destinés aux ''gamers''. Pour ces dernières, il est possible d'utiliser aussi bien de la mémoire dédiée que de la mémoire unifiée. D'anciennes consoles de jeu avaient une carte graphique soudée sur la carte mère, qu'on peut facilement repérer à l’œil nu, avec une mémoire unifiée. C'est notamment le cas sur la Nintendo 64, pour ne citer qu'elle. D'autres avaient leur propre mémoire vidéo dédiée. L'usage d'une carte vidéo dédiée se marie très bien avec une mémoire vidéo dédiée, mais il existe de nombreux cas où une carte vidéo dédiée est associée à de la mémoire unifiée. Comme exemple, la toute première carte graphique AGP, l'Intel 740, ne possédait pas de mémoire vidéo proprement dite, juste un simple ''framebuffer''. Tout le reste, texture comme géométrie, était placé en mémoire système et la carte graphique allait lire/écrire les données directement en mémoire RAM système ! Les performances sont généralement ridicules, pour des raisons très diverses, mais les cartes de ce type sont peu chères. Outre l'économie liée à l'absence de mémoire vidéo, les cartes graphiques de ce type sont peu puissantes, l'usage de la mémoire unifiée simplifie leur conception, etc. Par exemple, l'Intel 740 a eu un petit succès sur les ordinateurs d'entrée de gamme. ==Le partage de la mémoire unifiée== Avec la mémoire unifiée, la quantité de mémoire système disponible pour la carte graphique est généralement réglable avec un réglage dans le BIOS. On peut ainsi choisir d'allouer 64, 128 ou 256 mégaoctets de mémoire système pour la carte vidéo, sur un ordinateur avec 4 gigaoctets de RAM. L'interprétation de ce réglage varie grandement selon les cartes mères ou l'IGP. Pour les GPU les plus anciens, ce réglage implique que la RAM sélectionnée est réservée uniquement à la carte graphique, même si elle n'en utilise qu'une partie. La répartition entre mémoire vidéo et système est alors statique, fixée une fois pour toutes. Dans ce cas, la RAM allouée à la carte graphique est généralement petite par défaut. Les concepteurs de carte mère ne veulent pas qu'une trop quantité de RAM soit perdu et inutilisable pour les applications. Ils brident donc la carte vidéo et ne lui allouent que peu de RAM. Heureusement, les GPU modernes sont plus souples. Ils fournissent deux réglages : une quantité de RAM minimale, totalement dédiée au GPU, et une quantité de RAM maximale que le GPU ne peut pas dépasser. Par exemple, il est possible de régler le GPU de manière à ce qu'il ait 64 mégaoctets rien que pour lui, mais qu'il puisse avoir accès à maximum 1 gigaoctet s'il en a besoin. Cela fait au total 960 mégaoctets (1024-64) qui peut être alloués au choix à la carte graphique ou au reste des programmes en cours d’exécution, selon les besoins. Il est possible d'allouer de grandes quantités de RAM au GPU, parfois la totalité de la mémoire système. [[File:Partage de la mémoire unifiée entre CPU et GPU.png|centre|vignette|upright=2|Répartition de la mémoire entre RAM système et carte graphique]] ==Le partage de la mémoire système : la mémoire virtuelle des GPUs dédiés== Après avoir vu la mémoire unifiée, voyons maintenant la mémoire dédiée. Intuitivement, on se dit que la carte graphique n'a accès qu'à la mémoire vidéo dédiée et ne peut pas lire de données dans la mémoire système, la RAM de l'ordinateur. Cependant, ce n'est pas le cas. Et ce pour plusieurs raisons. La raison principale est que des données doivent être copiées de la mémoire RAM vers la mémoire vidéo. Les copies en question se font souvent via ''Direct Memory Access'', ce qui fait que les GPU intègrent un contrôleur DMA dédié. Et ce contrôleur DMA lit des données en RAM système pour les copier en RAM vidéo. La seconde raison est que les cartes graphiques intègrent presque toutes des technologies pour lire directement des données en RAM, sans forcément les copier en mémoire vidéo. Les technologies en question permettent à la carte graphique d'adresser plus de RAM qu'en a la mémoire vidéo. Par exemple, si la carte vidéo a 4 giga-octets de RAM, la carte graphique peut être capable d'en adresser 8 : 4 gigas en RAM vidéo, et 4 autres gigas en RAM système. Les technologies de ce genre ressemblent beaucoup à la mémoire virtuelle des CPU, avec cependant quelques différences. La mémoire virtuelle permet à un processeur d'utiliser plus de RAM qu'il n'y en a d'installée dans l'ordinateur. Par exemple, elle permet au CPU de gérer 4 gigas de RAM sur un ordinateur qui n'en contient que trois, le gigaoctet de trop étant en réalité simulé par un fichier sur le disque dur. La technique est utilisée par tous les processeurs modernes. La mémoire virtuelle des GPUs dédiés fait la même chose, sauf que le surplus d'adresses n'est pas stockés sur le disque dur dans un fichier pagefile, mais est dans la RAM système. Pour le dire autrement, ces cartes dédiées peuvent utiliser la mémoire système si jamais la mémoire vidéo est pleine. [[File:Mémoire virtuelle des cartes graphiques dédiées.png|centre|vignette|upright=2|Mémoire virtuelle des cartes graphiques dédiées]] ===La ''IO-Memory Management Unit'' (IOMMU)=== Pour que la carte graphique ait accès à la mémoire système, elle intègre un circuit appelé la '''''Graphics address remapping table''''', abrévié en GART. Cela vaut aussi bien pour les cartes graphiques utilisant le bus AGP que pour celles en PCI-Express. La GART est techniquement une une ''Memory Management Unit'' (MMU), à savoir un circuit spécialisé qui prend en charge la mémoire virtuelle. La dite MMU étant intégrée dans un périphérique d'entrée-sortie (IO), ici la carte graphique, elle est appelée une IO-MMU (''Input Output-MMU''). Le GPU utilise la technique dite de la pagination, à savoir que l'espace d'adressage est découpée en pages de taille fixe, généralement 4 kilo-octets. La traduction des adresses virtuelles en adresses physique se fait au niveau de la page. Une adresse est coupée en deux parts : un numéro de page, et la position de la donnée dans la page. La position dans la page ne change pas lors de la traduction d'adresse, mais le numéro de page est lui traduit. Le numéro de page virtuel est remplacé par un numéro de page physique lors de la traduction. Pour remplacer le numéro de page virtuel en numéro physique, il faut utiliser une table de translation, appelée la '''table des pages''', qui associe un numéro de page logique à un numéro de page physique. Le système d'exploitation dispose de sa table des pages, qui n'est pas accesible au GPU. Par contre, le GPU dispose d'une sorte de mini-table des pages, qui contient les associations page virtuelle-physique utiles pour traiter les commandes GPU, et rien d'autre. En clair, une sorte de sous-ensemble de la table des pages de l'OS, mais spécifique au GPU. La mini-table des pages est gérée par le pilote de périphérique, qui remplit la mini-table des pages. La mini-table des pages est mémorisée dans une mémoire intégrée au GPU, et précisément dans la MMU. ===Historique de la mémoire virtuelle sur les GPU=== La technologie existait déjà sur certaines cartes graphiques au format PCI, mais la documentation est assez rare. La carte graphique NV1 de NVIDIA, leur toute première carte graphique, disposait déjà de ce système de mémoire virtuelle. La carte graphique communiquait avec le processeur grâce à la fonctionnalité ''Direct Memory Access'' et intégrait donc un contrôleur DMA. Le ''driver'' de la carte graphique programmait le contrôleur DMA en utilisant les adresses fournies par les applications/logiciels. Et il s'agissait d'adresses virtuelles, non d'adresses physiques en mémoire RAM. Pour résoudre ce problème, le contrôleur DMA intégrait une MMU, une unité de traduction d'adresse, qui traduisait les adresses virtuelles fournies par les applications en adresse physique en mémoire système. : Le fonctionnement de cette IOMMU est décrite dans le brevet "US5758182A : DMA controller translates virtual I/O device address received directly from application program command to physical i/o device address of I/O device on device bus", des inventeurs David S. H. Rosenthal et Curtis Priem. [[File:Microarchitecture du GPU NV1 de NVIDIA.png|centre|vignette|upright=2|Microarchitecture du GPU NV1 de NVIDIA]] La technologie s'est démocratisée avec le bus AGP, dont la fonctionnalité dite d'''AGP texturing'' permettait de lire ou écrire directement dans la mémoire RAM, sans passer par le processeur. D'ailleurs, la carte graphique Intel i740 n'avait pas de mémoire vidéo et se débrouillait uniquement avec la mémoire système. L'arrivée du bus PCI-Express ne changea pas la donne, si ce n'est que le bus était plus rapide, ce qui améliorait les performances. Au début, seules les cartes graphiques PCI-Express d'entrée de gamme pouvaient accéder à certaines portions de la mémoire RAM grâce à des technologies adaptées, comme le TurboCache de NVIDIA ou l'HyperMemory d'AMD. Mais la technologie s'est aujourd'hui étendue. De nos jours, toutes les cartes vidéos modernes utilisent la RAM système en plus de la mémoire vidéo, mais seulement en dernier recours, soit quand la mémoire vidéo est quasiment pleine, soit pour faciliter les échanges de données avec le processeur. C'est typiquement le pilote de la carte graphique qui décide ce qui va dans la mémoire vidéo et la mémoire système, et il fait au mieux de manière à avoir les performances optimales. ===L'espace d'adressage du CPU et du GPU=== L'espace d'adressage est l'ensemble des adresses géré par le processeur ou la carte graphique. En théorie, l'espace d'adressage du processeur et de la carte graphique sont séparés, mais des standards comme l''''''Heterogeneous System Architecture''''' permettent au processeur et à une carte graphique de partager le même espace d'adressage. Une adresse mémoire est alors la même que ce soit pour le processeur ou la carte graphique. {|class="wikitable" |- ! !! Mémoire vidéo dédiée !! Mémoire vidéo unifiée |- ! Sans HSA | [[File:Desktop computer bus bandwidths.svg|400px|Desktop computer bus bandwidths]] | [[File:Integrated graphics with distinct memory allocation.svg|400px|Integrated graphics with distinct memory allocation]] |- ! Avec HSA | [[File:HSA-enabled virtual memory with distinct graphics card.svg|400px|HSA-enabled virtual memory with distinct graphics card]] | [[File:HSA-enabled integrated graphics.svg|400px|HSA-enabled integrated graphics]] |} ==Les échanges entre processeur et mémoire vidéo== Quand on charge un niveau de jeux vidéo, on doit notamment charger la scène, les textures, et d'autres choses dans la mémoire RAM, puis les envoyer à la carte graphique. Ce processus se fait d'une manière fortement différente selon que l'on a une mémoire unifiée ou une mémoire vidéo dédiée. ===Avec la mémoire unifiée=== Avec la mémoire unifié, les échanges de données entre processeur et carte graphique sont fortement simplifiés et aucune copie n'est nécessaire. La carte vidéo peut y accéder directement, en lisant leur position initiale en RAM. Une partie de la RAM est visible seulement pour le CPU, une autre seulement pour le GPU, le reste est partagé. Les échanges de données entre CPU et GPU se font en écrivant/lisant des données dans la RAM partagée entre CPU et GPU. Pas besoin de faire de copie d'une mémoire à une autre : la donnée a juste besoin d'être placée au bon endroit. Le chargement des textures, du tampon de commandes ou d'autres données du genre, est donc très rapide, presque instantané. Par contre, le débit de la RAM unifiée est partagé entre la carte graphique et le processeur. Alors qu'avec une mémoire dédiée, tout le débit de la mémoire vidéo aurait été dédié au GPU, le CPU ayant quant à lui accès à tout le débit de la RAM système. De plus, le partage du débit n'est pas chose facile. Les deux se marchent sur les pieds. La carte graphique doit parfois attendre que le processeur lui laisse l'accès à la RAM et inversement. Divers circuits d'arbitrage s'occupent de répartir équitablement les accès à RAM entre les deux, mais cela ne permet que d'avoir un compromis imparfait qui peut réduire les performances. Le seul moyen pour réduire la casse est d'ajouter des mémoires caches entre le GPU et la RAM, mais l'efficacité des caches est relativement limitée pour le rendu 3D. [[File:Echanges de données entre CPU et GPU avec une mémoire unifiée.png|centre|vignette|upright=2|Échanges de données entre CPU et GPU avec une mémoire unifiée]] Un autre défaut survient sur les cartes dédiées à mémoire unifiée, par exemple l'Intel 740. Pour lire en mémoire RAM, elles doivent passer par l'intermédiaire du bus AGP, PCI ou PCI-Express. Et ce bus est très lent, bien plus que ne le serait une mémoire vidéo normale. Aussi, les performances sont exécrables. J'insiste sur le fait que l'on parle des cartes graphiques dédiées, mais pas des cartes graphiques soudées des consoles de jeu. D'ailleurs, de telles cartes dédiées incorporent un ''framebuffer'' directement dans la carte graphique. Il n'y a pas le choix, le VDC de la carte graphique doit accéder à une mémoire suffisamment rapide pour alimenter l'écran. Ils ne peuvent pas prendre le risque d'aller lire la RAM, dont le temps de latence est élevé, et qui peut potentiellement être réservée par le processeur pendant l’affichage d'une image à l'écran. ===Avec une mémoire vidéo dédiée=== Avec une mémoire vidéo dédiée, on doit copier les données adéquates dans la mémoire vidéo, ce qui implique des transferts de données passant par le bus PCI-Express. Le processeur voit une partie de la mémoire vidéo, dans laquelle il peut lire ou écrire comme bon lui semble. Le reste de la mémoire vidéo est invisible du point de vue du processeur, mais manipulable par le GPU à sa guise. Il est possible pour le CPU de copier des données dans la portion invisible de la mémoire vidéo, mais cela se fait de manière indirecte en passant par le GPU d'abord. Il faut typiquement envoyer une commande spéciale au GPU, pour lui dire de charger une texture en mémoire vidéo, par exemple. Le GPU effectue alors une copie de la mémoire système vers la mémoire vidéo, en utilisant un contrôleur DMA intégré au GPU. [[File:Interaction du GPU avec la mémoire vidéo et la RAM système sur une carte graphique dédiée.png|centre|vignette|upright=2|Échanges de données entre CPU et GPU avec une mémoire vidéo dédiée]] La gestion de la mémoire vidéo est prise en charge par le pilote de la carte graphique, sur le processeur. Elle a tendance à allouer les textures et d'autres données de grande taille dans la mémoire vidéo invisible, le reste étant placé ailleurs. Les copies DMA vers la mémoire vidéo invisible sont adaptées à des copies de grosses données comme les textures, mais elles marchent mal pour des données assez petites. Or, les jeux vidéos ont tendance à générer à la volée de nombreuses données de petite taille, qu'il faut copier en mémoire vidéo. Et c'est sans compter sur des ressources du pilote de périphériques, qui doivent être copiées en mémoire vidéo, comme le tampon de commande ou d'autres ressources. Et celles-ci ne peuvent pas forcément être copiées dans la mémoire vidéo invisible. Si la mémoire vidéo visible par le CPU est trop petite, les données précédentes sont copiées dans la mémoire visible par le CPU, en mémoire système, mais leur accès par le GPU est alors très lent. Aussi, plus la portion visible de la mémoire vidéo est grande, plus simple est la gestion de la mémoire vidéo par le pilote graphique. Et de ce point de vue, les choses ont évolué récemment. Pour accéder à un périphérique PCI-Express, il faut configurer des registres spécialisés, appelés les ''Base Address Registers'' (BARs). La configuration des registres précise quelle portion de mémoire vidéo est adressable par le processeur, quelle est sa taille, sa position en mémoire vidéo, etc. Avant 2008, les BAR permettaient d’accéder à seulement 256 mégaoctets, pas plus. La gestion de la mémoire vidéo était alors difficile. Les échanges entre portion visible et invisible de la mémoire vidéo étaient complexes, demandaient d’exécuter des commandes spécifiques au GPU et autres. Après 2008, la spécification du PCI-Express ajouta un support de la technologie ''resizable bar'', qui permet au processeur d’accéder directement à plus de 256 mégaoctets de mémoire vidéo, voire à la totalité de la mémoire vidéo. De nombreux fabricants de cartes graphiques commencent à incorporer cette technologie, qui demande quelques changements au niveau du système d'exploitation, des pilotes de périphériques et du matériel. {{NavChapitre | book=Les cartes graphiques | prev=La microarchitecture des processeurs de shaders | prevText=La microarchitecture des processeurs de shaders | next=La hiérarchie mémoire d'un GPU | netxText=La hiérarchie mémoire d'un GPU }}{{autocat}} 6d46u3cwhewt67t0pr004dexeoifz9m 744054 744053 2025-06-03T16:53:19Z Mewtow 31375 /* L'espace d'adressage du CPU et du GPU */ 744054 wikitext text/x-wiki Pour rappel, il existe deux types de cartes graphiques : les cartes dédiées et les cartes intégrées. Les '''cartes graphiques dédiées''' sont des cartes graphiques branchées sur des connecteurs/ports de la carte mère. A l'opposé, tous les processeurs modernes intègrent une carte graphique, appelée '''carte graphique intégrée''', ou encore '''IGP''' (''Integrated Graphic Processor''). En somme, les cartes dédiées sont opposées à celles intégrées dans les processeurs modernes. La différence a un impact sur la mémoire vidéo. Les cartes graphiques dédiées ont souvent de la mémoire vidéo intégrée à la carte graphique. Il y a des exceptions, mais on en parlera plus tard. Les cartes graphiques intégrées au processeur n'ont pas de mémoire vidéo dédiée, vu qu'on ne peut pas intégrer beaucoup de mémoire vidéo dans un processeur. La conséquence est qu'il existe deux grandes manières d'organiser la mémoire à laquelle la carte graphique a accès. * La première est celle de la '''mémoire vidéo dédiée''', à savoir que la carte graphique dispose de sa propre mémoire rien qu'à elle, séparée de la mémoire RAM de l'ordinateur. On fait alors la distinction entre ''RAM système'' et ''RAM vidéo''. Si les premières cartes graphiques n'avaient que quelques mégaoctets de RAM dédiée, elles disposent actuellement de plusieurs gigas-octets de RAM. * A l'opposé, on trouve la '''mémoire unifiée''', avec une seule mémoire RAM est partagée entre le processeur et la carte graphique. Le terme "unifiée" sous-entend que l'on a unifié la mémoire vidéo et la mémoire système (la RAM). [[File:Répartition de la mémoire entre RAM système et carte graphique.png|centre|vignette|upright=2.5|Répartition de la mémoire entre RAM système et carte graphique]] Dans la grosse majorité des cas, les cartes vidéos dédiées ont une mémoire dédiée, alors que les cartes graphiques intégrées doivent utiliser la mémoire unifiée. Mais outre les cartes dédiées et intégrées, il faut aussi citer les cartes graphiques soudées sur la carte mère. Elles étaient utilisées sur les consoles de jeu vidéos assez anciennes, elles sont encore utilisées sur certains PC portables puissants, destinés aux ''gamers''. Pour ces dernières, il est possible d'utiliser aussi bien de la mémoire dédiée que de la mémoire unifiée. D'anciennes consoles de jeu avaient une carte graphique soudée sur la carte mère, qu'on peut facilement repérer à l’œil nu, avec une mémoire unifiée. C'est notamment le cas sur la Nintendo 64, pour ne citer qu'elle. D'autres avaient leur propre mémoire vidéo dédiée. L'usage d'une carte vidéo dédiée se marie très bien avec une mémoire vidéo dédiée, mais il existe de nombreux cas où une carte vidéo dédiée est associée à de la mémoire unifiée. Comme exemple, la toute première carte graphique AGP, l'Intel 740, ne possédait pas de mémoire vidéo proprement dite, juste un simple ''framebuffer''. Tout le reste, texture comme géométrie, était placé en mémoire système et la carte graphique allait lire/écrire les données directement en mémoire RAM système ! Les performances sont généralement ridicules, pour des raisons très diverses, mais les cartes de ce type sont peu chères. Outre l'économie liée à l'absence de mémoire vidéo, les cartes graphiques de ce type sont peu puissantes, l'usage de la mémoire unifiée simplifie leur conception, etc. Par exemple, l'Intel 740 a eu un petit succès sur les ordinateurs d'entrée de gamme. ==Le partage de la mémoire unifiée== Avec la mémoire unifiée, la quantité de mémoire système disponible pour la carte graphique est généralement réglable avec un réglage dans le BIOS. On peut ainsi choisir d'allouer 64, 128 ou 256 mégaoctets de mémoire système pour la carte vidéo, sur un ordinateur avec 4 gigaoctets de RAM. L'interprétation de ce réglage varie grandement selon les cartes mères ou l'IGP. Pour les GPU les plus anciens, ce réglage implique que la RAM sélectionnée est réservée uniquement à la carte graphique, même si elle n'en utilise qu'une partie. La répartition entre mémoire vidéo et système est alors statique, fixée une fois pour toutes. Dans ce cas, la RAM allouée à la carte graphique est généralement petite par défaut. Les concepteurs de carte mère ne veulent pas qu'une trop quantité de RAM soit perdu et inutilisable pour les applications. Ils brident donc la carte vidéo et ne lui allouent que peu de RAM. Heureusement, les GPU modernes sont plus souples. Ils fournissent deux réglages : une quantité de RAM minimale, totalement dédiée au GPU, et une quantité de RAM maximale que le GPU ne peut pas dépasser. Par exemple, il est possible de régler le GPU de manière à ce qu'il ait 64 mégaoctets rien que pour lui, mais qu'il puisse avoir accès à maximum 1 gigaoctet s'il en a besoin. Cela fait au total 960 mégaoctets (1024-64) qui peut être alloués au choix à la carte graphique ou au reste des programmes en cours d’exécution, selon les besoins. Il est possible d'allouer de grandes quantités de RAM au GPU, parfois la totalité de la mémoire système. [[File:Partage de la mémoire unifiée entre CPU et GPU.png|centre|vignette|upright=2|Répartition de la mémoire entre RAM système et carte graphique]] ==Le partage de la mémoire système : la mémoire virtuelle des GPUs dédiés== Après avoir vu la mémoire unifiée, voyons maintenant la mémoire dédiée. Intuitivement, on se dit que la carte graphique n'a accès qu'à la mémoire vidéo dédiée et ne peut pas lire de données dans la mémoire système, la RAM de l'ordinateur. Cependant, ce n'est pas le cas. Et ce pour plusieurs raisons. La raison principale est que des données doivent être copiées de la mémoire RAM vers la mémoire vidéo. Les copies en question se font souvent via ''Direct Memory Access'', ce qui fait que les GPU intègrent un contrôleur DMA dédié. Et ce contrôleur DMA lit des données en RAM système pour les copier en RAM vidéo. La seconde raison est que les cartes graphiques intègrent presque toutes des technologies pour lire directement des données en RAM, sans forcément les copier en mémoire vidéo. Les technologies en question permettent à la carte graphique d'adresser plus de RAM qu'en a la mémoire vidéo. Par exemple, si la carte vidéo a 4 giga-octets de RAM, la carte graphique peut être capable d'en adresser 8 : 4 gigas en RAM vidéo, et 4 autres gigas en RAM système. Les technologies de ce genre ressemblent beaucoup à la mémoire virtuelle des CPU, avec cependant quelques différences. La mémoire virtuelle permet à un processeur d'utiliser plus de RAM qu'il n'y en a d'installée dans l'ordinateur. Par exemple, elle permet au CPU de gérer 4 gigas de RAM sur un ordinateur qui n'en contient que trois, le gigaoctet de trop étant en réalité simulé par un fichier sur le disque dur. La technique est utilisée par tous les processeurs modernes. La mémoire virtuelle des GPUs dédiés fait la même chose, sauf que le surplus d'adresses n'est pas stockés sur le disque dur dans un fichier pagefile, mais est dans la RAM système. Pour le dire autrement, ces cartes dédiées peuvent utiliser la mémoire système si jamais la mémoire vidéo est pleine. [[File:Mémoire virtuelle des cartes graphiques dédiées.png|centre|vignette|upright=2|Mémoire virtuelle des cartes graphiques dédiées]] ===La ''IO-Memory Management Unit'' (IOMMU)=== Pour que la carte graphique ait accès à la mémoire système, elle intègre un circuit appelé la '''''Graphics address remapping table''''', abrévié en GART. Cela vaut aussi bien pour les cartes graphiques utilisant le bus AGP que pour celles en PCI-Express. La GART est techniquement une une ''Memory Management Unit'' (MMU), à savoir un circuit spécialisé qui prend en charge la mémoire virtuelle. La dite MMU étant intégrée dans un périphérique d'entrée-sortie (IO), ici la carte graphique, elle est appelée une IO-MMU (''Input Output-MMU''). Le GPU utilise la technique dite de la pagination, à savoir que l'espace d'adressage est découpée en pages de taille fixe, généralement 4 kilo-octets. La traduction des adresses virtuelles en adresses physique se fait au niveau de la page. Une adresse est coupée en deux parts : un numéro de page, et la position de la donnée dans la page. La position dans la page ne change pas lors de la traduction d'adresse, mais le numéro de page est lui traduit. Le numéro de page virtuel est remplacé par un numéro de page physique lors de la traduction. Pour remplacer le numéro de page virtuel en numéro physique, il faut utiliser une table de translation, appelée la '''table des pages''', qui associe un numéro de page logique à un numéro de page physique. Le système d'exploitation dispose de sa table des pages, qui n'est pas accesible au GPU. Par contre, le GPU dispose d'une sorte de mini-table des pages, qui contient les associations page virtuelle-physique utiles pour traiter les commandes GPU, et rien d'autre. En clair, une sorte de sous-ensemble de la table des pages de l'OS, mais spécifique au GPU. La mini-table des pages est gérée par le pilote de périphérique, qui remplit la mini-table des pages. La mini-table des pages est mémorisée dans une mémoire intégrée au GPU, et précisément dans la MMU. ===Historique de la mémoire virtuelle sur les GPU=== La technologie existait déjà sur certaines cartes graphiques au format PCI, mais la documentation est assez rare. La carte graphique NV1 de NVIDIA, leur toute première carte graphique, disposait déjà de ce système de mémoire virtuelle. La carte graphique communiquait avec le processeur grâce à la fonctionnalité ''Direct Memory Access'' et intégrait donc un contrôleur DMA. Le ''driver'' de la carte graphique programmait le contrôleur DMA en utilisant les adresses fournies par les applications/logiciels. Et il s'agissait d'adresses virtuelles, non d'adresses physiques en mémoire RAM. Pour résoudre ce problème, le contrôleur DMA intégrait une MMU, une unité de traduction d'adresse, qui traduisait les adresses virtuelles fournies par les applications en adresse physique en mémoire système. : Le fonctionnement de cette IOMMU est décrite dans le brevet "US5758182A : DMA controller translates virtual I/O device address received directly from application program command to physical i/o device address of I/O device on device bus", des inventeurs David S. H. Rosenthal et Curtis Priem. [[File:Microarchitecture du GPU NV1 de NVIDIA.png|centre|vignette|upright=2|Microarchitecture du GPU NV1 de NVIDIA]] La technologie s'est démocratisée avec le bus AGP, dont la fonctionnalité dite d'''AGP texturing'' permettait de lire ou écrire directement dans la mémoire RAM, sans passer par le processeur. D'ailleurs, la carte graphique Intel i740 n'avait pas de mémoire vidéo et se débrouillait uniquement avec la mémoire système. L'arrivée du bus PCI-Express ne changea pas la donne, si ce n'est que le bus était plus rapide, ce qui améliorait les performances. Au début, seules les cartes graphiques PCI-Express d'entrée de gamme pouvaient accéder à certaines portions de la mémoire RAM grâce à des technologies adaptées, comme le TurboCache de NVIDIA ou l'HyperMemory d'AMD. Mais la technologie s'est aujourd'hui étendue. De nos jours, toutes les cartes vidéos modernes utilisent la RAM système en plus de la mémoire vidéo, mais seulement en dernier recours, soit quand la mémoire vidéo est quasiment pleine, soit pour faciliter les échanges de données avec le processeur. C'est typiquement le pilote de la carte graphique qui décide ce qui va dans la mémoire vidéo et la mémoire système, et il fait au mieux de manière à avoir les performances optimales. ===L'espace d'adressage du CPU et du GPU=== L'espace d'adressage est l'ensemble des adresses géré par le processeur ou la carte graphique. En général, l'espace d'adressage du processeur et de la carte graphique sont séparés, mais des standards comme l''''''Heterogeneous System Architecture''''' permettent au processeur et à une carte graphique de partager le même espace d'adressage. Une adresse mémoire est alors la même que ce soit pour le processeur ou la carte graphique. {|class="wikitable" |- ! !! Mémoire vidéo dédiée !! Mémoire vidéo unifiée |- ! Sans HSA | [[File:Desktop computer bus bandwidths.svg|400px|Desktop computer bus bandwidths]] | [[File:Integrated graphics with distinct memory allocation.svg|400px|Integrated graphics with distinct memory allocation]] |- ! Avec HSA | [[File:HSA-enabled virtual memory with distinct graphics card.svg|400px|HSA-enabled virtual memory with distinct graphics card]] | [[File:HSA-enabled integrated graphics.svg|400px|HSA-enabled integrated graphics]] |} ==Les échanges entre processeur et mémoire vidéo== Quand on charge un niveau de jeux vidéo, on doit notamment charger la scène, les textures, et d'autres choses dans la mémoire RAM, puis les envoyer à la carte graphique. Ce processus se fait d'une manière fortement différente selon que l'on a une mémoire unifiée ou une mémoire vidéo dédiée. ===Avec la mémoire unifiée=== Avec la mémoire unifié, les échanges de données entre processeur et carte graphique sont fortement simplifiés et aucune copie n'est nécessaire. La carte vidéo peut y accéder directement, en lisant leur position initiale en RAM. Une partie de la RAM est visible seulement pour le CPU, une autre seulement pour le GPU, le reste est partagé. Les échanges de données entre CPU et GPU se font en écrivant/lisant des données dans la RAM partagée entre CPU et GPU. Pas besoin de faire de copie d'une mémoire à une autre : la donnée a juste besoin d'être placée au bon endroit. Le chargement des textures, du tampon de commandes ou d'autres données du genre, est donc très rapide, presque instantané. Par contre, le débit de la RAM unifiée est partagé entre la carte graphique et le processeur. Alors qu'avec une mémoire dédiée, tout le débit de la mémoire vidéo aurait été dédié au GPU, le CPU ayant quant à lui accès à tout le débit de la RAM système. De plus, le partage du débit n'est pas chose facile. Les deux se marchent sur les pieds. La carte graphique doit parfois attendre que le processeur lui laisse l'accès à la RAM et inversement. Divers circuits d'arbitrage s'occupent de répartir équitablement les accès à RAM entre les deux, mais cela ne permet que d'avoir un compromis imparfait qui peut réduire les performances. Le seul moyen pour réduire la casse est d'ajouter des mémoires caches entre le GPU et la RAM, mais l'efficacité des caches est relativement limitée pour le rendu 3D. [[File:Echanges de données entre CPU et GPU avec une mémoire unifiée.png|centre|vignette|upright=2|Échanges de données entre CPU et GPU avec une mémoire unifiée]] Un autre défaut survient sur les cartes dédiées à mémoire unifiée, par exemple l'Intel 740. Pour lire en mémoire RAM, elles doivent passer par l'intermédiaire du bus AGP, PCI ou PCI-Express. Et ce bus est très lent, bien plus que ne le serait une mémoire vidéo normale. Aussi, les performances sont exécrables. J'insiste sur le fait que l'on parle des cartes graphiques dédiées, mais pas des cartes graphiques soudées des consoles de jeu. D'ailleurs, de telles cartes dédiées incorporent un ''framebuffer'' directement dans la carte graphique. Il n'y a pas le choix, le VDC de la carte graphique doit accéder à une mémoire suffisamment rapide pour alimenter l'écran. Ils ne peuvent pas prendre le risque d'aller lire la RAM, dont le temps de latence est élevé, et qui peut potentiellement être réservée par le processeur pendant l’affichage d'une image à l'écran. ===Avec une mémoire vidéo dédiée=== Avec une mémoire vidéo dédiée, on doit copier les données adéquates dans la mémoire vidéo, ce qui implique des transferts de données passant par le bus PCI-Express. Le processeur voit une partie de la mémoire vidéo, dans laquelle il peut lire ou écrire comme bon lui semble. Le reste de la mémoire vidéo est invisible du point de vue du processeur, mais manipulable par le GPU à sa guise. Il est possible pour le CPU de copier des données dans la portion invisible de la mémoire vidéo, mais cela se fait de manière indirecte en passant par le GPU d'abord. Il faut typiquement envoyer une commande spéciale au GPU, pour lui dire de charger une texture en mémoire vidéo, par exemple. Le GPU effectue alors une copie de la mémoire système vers la mémoire vidéo, en utilisant un contrôleur DMA intégré au GPU. [[File:Interaction du GPU avec la mémoire vidéo et la RAM système sur une carte graphique dédiée.png|centre|vignette|upright=2|Échanges de données entre CPU et GPU avec une mémoire vidéo dédiée]] La gestion de la mémoire vidéo est prise en charge par le pilote de la carte graphique, sur le processeur. Elle a tendance à allouer les textures et d'autres données de grande taille dans la mémoire vidéo invisible, le reste étant placé ailleurs. Les copies DMA vers la mémoire vidéo invisible sont adaptées à des copies de grosses données comme les textures, mais elles marchent mal pour des données assez petites. Or, les jeux vidéos ont tendance à générer à la volée de nombreuses données de petite taille, qu'il faut copier en mémoire vidéo. Et c'est sans compter sur des ressources du pilote de périphériques, qui doivent être copiées en mémoire vidéo, comme le tampon de commande ou d'autres ressources. Et celles-ci ne peuvent pas forcément être copiées dans la mémoire vidéo invisible. Si la mémoire vidéo visible par le CPU est trop petite, les données précédentes sont copiées dans la mémoire visible par le CPU, en mémoire système, mais leur accès par le GPU est alors très lent. Aussi, plus la portion visible de la mémoire vidéo est grande, plus simple est la gestion de la mémoire vidéo par le pilote graphique. Et de ce point de vue, les choses ont évolué récemment. Pour accéder à un périphérique PCI-Express, il faut configurer des registres spécialisés, appelés les ''Base Address Registers'' (BARs). La configuration des registres précise quelle portion de mémoire vidéo est adressable par le processeur, quelle est sa taille, sa position en mémoire vidéo, etc. Avant 2008, les BAR permettaient d’accéder à seulement 256 mégaoctets, pas plus. La gestion de la mémoire vidéo était alors difficile. Les échanges entre portion visible et invisible de la mémoire vidéo étaient complexes, demandaient d’exécuter des commandes spécifiques au GPU et autres. Après 2008, la spécification du PCI-Express ajouta un support de la technologie ''resizable bar'', qui permet au processeur d’accéder directement à plus de 256 mégaoctets de mémoire vidéo, voire à la totalité de la mémoire vidéo. De nombreux fabricants de cartes graphiques commencent à incorporer cette technologie, qui demande quelques changements au niveau du système d'exploitation, des pilotes de périphériques et du matériel. {{NavChapitre | book=Les cartes graphiques | prev=La microarchitecture des processeurs de shaders | prevText=La microarchitecture des processeurs de shaders | next=La hiérarchie mémoire d'un GPU | netxText=La hiérarchie mémoire d'un GPU }}{{autocat}} dboeqjmxsb1hya9dbz479k3fygw6a0u Fonctionnement d'un ordinateur/L'unité de chargement et le program counter 0 80691 744058 743108 2025-06-03T18:38:48Z Mewtow 31375 /* Le Zero-overhead looping */ 744058 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. ===La ''prefetch input queue''=== Avec un pipeline, plusieurs instructions sont présentes en même temps dans le pipeline. Et cela fait que des accès mémoires simultanés peuvent avoir lieu. Pour comprendre pourquoi, regardons dans quels étages du pipeline il peut y avoir un accès mémoire. Le premier, assez évident, est celui dédié aux accès mémoire, lors de l’exécution d'une instruction. Si une instruction effectue un accès mémoire, c'est cet étage qui le prend en charge. Il n'est pas systématique, seules certaines instructions l'utilisent. Par contre, un second étage utilise systématiquement un accès mémoire : le chargement de l'instruction depuis la mémoire ou le cache. En clair, il n'est pas rare qu'on ait accès simultané à la mémoire : un pour charger l'instruction, un autre pour charger la donnée. Pour éviter cela, une solution simple consiste à séparer les voies d'accès aux instructions et aux données, de manière à autoriser des accès simultanés. Dans le cas le plus fréquent, les processeurs disposent d'un cache, et la solution est alors évidente : le cache L1 est séparé en deux, avec un cache d’instruction séparé du cache L1 de données. Les accès concurrents à la mémoire ne sont plus un problème. Sur les processeurs ne disposant pas de mémoire cache, la solution la plus est d'utiliser une architecture Harvard. Dans tous les cas, il faut utiliser une architecture harvard, ou harvard modifiée (caches séparés). Sur les architectures Von Neumann, il est possible de limiter la casse en utilisant une optimisation appelée la ''prefetch input queue'', vue dans le chapitre sur le chargement des instructions. l'idée est que le processeur précharge les instructions quand la mémoire est libre, dans une mémoire tampon située avant l'unité de décodage. Si un accès aux données a lieu, le processeur peut décoder les instructions préchargées, en les piochant dans la mémoire tampon, sans accéder à la RAM ou au cache. Pour implémenter le préchargement d'instruction, le registre d'instruction est remplacé par une mémoire FIFO appelée la '''''Prefetch input queue'''''. On peut la voir comme un registre d'instruction sous stéroïde, capable de mémoriser plusieurs instructions consécutives. Les instructions sont chargées dans la ''Prefetch input queue'' et y attendent que le processeur les lise et les décode. Les instructions y sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser cette méthode était le 8086, un processeur d'Intel de jeu d'instruction x86. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permattait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons voir dans ce qui suit. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Cette détection ne peut se faire qu'une fois le branchement décodé : on ne sait pas si l'instruction est un branchement ou autre chose tant que le décodage n'a pas eu lieu, par définition. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> 3n8559z9ofqeorlcqy087zvwixtqb5c 744059 744058 2025-06-03T18:45:02Z Mewtow 31375 /* Les optimisations du chargement des instructions */ 744059 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne part pas du principe que la mémoire a un débit binaire important. L'idée est que pendant que le processeur exécute une instruction, on précharge la suivante. Évidemment, les instructions préchargées sont accumulées dans une mémoire FIFO appelée la '''''prefetch input queue''''', elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. La ''prefetch input queue'' a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peutr en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). Pour implémenter le préchargement d'instruction, le registre d'instruction est remplacé par une mémoire FIFO appelée la '''''Prefetch input queue'''''. On peut la voir comme un registre d'instruction sous stéroïde, capable de mémoriser plusieurs instructions consécutives. Les instructions sont chargées dans la ''Prefetch input queue'' et y attendent que le processeur les lise et les décode. Les instructions y sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser cette méthode était le 8086, un processeur d'Intel de jeu d'instruction x86. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permattait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons voir dans ce qui suit. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Cette détection ne peut se faire qu'une fois le branchement décodé : on ne sait pas si l'instruction est un branchement ou autre chose tant que le décodage n'a pas eu lieu, par définition. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> bezoq4ld7y16mmcptxruvcvvi1uzxbn 744060 744059 2025-06-03T18:46:36Z Mewtow 31375 /* La prefetch input queue */ 744060 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une optimisation matérielle qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne part pas du principe que la mémoire a un débit binaire important, on ne charge pas plusieurs instructions à la fois. Les instructions sont préchargées séquentiellement, un octet à la fois. Évidemment, les instructions préchargées sont accumulées dans une mémoire FIFO appelée la '''''prefetch input queue''''', elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. L'idée est que pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peutr en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). Pour implémenter le préchargement d'instruction, le registre d'instruction est remplacé par une mémoire FIFO appelée la '''''Prefetch input queue'''''. On peut la voir comme un registre d'instruction sous stéroïde, capable de mémoriser plusieurs instructions consécutives. Les instructions sont chargées dans la ''Prefetch input queue'' et y attendent que le processeur les lise et les décode. Les instructions y sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser cette méthode était le 8086, un processeur d'Intel de jeu d'instruction x86. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permattait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons voir dans ce qui suit. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Cette détection ne peut se faire qu'une fois le branchement décodé : on ne sait pas si l'instruction est un branchement ou autre chose tant que le décodage n'a pas eu lieu, par définition. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> fi2iwpl6xji8eutkiarejqxzmj3xtcp 744061 744060 2025-06-03T18:48:36Z Mewtow 31375 /* La prefetch input queue */ 744061 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une optimisation matérielle qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un octet à la fois. Le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement. L'idée est que pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peutr en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). Pour implémenter le préchargement d'instruction, le registre d'instruction est remplacé par une mémoire FIFO appelée la '''''Prefetch input queue'''''. On peut la voir comme un registre d'instruction sous stéroïde, capable de mémoriser plusieurs instructions consécutives. Les instructions sont chargées dans la ''Prefetch input queue'' et y attendent que le processeur les lise et les décode. Les instructions y sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser cette méthode était le 8086, un processeur d'Intel de jeu d'instruction x86. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permattait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons voir dans ce qui suit. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Cette détection ne peut se faire qu'une fois le branchement décodé : on ne sait pas si l'instruction est un branchement ou autre chose tant que le décodage n'a pas eu lieu, par définition. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> 2cultaozuhamxcjzpyiuj1v1j124j13 744062 744061 2025-06-03T18:50:21Z Mewtow 31375 /* La prefetch input queue */ 744062 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une optimisation matérielle qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un octet à la fois. Le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement. L'idée est que pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peutr en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. Pour implémenter le préchargement d'instruction, le registre d'instruction est remplacé par une mémoire FIFO appelée la '''''Prefetch input queue'''''. On peut la voir comme un registre d'instruction sous stéroïde, capable de mémoriser plusieurs instructions consécutives. Les instructions sont chargées dans la ''Prefetch input queue'' et y attendent que le processeur les lise et les décode. Les instructions y sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser cette méthode était le 8086, un processeur d'Intel de jeu d'instruction x86. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permattait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons voir dans ce qui suit. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Cette détection ne peut se faire qu'une fois le branchement décodé : on ne sait pas si l'instruction est un branchement ou autre chose tant que le décodage n'a pas eu lieu, par définition. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> ch0joxm7ppqk23jk2crzi01sbt6nozj 744063 744062 2025-06-03T18:51:39Z Mewtow 31375 /* La prefetch input queue */ 744063 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une optimisation matérielle qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un octet à la fois. Le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement. L'idée est que pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peutr en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. Le premier processeur commercial grand public à utiliser cette méthode était le 8086, un processeur d'Intel de jeu d'instruction x86. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons voir dans ce qui suit. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Cette détection ne peut se faire qu'une fois le branchement décodé : on ne sait pas si l'instruction est un branchement ou autre chose tant que le décodage n'a pas eu lieu, par définition. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> rg33t8sc0vpy6t2r62t5ipkntsiwgoj 744068 744063 2025-06-03T19:01:23Z Mewtow 31375 /* La prefetch input queue */ 744068 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une optimisation matérielle qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un octet à la fois. Le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement. L'idée est que pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peutr en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Sur le 8086 et le 8088, la plupart des instructions faisaient deux octets, alors que la mémoire RAM ne permettait que de charger un octet à la fois. Le décodeur devait attendre que les deux octets d'une instruction soient disponibles dans la ''Prefetch input queue''. Pour cela, un circuit appelé le ''loader'' fournissait deux signaux au décodeur d'instruction : l'un indiquant que le premier octet est déjà chargé, l'autre indiquant que le second octet est disponible. Le décodeur, quant à lui, envoyait le signal ''Run Next Instruction'' pour lire une instruction : elle était alors dépilée de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'' un cycle en avance, un cyucle avant que l'instruction en cours ne termine. Le résultat est que le ''loader'' réagissait en préchargeant l'instruction suivante. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. Le premier processeur commercial grand public à utiliser cette méthode était le 8086, un processeur d'Intel de jeu d'instruction x86. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons voir dans ce qui suit. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Cette détection ne peut se faire qu'une fois le branchement décodé : on ne sait pas si l'instruction est un branchement ou autre chose tant que le décodage n'a pas eu lieu, par définition. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> bz8z4zwhl1miqzft5fufs2869ag6hsq 744069 744068 2025-06-03T19:04:09Z Mewtow 31375 /* La prefetch input queue */ 744069 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une optimisation matérielle qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un octet à la fois. Le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement. L'idée est que pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peutr en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Sur le 8086 et le 8088, la plupart des instructions faisaient deux octets, alors que la mémoire RAM ne permettait que de charger un octet à la fois. Le décodeur devait attendre que les deux octets d'une instruction soient disponibles dans la ''Prefetch input queue''. Pour cela, un circuit appelé le ''loader'' fournissait deux signaux au décodeur d'instruction : l'un indiquant que le premier octet est déjà chargé, l'autre indiquant que le second octet est disponible. Le décodeur, quant à lui, envoyait le signal ''Run Next Instruction'' pour lire une instruction : elle était alors dépilée de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'' un cycle en avance, un cyucle avant que l'instruction en cours ne termine. Le résultat est que le ''loader'' réagissait en préchargeant l'instruction suivante. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Il faut noter que les instructions x86 sont de longueur variables. Pour les gérer, le décodeur pouvait lire une instruction en plusieurs fois dans la ''Prefetch input queue''. Les deux premiers octets sont lus depuis la ''Prefetch input queue'', et sont alors décodés. Le décodeur détermine alors la taille de l'instruction. Si l'instruction fait exactement deux octets, elle est exécutée directement. Sinon, les octets manquants sont lus depuis la ''Prefetch input queue''. La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. Le premier processeur commercial grand public à utiliser cette méthode était le 8086, un processeur d'Intel de jeu d'instruction x86. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons voir dans ce qui suit. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Cette détection ne peut se faire qu'une fois le branchement décodé : on ne sait pas si l'instruction est un branchement ou autre chose tant que le décodage n'a pas eu lieu, par définition. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> qbcwwd91j8uy9n9sfrjwambv2rvttgs 744070 744069 2025-06-03T19:13:23Z Mewtow 31375 /* La prefetch input queue */ 744070 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une optimisation matérielle qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un octet à la fois. Le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement. L'idée est que pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peutr en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. En conséquence, il arrive que la 'prefetch input queue'' n'ait pas préchargé l'instruction suivante, alors que le décodeur d'instruction est prêt pour la décoder. Dans ce cas, le décodeur doit attendre que l'instruction soit chargée. Sur le 8086 et le 8088, la plupart des instructions faisaient deux octets, alors que la mémoire RAM ne permettait que de charger un octet à la fois. Le décodeur devait attendre que les deux octets d'une instruction soient disponibles dans la ''Prefetch input queue''. Pour cela, un circuit appelé le ''loader'' fournissait deux signaux au décodeur d'instruction : l'un indiquant que le premier octet est déjà chargé, l'autre indiquant que le second octet est disponible. Le décodeur, quant à lui, envoyait le signal ''Run Next Instruction'' pour lire une instruction : elle était alors dépilée de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'' un cycle en avance, un cucle avant que l'instruction en cours ne termine. Le résultat est que le ''loader'' réagissait en préchargeant l'instruction suivante. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Il faut noter que les instructions x86 sont de longueur variables. Pour les gérer, le décodeur pouvait lire une instruction en plusieurs fois dans la ''Prefetch input queue''. Les deux premiers octets sont lus depuis la ''Prefetch input queue'', et sont alors décodés. Le décodeur détermine alors la taille de l'instruction. Si l'instruction fait exactement deux octets, elle est exécutée directement. Sinon, les octets manquants sont lus depuis la ''Prefetch input queue''. Pour cela, le décodeur dispose d'une micro-opération pour lire un octet depuis la ''Prefetch input queue''. Il faut noter qu'une ''Prefetch input queue'' interagit assez mal avec le ''program counter''. En effet, la ''Prefetch input queue'' précharge les instructions séquentiellement. Pour savoir où elle en est rendue, elle mémorise l'adresse de la prochaine instruction à charger dans un registre dédié. Et pour ne pas faire doublon, ce registre remplace le ''program counter''. Après tout, le registre n'est qu'un ''program counter'' ayant pris une avance de quelques cycles d'horloge, qui a été incrémenté en avance. Et cela ne pose pas de problèmes, sauf dans le cas des branchements. Le décodeur d'instruction dispose d'autres micro-opérations qui agissent sur la ''Prefetch input queue'', trois au total. La première stoppe le préchargement des instructions dans la ''Prefetch input queue''. La seconde vide la ''Prefetch input queue'', elle invalide les instructions préchargées. La troisième permet de reconstituer le ''program counter''. Elles servent à gérer l'exécution des branchements, comme on le verra plus bas. Le premier processeur commercial grand public à utiliser cette méthode était le 8086, un processeur d'Intel de jeu d'instruction x86. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons voir dans ce qui suit. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Cette détection ne peut se faire qu'une fois le branchement décodé : on ne sait pas si l'instruction est un branchement ou autre chose tant que le décodage n'a pas eu lieu, par définition. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> p1h2hxtrwy3t8uqmrke8x0geosr75c2 744075 744070 2025-06-03T19:17:00Z Mewtow 31375 /* La prefetch input queue */ 744075 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une optimisation matérielle qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un octet à la fois. Le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement. L'idée est que pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peut en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. En conséquence, il arrive que la 'prefetch input queue'' n'ait pas préchargé l'instruction suivante, alors que le décodeur d'instruction est prêt pour la décoder. Dans ce cas, le décodeur doit attendre que l'instruction soit chargée. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons expliquer dans quelques paragraphes. Le premier processeur commercial grand public à utiliser une ''prefetch input queue'' était le 8086. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. Vous remarquerez que j'ai exprimé la capacité de la ''prefetch input queue'' en octets et non en instructions. La raison est que sur les processeurs x86, les instructions sont de taille variable. Les instructions de ces processeurs ont une taille qui varie entre deux octets et 6 octets. La ''prefetch input queue'' était optimisée pour lire des instructions de deux octets, avec quelques mécanismes pour gérer les instructions plus longues. Il faut dire que les instructions les plus courantes faisaient deux octets, respectivement un octet d'opcode et un octet Mod/RM pour préciser le mode d'adressage. Si les instructions faisaient deux octets ou plus, La mémoire RAM ne permettait que de charger un octet à la fois. Le décodeur devait attendre que les deux octets d'une instruction soient disponibles dans la ''Prefetch input queue''. Pour cela, un circuit appelé le ''loader'' fournissait deux signaux au décodeur d'instruction : l'un indiquant que le premier octet est déjà chargé, l'autre indiquant que le second octet est disponible. Le décodeur, quant à lui, envoyait le signal ''Run Next Instruction'' pour lire une instruction : elle était alors dépilée de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'' un cycle en avance, un cucle avant que l'instruction en cours ne termine. Le résultat est que le ''loader'' réagissait en préchargeant l'instruction suivante. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Il faut noter que les instructions x86 sont de longueur variables. Pour les gérer, le décodeur pouvait lire une instruction en plusieurs fois dans la ''Prefetch input queue''. Les deux premiers octets sont lus depuis la ''Prefetch input queue'', et sont alors décodés. Le décodeur détermine alors la taille de l'instruction. Si l'instruction fait exactement deux octets, elle est exécutée directement. Sinon, les octets manquants sont lus depuis la ''Prefetch input queue''. Pour cela, le décodeur dispose d'une micro-opération pour lire un octet depuis la ''Prefetch input queue''. Il faut noter qu'une ''Prefetch input queue'' interagit assez mal avec le ''program counter''. En effet, la ''Prefetch input queue'' précharge les instructions séquentiellement. Pour savoir où elle en est rendue, elle mémorise l'adresse de la prochaine instruction à charger dans un registre dédié. Et pour ne pas faire doublon, ce registre remplace le ''program counter''. Après tout, le registre n'est qu'un ''program counter'' ayant pris une avance de quelques cycles d'horloge, qui a été incrémenté en avance. Et cela ne pose pas de problèmes, sauf dans le cas des branchements. Le décodeur d'instruction dispose d'autres micro-opérations qui agissent sur la ''Prefetch input queue'', trois au total. La première stoppe le préchargement des instructions dans la ''Prefetch input queue''. La seconde vide la ''Prefetch input queue'', elle invalide les instructions préchargées. La troisième permet de reconstituer le ''program counter''. Elles servent à gérer l'exécution des branchements, comme on le verra plus bas. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Cette détection ne peut se faire qu'une fois le branchement décodé : on ne sait pas si l'instruction est un branchement ou autre chose tant que le décodage n'a pas eu lieu, par définition. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> dufpptlx4qwzxmdyxg14b0f40zra8p0 744076 744075 2025-06-03T19:19:26Z Mewtow 31375 /* La prefetch input queue */ 744076 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une optimisation matérielle qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un octet à la fois. Le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement. L'idée est que pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peut en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. En conséquence, il arrive que la 'prefetch input queue'' n'ait pas préchargé l'instruction suivante, alors que le décodeur d'instruction est prêt pour la décoder. Dans ce cas, le décodeur doit attendre que l'instruction soit chargée. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons expliquer dans quelques paragraphes. Le premier processeur commercial grand public à utiliser une ''prefetch input queue'' était le 8086. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. Vous remarquerez que j'ai exprimé la capacité de la ''prefetch input queue'' en octets et non en instructions. La raison est que sur les processeurs x86, les instructions sont de taille variable. Les instructions de ces processeurs ont une taille qui varie entre deux octets et 6 octets. La ''prefetch input queue'' était optimisée pour lire des instructions de deux octets, avec quelques mécanismes pour gérer les instructions plus longues. Il faut dire que les instructions les plus courantes faisaient deux octets, respectivement un octet d'opcode et un octet Mod/RM pour préciser le mode d'adressage. Si les instructions faisaient deux octets ou plus, La mémoire RAM ne permettait que de charger un octet à la fois. Le décodeur devait attendre que les deux octets d'une instruction soient disponibles dans la ''Prefetch input queue''. Pour cela, un circuit appelé le ''loader'' fournissait deux signaux au décodeur d'instruction : l'un indiquant que le premier octet est déjà chargé, l'autre indiquant que le second octet est disponible. Pour gérer les instructions de plus de deux octets, le décodeur pouvait lire une instruction en plusieurs fois dans la ''Prefetch input queue''. Les deux premiers octets sont lus depuis la ''Prefetch input queue'', et sont alors décodés. Le décodeur détermine alors la taille de l'instruction. Si l'instruction fait exactement deux octets, elle est exécutée directement. Sinon, les octets manquants sont lus depuis la ''Prefetch input queue''. Pour cela, le décodeur dispose d'une micro-opération pour lire un octet depuis la ''Prefetch input queue''. Le ''loader'' ne faisait pas que fournir les deux signaux au décodeur d'instruction. Il recevait aussi des signaux de la part du décodeur d'instruction, afin de gérer les lectures dans la ''Prefetch input queue''. Le décodeur envoyait le signal ''Run Next Instruction'' pour lire une instruction : elle était alors dépilée de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'' un cycle en avance, un cucle avant que l'instruction en cours ne termine. Le résultat est que le ''loader'' réagissait en préchargeant l'instruction suivante. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Il faut noter qu'une ''Prefetch input queue'' interagit assez mal avec le ''program counter''. En effet, la ''Prefetch input queue'' précharge les instructions séquentiellement. Pour savoir où elle en est rendue, elle mémorise l'adresse de la prochaine instruction à charger dans un registre dédié. Et pour ne pas faire doublon, ce registre remplace le ''program counter''. Après tout, le registre n'est qu'un ''program counter'' ayant pris une avance de quelques cycles d'horloge, qui a été incrémenté en avance. Et cela ne pose pas de problèmes, sauf dans le cas des branchements. Le décodeur d'instruction dispose d'autres micro-opérations qui agissent sur la ''Prefetch input queue'', trois au total. La première stoppe le préchargement des instructions dans la ''Prefetch input queue''. La seconde vide la ''Prefetch input queue'', elle invalide les instructions préchargées. La troisième permet de reconstituer le ''program counter''. Elles servent à gérer l'exécution des branchements, comme on le verra plus bas. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Cette détection ne peut se faire qu'une fois le branchement décodé : on ne sait pas si l'instruction est un branchement ou autre chose tant que le décodage n'a pas eu lieu, par définition. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> tgvje186cmr1rejul6t9jpuqpyw7vh6 744077 744076 2025-06-03T19:26:48Z Mewtow 31375 /* La prefetch input queue */ 744077 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement, qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un octet à la fois. En conséquence, le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. L'idée est que pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peut en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. En conséquence, il arrive que la 'prefetch input queue'' n'ait pas préchargé l'instruction suivante, alors que le décodeur d'instruction est prêt pour la décoder. Dans ce cas, le décodeur doit attendre que l'instruction soit chargée. Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser une ''prefetch input queue'' était le 8086. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons expliquer dans quelques paragraphes. Vous remarquerez que j'ai exprimé la capacité de la ''prefetch input queue'' en octets et non en instructions. La raison est que sur les processeurs x86, les instructions sont de taille variable. Les instructions de ces processeurs ont une taille qui varie entre deux octets et 6 octets. La ''prefetch input queue'' était optimisée pour lire des instructions de deux octets, avec quelques mécanismes pour gérer les instructions plus longues. Il faut dire que les instructions les plus courantes faisaient deux octets, respectivement un octet d'opcode et un octet Mod/RM pour préciser le mode d'adressage. Si les instructions faisaient deux octets ou plus, La mémoire RAM ne permettait que de charger un octet à la fois. Le décodeur devait attendre que les deux octets d'une instruction soient disponibles dans la ''Prefetch input queue''. Pour cela, un circuit appelé le ''loader'' fournissait deux signaux au décodeur d'instruction : l'un indiquant que le premier octet est déjà chargé, l'autre indiquant que le second octet est disponible. Le ''loader'' recevait aussi des signaux de la part du décodeur d'instruction, afin de gérer les lectures dans la ''Prefetch input queue''. Le décodeur envoyait le signal ''Run Next Instruction'' pour lire une instruction : elle était alors dépilée de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'' un cycle en avance, un cucle avant que l'instruction en cours ne termine. Le résultat est que le ''loader'' réagissait en préchargeant l'instruction suivante. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Pour gérer les instructions de plus de deux octets, le décodeur pouvait lire une instruction en plusieurs fois dans la ''Prefetch input queue''. Les deux premiers octets sont lus depuis la ''Prefetch input queue'', et sont alors décodés. Le décodeur détermine alors la taille de l'instruction. Si l'instruction fait exactement deux octets, elle est exécutée directement. Sinon, les octets manquants sont lus depuis la ''Prefetch input queue''. Pour cela, le décodeur dispose d'une micro-opération pour lire un octet depuis la ''Prefetch input queue''. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Pour cela, le décodeur d'instruction dispose d'une micro-opération qui vide la ''Prefetch input queue'', elle invalide les instructions préchargées. Cette détection ne peut se faire qu'une fois le branchement décodé, qu'une fois que l'on sait que l'instruction décodée est un branchement. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Il faut noter qu'une ''Prefetch input queue'' interagit assez mal avec le ''program counter''. En effet, la ''Prefetch input queue'' précharge les instructions séquentiellement. Pour savoir où elle en est rendue, elle mémorise l'adresse de la prochaine instruction à charger dans un registre dédié. Et pour ne pas faire doublon, ce registre remplace le ''program counter''. Après tout, le registre n'est qu'un ''program counter'' ayant pris une avance de quelques cycles d'horloge, qui a été incrémenté en avance. Il serait possible d'utiliser un ''program counter'' en plus du registre de préchargement, mais ce n'est pas la solution qui a été utilisée. Les processeurs Intel anciens ont préféré n'utiliser qu'un seul registre de préchargement en remplacement du ''program counter''. Et cela ne pose pas de problèmes, sauf dans le cas des branchements. Par exemple, certains branchements relatifs demandent de connaitre la véritable valeur du ''program counter'', pas celle calculée en avance. D'autres situations demandent de connaitre exactement la valeur du ''program counter'', celle sans préchargement. Pour cela, le décodeur d'instruction dispose d'une instruction pour reconstituer le ''program counter'', à savoir corriger le ''program coutner'' et éliminer l'effet du préchargement. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. Le décodeur d'instruction dispose aussi d'une micro-opération qui stoppe le préchargement des instructions dans la ''Prefetch input queue''. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> saagvh0xivfhorbpv85z2alml5rn3mb 744078 744077 2025-06-03T19:32:43Z Mewtow 31375 /* La prefetch input queue */ 744078 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement, qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un octet à la fois. En conséquence, le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. L'idée est que pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peut en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. En conséquence, il arrive que la 'prefetch input queue'' n'ait pas préchargé l'instruction suivante, alors que le décodeur d'instruction est prêt pour la décoder. Dans ce cas, le décodeur doit attendre que l'instruction soit chargée. Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser une ''prefetch input queue'' était le 8086. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons expliquer dans quelques paragraphes. Vous remarquerez que j'ai exprimé la capacité de la ''prefetch input queue'' en octets et non en instructions. La raison est que sur les processeurs x86, les instructions sont de taille variable. Les instructions de ces processeurs ont une taille qui varie entre deux octets et 6 octets. La ''prefetch input queue'' était optimisée pour lire des instructions de deux octets, avec quelques mécanismes pour gérer les instructions plus longues. Il faut dire que les instructions les plus courantes faisaient deux octets, respectivement un octet d'opcode et un octet Mod/RM pour préciser le mode d'adressage. Si les instructions faisaient deux octets ou plus, La mémoire RAM ne permettait que de charger un octet à la fois. Le décodeur devait attendre que les deux octets d'une instruction soient disponibles dans la ''Prefetch input queue''. Pour cela, un circuit appelé le ''loader'' fournissait deux signaux au décodeur d'instruction : l'un indiquant que le premier octet est déjà chargé, l'autre indiquant que le second octet est disponible. Le ''loader'' recevait aussi des signaux de la part du décodeur d'instruction, afin de gérer les lectures dans la ''Prefetch input queue''. Le décodeur envoyait le signal ''Run Next Instruction'' pour lire une instruction : elle était alors dépilée de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'' un cycle en avance, un cucle avant que l'instruction en cours ne termine. Le résultat est que le ''loader'' réagissait en préchargeant l'instruction suivante. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Pour gérer les instructions de plus de deux octets, le décodeur pouvait lire une instruction en plusieurs fois dans la ''Prefetch input queue''. Les deux premiers octets sont lus depuis la ''Prefetch input queue'', et sont alors décodés. Le décodeur détermine alors la taille de l'instruction. Si l'instruction fait exactement deux octets, elle est exécutée directement. Sinon, les octets manquants sont lus depuis la ''Prefetch input queue''. Pour cela, le décodeur dispose d'une micro-opération pour lire un octet depuis la ''Prefetch input queue''. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Pour cela, le décodeur d'instruction dispose d'une micro-opération qui vide la ''Prefetch input queue'', elle invalide les instructions préchargées. Cette détection ne peut se faire qu'une fois le branchement décodé, qu'une fois que l'on sait que l'instruction décodée est un branchement. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Il faut noter qu'une ''Prefetch input queue'' interagit assez mal avec le ''program counter''. En effet, la ''Prefetch input queue'' précharge les instructions séquentiellement. Pour savoir où elle en est rendue, elle mémorise l'adresse de la prochaine instruction à charger dans un '''registre de préchargement''' dédié. Il serait possible d'utiliser un ''program counter'' en plus du registre de préchargement, mais ce n'est pas la solution qui a été utilisée. Les processeurs Intel anciens ont préféré n'utiliser qu'un seul registre de préchargement en remplacement du ''program counter''. Après tout, le registre de préchargement n'est qu'un ''program counter'' ayant pris une avance de quelques cycles d'horloge, qui a été incrémenté en avance. Et cela ne pose pas de problèmes, sauf avec certains branchements. Par exemple, certains branchements relatifs demandent de connaitre la véritable valeur du ''program counter'', pas celle calculée en avance. Idem avec les instructions d'appel de fonction, qui demandent de sauvegarder l'adresse de retour exacte, donc le vrai ''program counter''. De telles situations demandent de connaitre la valeur réelle du ''program counter'', celle sans préchargement. Pour cela, le décodeur d'instruction dispose d'une instruction pour reconstituer le ''program counter'', à savoir corriger le ''program coutner'' et éliminer l'effet du préchargement. La micro-opération de correction se contente de soustraire le nombre d'octets préchargés au registre de préchargement. Le nombre d'octets préchargés est déduit à partir des deux pointeurs intégré à la FIFO, qui indiquent la position du premier et du dernier octet préchargé. Le bit qui indique si la FIFO est vide était aussi utilisé. Les deux pointeurs sont lus depuis la FIFO, et sont envoyés à un circuit qui détermine le nombre d'octets préchargés. Sur le 8086, ce circuit était implémenté non pas par un circuit combinatoire, mais par une mémoire ROM équivalente. La petite taille de la FIFO faisait que les pointeurs étaient très petits et la ROM l'était aussi. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. Le décodeur d'instruction dispose aussi d'une micro-opération qui stoppe le préchargement des instructions dans la ''Prefetch input queue''. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> snop5my30q4kn3h68r5nbtdge1eynd5 744079 744078 2025-06-03T19:33:33Z Mewtow 31375 /* La prefetch input queue */ 744079 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement, qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un octet à la fois. En conséquence, le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. L'idée est que pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peut en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. En conséquence, il arrive que la 'prefetch input queue'' n'ait pas préchargé l'instruction suivante, alors que le décodeur d'instruction est prêt pour la décoder. Dans ce cas, le décodeur doit attendre que l'instruction soit chargée. Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser une ''prefetch input queue'' était le 8086. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons expliquer dans quelques paragraphes. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Vous remarquerez que j'ai exprimé la capacité de la ''prefetch input queue'' en octets et non en instructions. La raison est que sur les processeurs x86, les instructions sont de taille variable. Les instructions de ces processeurs ont une taille qui varie entre deux octets et 6 octets. La ''prefetch input queue'' était optimisée pour lire des instructions de deux octets, avec quelques mécanismes pour gérer les instructions plus longues. Il faut dire que les instructions les plus courantes faisaient deux octets, respectivement un octet d'opcode et un octet Mod/RM pour préciser le mode d'adressage. Si les instructions faisaient deux octets ou plus, La mémoire RAM ne permettait que de charger un octet à la fois. Le décodeur devait attendre que les deux octets d'une instruction soient disponibles dans la ''Prefetch input queue''. Pour cela, un circuit appelé le ''loader'' fournissait deux signaux au décodeur d'instruction : l'un indiquant que le premier octet est déjà chargé, l'autre indiquant que le second octet est disponible. Le ''loader'' recevait aussi des signaux de la part du décodeur d'instruction, afin de gérer les lectures dans la ''Prefetch input queue''. Le décodeur envoyait le signal ''Run Next Instruction'' pour lire une instruction : elle était alors dépilée de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'' un cycle en avance, un cucle avant que l'instruction en cours ne termine. Le résultat est que le ''loader'' réagissait en préchargeant l'instruction suivante. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Pour gérer les instructions de plus de deux octets, le décodeur pouvait lire une instruction en plusieurs fois dans la ''Prefetch input queue''. Les deux premiers octets sont lus depuis la ''Prefetch input queue'', et sont alors décodés. Le décodeur détermine alors la taille de l'instruction. Si l'instruction fait exactement deux octets, elle est exécutée directement. Sinon, les octets manquants sont lus depuis la ''Prefetch input queue''. Pour cela, le décodeur dispose d'une micro-opération pour lire un octet depuis la ''Prefetch input queue''. Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Pour cela, le décodeur d'instruction dispose d'une micro-opération qui vide la ''Prefetch input queue'', elle invalide les instructions préchargées. Cette détection ne peut se faire qu'une fois le branchement décodé, qu'une fois que l'on sait que l'instruction décodée est un branchement. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Il faut noter qu'une ''Prefetch input queue'' interagit assez mal avec le ''program counter''. En effet, la ''Prefetch input queue'' précharge les instructions séquentiellement. Pour savoir où elle en est rendue, elle mémorise l'adresse de la prochaine instruction à charger dans un '''registre de préchargement''' dédié. Il serait possible d'utiliser un ''program counter'' en plus du registre de préchargement, mais ce n'est pas la solution qui a été utilisée. Les processeurs Intel anciens ont préféré n'utiliser qu'un seul registre de préchargement en remplacement du ''program counter''. Après tout, le registre de préchargement n'est qu'un ''program counter'' ayant pris une avance de quelques cycles d'horloge, qui a été incrémenté en avance. Et cela ne pose pas de problèmes, sauf avec certains branchements. Par exemple, certains branchements relatifs demandent de connaitre la véritable valeur du ''program counter'', pas celle calculée en avance. Idem avec les instructions d'appel de fonction, qui demandent de sauvegarder l'adresse de retour exacte, donc le vrai ''program counter''. De telles situations demandent de connaitre la valeur réelle du ''program counter'', celle sans préchargement. Pour cela, le décodeur d'instruction dispose d'une instruction pour reconstituer le ''program counter'', à savoir corriger le ''program coutner'' et éliminer l'effet du préchargement. La micro-opération de correction se contente de soustraire le nombre d'octets préchargés au registre de préchargement. Le nombre d'octets préchargés est déduit à partir des deux pointeurs intégré à la FIFO, qui indiquent la position du premier et du dernier octet préchargé. Le bit qui indique si la FIFO est vide était aussi utilisé. Les deux pointeurs sont lus depuis la FIFO, et sont envoyés à un circuit qui détermine le nombre d'octets préchargés. Sur le 8086, ce circuit était implémenté non pas par un circuit combinatoire, mais par une mémoire ROM équivalente. La petite taille de la FIFO faisait que les pointeurs étaient très petits et la ROM l'était aussi. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. Le décodeur d'instruction dispose aussi d'une micro-opération qui stoppe le préchargement des instructions dans la ''Prefetch input queue''. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> e31iqpu86acm6q7l03adnq2aohvuayd 744080 744079 2025-06-03T19:35:42Z Mewtow 31375 /* La prefetch input queue */ 744080 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement, qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un octet à la fois. En conséquence, le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. L'idée est que pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peut en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. En conséquence, il arrive que la 'prefetch input queue'' n'ait pas préchargé l'instruction suivante, alors que le décodeur d'instruction est prêt pour la décoder. Dans ce cas, le décodeur doit attendre que l'instruction soit chargée. Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser une ''prefetch input queue'' était le 8086. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons expliquer dans quelques paragraphes. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Vous remarquerez que j'ai exprimé la capacité de la ''prefetch input queue'' en octets et non en instructions. La raison est que sur les processeurs x86, les instructions sont de taille variable. Les instructions de ces processeurs ont une taille qui varie entre deux octets et 6 octets. La ''prefetch input queue'' était optimisée pour lire des instructions de deux octets, avec quelques mécanismes pour gérer les instructions plus longues. Il faut dire que les instructions les plus courantes faisaient deux octets, respectivement un octet d'opcode et un octet Mod/RM pour préciser le mode d'adressage. Le bus de données du 8086 faisait 16 bits, ce qui fait qu'il était possible de charger une instruction courte en un cycle. Par contre, sur le 8088, un processeur 8 bits, le bus de donnée ne permettait que de lire un octet à la fois. Dans les deux cas, le décodeur devait attendre que les deux octets d'une instruction soient disponibles dans la ''Prefetch input queue''. Pour cela, un circuit appelé le ''loader'' fournissait deux signaux au décodeur d'instruction : l'un indiquant que le premier octet est déjà chargé, l'autre indiquant que le second octet est disponible. Le ''loader'' recevait aussi des signaux de la part du décodeur d'instruction, afin de gérer les lectures dans la ''Prefetch input queue''. Le décodeur envoyait le signal ''Run Next Instruction'' pour lire une instruction : elle était alors dépilée de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'' un cycle en avance, un cucle avant que l'instruction en cours ne termine. Le résultat est que le ''loader'' réagissait en préchargeant l'instruction suivante. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Pour gérer les instructions de plus de deux octets, le décodeur pouvait lire une instruction en plusieurs fois dans la ''Prefetch input queue''. Les deux premiers octets sont lus depuis la ''Prefetch input queue'', et sont alors décodés. Le décodeur détermine alors la taille de l'instruction. Si l'instruction fait exactement deux octets, elle est exécutée directement. Sinon, les octets manquants sont lus depuis la ''Prefetch input queue''. Pour cela, le décodeur dispose d'une micro-opération pour lire un octet depuis la ''Prefetch input queue''. Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Pour cela, le décodeur d'instruction dispose d'une micro-opération qui vide la ''Prefetch input queue'', elle invalide les instructions préchargées. Cette détection ne peut se faire qu'une fois le branchement décodé, qu'une fois que l'on sait que l'instruction décodée est un branchement. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Il faut noter qu'une ''Prefetch input queue'' interagit assez mal avec le ''program counter''. En effet, la ''Prefetch input queue'' précharge les instructions séquentiellement. Pour savoir où elle en est rendue, elle mémorise l'adresse de la prochaine instruction à charger dans un '''registre de préchargement''' dédié. Il serait possible d'utiliser un ''program counter'' en plus du registre de préchargement, mais ce n'est pas la solution qui a été utilisée. Les processeurs Intel anciens ont préféré n'utiliser qu'un seul registre de préchargement en remplacement du ''program counter''. Après tout, le registre de préchargement n'est qu'un ''program counter'' ayant pris une avance de quelques cycles d'horloge, qui a été incrémenté en avance. Et cela ne pose pas de problèmes, sauf avec certains branchements. Par exemple, certains branchements relatifs demandent de connaitre la véritable valeur du ''program counter'', pas celle calculée en avance. Idem avec les instructions d'appel de fonction, qui demandent de sauvegarder l'adresse de retour exacte, donc le vrai ''program counter''. De telles situations demandent de connaitre la valeur réelle du ''program counter'', celle sans préchargement. Pour cela, le décodeur d'instruction dispose d'une instruction pour reconstituer le ''program counter'', à savoir corriger le ''program coutner'' et éliminer l'effet du préchargement. La micro-opération de correction se contente de soustraire le nombre d'octets préchargés au registre de préchargement. Le nombre d'octets préchargés est déduit à partir des deux pointeurs intégré à la FIFO, qui indiquent la position du premier et du dernier octet préchargé. Le bit qui indique si la FIFO est vide était aussi utilisé. Les deux pointeurs sont lus depuis la FIFO, et sont envoyés à un circuit qui détermine le nombre d'octets préchargés. Sur le 8086, ce circuit était implémenté non pas par un circuit combinatoire, mais par une mémoire ROM équivalente. La petite taille de la FIFO faisait que les pointeurs étaient très petits et la ROM l'était aussi. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. Le décodeur d'instruction dispose aussi d'une micro-opération qui stoppe le préchargement des instructions dans la ''Prefetch input queue''. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> 8p8poj6b7qnolqapwfx4nijpg8iirw0 744082 744080 2025-06-03T19:42:16Z Mewtow 31375 /* La prefetch input queue */ 744082 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement, qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un octet à la fois. En conséquence, le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. L'idée est que pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peut en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. En conséquence, il arrive que la 'prefetch input queue'' n'ait pas préchargé l'instruction suivante, alors que le décodeur d'instruction est prêt pour la décoder. Dans ce cas, le décodeur doit attendre que l'instruction soit chargée. Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser une ''prefetch input queue'' était le 8086. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons expliquer dans quelques paragraphes. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Vous remarquerez que j'ai exprimé la capacité de la ''prefetch input queue'' en octets et non en instructions. La raison est que sur les processeurs x86, les instructions sont de taille variable. Les instructions de ces processeurs ont une taille qui varie entre deux octets et 6 octets. La ''prefetch input queue'' était optimisée pour lire des instructions de deux octets, avec quelques mécanismes pour gérer les instructions plus longues. Il faut dire que les instructions les plus courantes faisaient deux octets, respectivement un octet d'opcode et un octet Mod/RM pour préciser le mode d'adressage. Le bus de données du 8086 faisait 16 bits, ce qui fait qu'il était possible de charger une instruction courte en un cycle. Par contre, sur le 8088, un processeur 8 bits, le bus de donnée ne permettait que de lire un octet à la fois. Dans les deux cas, le décodeur devait attendre que les deux octets d'une instruction soient disponibles dans la ''Prefetch input queue''. Pour cela, un circuit appelé le ''loader'' fournissait deux signaux au décodeur d'instruction : l'un indiquant que le premier octet est déjà chargé, l'autre indiquant que le second octet est disponible. Le ''loader'' recevait aussi des signaux de la part du décodeur d'instruction, afin de gérer les lectures dans la ''Prefetch input queue''. Le décodeur envoyait le signal ''Run Next Instruction'' pour lire une instruction : elle était alors dépilée de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'' un cycle en avance, un cucle avant que l'instruction en cours ne termine. Le résultat est que le ''loader'' réagissait en préchargeant l'instruction suivante. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Pour gérer les instructions de plus de deux octets, le décodeur pouvait lire une instruction en plusieurs fois dans la ''Prefetch input queue''. Les deux premiers octets sont lus depuis la ''Prefetch input queue'', et sont alors décodés. Le décodeur détermine alors la taille de l'instruction. Si l'instruction fait exactement deux octets, elle est exécutée directement. Sinon, les octets manquants sont lus depuis la ''Prefetch input queue''. Pour cela, le décodeur dispose d'une micro-opération pour lire un octet depuis la ''Prefetch input queue''. Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Pour cela, le décodeur d'instruction dispose d'une micro-opération qui vide la ''Prefetch input queue'', elle invalide les instructions préchargées. Cette détection ne peut se faire qu'une fois le branchement décodé, qu'une fois que l'on sait que l'instruction décodée est un branchement. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Il faut noter qu'une ''Prefetch input queue'' interagit assez mal avec le ''program counter''. En effet, la ''Prefetch input queue'' précharge les instructions séquentiellement. Pour savoir où elle en est rendue, elle mémorise l'adresse de la prochaine instruction à charger dans un '''registre de préchargement''' dédié. Il serait possible d'utiliser un ''program counter'' en plus du registre de préchargement, mais ce n'est pas la solution qui a été utilisée. Les processeurs Intel anciens ont préféré n'utiliser qu'un seul registre de préchargement en remplacement du ''program counter''. Après tout, le registre de préchargement n'est qu'un ''program counter'' ayant pris une avance de quelques cycles d'horloge, qui a été incrémenté en avance. Et cela ne pose pas de problèmes, sauf avec certains branchements. Par exemple, certains branchements relatifs demandent de connaitre la véritable valeur du ''program counter'', pas celle calculée en avance. Idem avec les instructions d'appel de fonction, qui demandent de sauvegarder l'adresse de retour exacte, donc le vrai ''program counter''. De telles situations demandent de connaitre la valeur réelle du ''program counter'', celle sans préchargement. Pour cela, le décodeur d'instruction dispose d'une instruction pour reconstituer le ''program counter'', à savoir corriger le ''program coutner'' et éliminer l'effet du préchargement. La micro-opération de correction se contente de soustraire le nombre d'octets préchargés au registre de préchargement. Le nombre d'octets préchargés est déduit à partir des deux pointeurs intégré à la FIFO, qui indiquent la position du premier et du dernier octet préchargé. Le bit qui indique si la FIFO est vide était aussi utilisé. Les deux pointeurs sont lus depuis la FIFO, et sont envoyés à un circuit qui détermine le nombre d'octets préchargés. Sur le 8086, ce circuit était implémenté non pas par un circuit combinatoire, mais par une mémoire ROM équivalente. La petite taille de la FIFO faisait que les pointeurs étaient très petits et la ROM l'était aussi. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. Le décodeur d'instruction dispose aussi d'une micro-opération qui stoppe le préchargement des instructions dans la ''Prefetch input queue''. : Pour ceux qui ont déjà lu un cours d'architecture des ordinateurs, la relation entre ''prefetch input queue'' et pipeline est quelque peu complexe. En apparence, la ''prefetch input queue'' permet une certaines forme de pipeline, en chargeant une instruction pendant que la précédente s'exécute. Les problématiques liées aux branchements ressemblent beaucoup à celles de la prédiction de branchement. Cependant, il est possible de dire qu'il s'agit plus d'une technique de préchargement que de pipeline. La différence entre les deux est assez subtile et les frontières sont assez floues, mais le fait est que l'instruction en cours d'exécution et le préchargement peuvent tout deux faire des accès mémoire et que l'instruction en cours a la priorité. Un vrai pipeline se débrouillerait avec une architecture Harvard, non avec un bus mémoire unique pour le chargement des instruction et la lecture/écriture des données. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> qa5rniqtk29ctw095nzv0r4bt1szk60 744083 744082 2025-06-03T19:49:46Z Mewtow 31375 /* La prefetch input queue */ 744083 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement, qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un octet à la fois. En conséquence, le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. L'idée est que pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peut en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. En conséquence, il arrive que la ''prefetch input queue'' n'ait pas préchargé l'instruction suivante, alors que le décodeur d'instruction est prêt pour la décoder. Dans ce cas, le décodeur doit attendre que l'instruction soit chargée. Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser une ''prefetch input queue'' était le 8086. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons expliquer dans quelques paragraphes. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Vous remarquerez que j'ai exprimé la capacité de la ''prefetch input queue'' en octets et non en instructions. La raison est que sur les processeurs x86, les instructions sont de taille variable. Les instructions de ces processeurs ont une taille qui varie entre deux octets et 6 octets. La ''prefetch input queue'' était optimisée pour lire des instructions de deux octets, avec quelques mécanismes pour gérer les instructions plus longues. Il faut dire que les instructions les plus courantes faisaient deux octets, respectivement un octet d'opcode et un octet Mod/RM pour préciser le mode d'adressage. Le bus de données du 8086 faisait 16 bits, ce qui fait qu'il était possible de charger une instruction courte en un cycle. Par contre, sur le 8088, un processeur 8 bits, le bus de donnée ne permettait que de lire un octet à la fois. Dans les deux cas, le décodeur devait attendre que les deux octets d'une instruction soient disponibles dans la ''Prefetch input queue''. Pour cela, un circuit appelé le ''loader'' fournissait deux signaux au décodeur d'instruction : l'un indiquant que le premier octet est déjà chargé, l'autre indiquant que le second octet est disponible. Le ''loader'' recevait aussi des signaux de la part du décodeur d'instruction, afin de gérer les lectures dans la ''Prefetch input queue''. Le décodeur envoyait le signal ''Run Next Instruction'' pour lire une instruction : elle était alors dépilée de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'' un cycle en avance, un cycle avant que l'instruction en cours ne termine. Le résultat est que le ''loader'' réagissait en préchargeant l'instruction suivante. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Pour gérer les instructions de plus de deux octets, le décodeur pouvait lire une instruction en plusieurs fois dans la ''Prefetch input queue''. Les deux premiers octets sont lus depuis la ''Prefetch input queue'', et sont alors décodés. Le décodeur détermine alors la taille de l'instruction. Si l'instruction fait exactement deux octets, elle est exécutée directement. Sinon, les octets manquants sont lus depuis la ''Prefetch input queue''. Pour cela, le décodeur dispose d'une micro-opération pour lire un octet depuis la ''Prefetch input queue''. Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Pour cela, le décodeur d'instruction dispose d'une micro-opération qui vide la ''Prefetch input queue'', elle invalide les instructions préchargées. Cette détection ne peut se faire qu'une fois le branchement décodé, qu'une fois que l'on sait que l'instruction décodée est un branchement. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Il faut noter qu'une ''Prefetch input queue'' interagit assez mal avec le ''program counter''. En effet, la ''Prefetch input queue'' précharge les instructions séquentiellement. Pour savoir où elle en est rendue, elle mémorise l'adresse de la prochaine instruction à charger dans un '''registre de préchargement''' dédié. Il serait possible d'utiliser un ''program counter'' en plus du registre de préchargement, mais ce n'est pas la solution qui a été utilisée. Les processeurs Intel anciens ont préféré n'utiliser qu'un seul registre de préchargement en remplacement du ''program counter''. Après tout, le registre de préchargement n'est qu'un ''program counter'' ayant pris une avance de quelques cycles d'horloge, qui a été incrémenté en avance. Et cela ne pose pas de problèmes, sauf avec certains branchements. Par exemple, certains branchements relatifs demandent de connaitre la véritable valeur du ''program counter'', pas celle calculée en avance. Idem avec les instructions d'appel de fonction, qui demandent de sauvegarder l'adresse de retour exacte, donc le vrai ''program counter''. De telles situations demandent de connaitre la valeur réelle du ''program counter'', celle sans préchargement. Pour cela, le décodeur d'instruction dispose d'une instruction pour reconstituer le ''program counter'', à savoir corriger le ''program coutner'' et éliminer l'effet du préchargement. La micro-opération de correction se contente de soustraire le nombre d'octets préchargés au registre de préchargement. Le nombre d'octets préchargés est déduit à partir des deux pointeurs intégré à la FIFO, qui indiquent la position du premier et du dernier octet préchargé. Le bit qui indique si la FIFO est vide était aussi utilisé. Les deux pointeurs sont lus depuis la FIFO, et sont envoyés à un circuit qui détermine le nombre d'octets préchargés. Sur le 8086, ce circuit était implémenté non pas par un circuit combinatoire, mais par une mémoire ROM équivalente. La petite taille de la FIFO faisait que les pointeurs étaient très petits et la ROM l'était aussi. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. Le décodeur d'instruction dispose aussi d'une micro-opération qui stoppe le préchargement des instructions dans la ''Prefetch input queue''. : Pour ceux qui ont déjà lu un cours d'architecture des ordinateurs, la relation entre ''prefetch input queue'' et pipeline est quelque peu complexe. En apparence, la ''prefetch input queue'' permet une certaines forme de pipeline, en chargeant une instruction pendant que la précédente s'exécute. Les problématiques liées aux branchements ressemblent beaucoup à celles de la prédiction de branchement. Cependant, il est possible de dire qu'il s'agit plus d'une technique de préchargement que de pipeline. La différence entre les deux est assez subtile et les frontières sont assez floues, mais le fait est que l'instruction en cours d'exécution et le préchargement peuvent tout deux faire des accès mémoire et que l'instruction en cours a la priorité. Un vrai pipeline se débrouillerait avec une architecture Harvard, non avec un bus mémoire unique pour le chargement des instruction et la lecture/écriture des données. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> oelta66ka8fz8uixp5g6y5jba1wibom 744084 744083 2025-06-03T20:03:58Z Mewtow 31375 /* La prefetch input queue */ 744084 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement, qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un octet à la fois. En conséquence, le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. L'idée est que pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peut en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. En conséquence, il arrive que la ''prefetch input queue'' n'ait pas préchargé l'instruction suivante, alors que le décodeur d'instruction est prêt pour la décoder. Dans ce cas, le décodeur doit attendre que l'instruction soit chargée. Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser une ''prefetch input queue'' était le 8086. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons expliquer dans quelques paragraphes. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Vous remarquerez que j'ai exprimé la capacité de la ''prefetch input queue'' en octets et non en instructions. La raison est que sur les processeurs x86, les instructions sont de taille variable. Les instructions de ces processeurs ont une taille qui varie entre un octet et 6 octets. Le bus de données du 8086 faisait 16 bits, ce qui fait qu'il était possible de charger une instruction courte en un cycle. Par contre, sur le 8088, un processeur 8 bits, le bus de donnée ne permettait que de lire un octet à la fois. La ''prefetch input queue'' du 8086 avait un port d'écriture 16 bits relié à la RAM et un port de lecture de 8 bits relié au décodeur. La ''prefetch input queue'' avait des ports de 8 bits uniquement. Le décodage des instructions se faisait un octet à la fois : le décodeur lisait un octet, puis éventuellement le suivant, et ainsi de suite. Pour gérer les instructions de plus deux octets ou plus, le décodeur pouvait lire une instruction en plusieurs fois dans la ''Prefetch input queue''. Pour cela, le décodeur dispose d'une micro-opération pour lire un octet depuis la ''Prefetch input queue''. Un circuit appelé le ''loader'' synchronisait le décodeur d'instruction et la ''Prefetch input queue''. Il fournissait un bit qui indiquait si le premier octet d'une instruction était disponible dans la ''Prefetch input queue''. Un second bit indiquait si l'octet suivant était disponible, nous verrons pourquoi dans ce qui suit. Le ''loader'' recevait aussi des signaux de la part du décodeur d'instruction, afin de gérer la micro-opération de lecture dans la ''Prefetch input queue''. Le décodeur envoyait le signal ''Run Next Instruction'' pour lire une instruction, qui était alors dépilée de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'', un cycle avant que l'instruction en cours ne termine. Le ''loader'' réagissait en préchargeant l'octet suivant. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Le décodeur devait attendre que qu'un moins un octet soit disponible dans la ''Prefetch input queue'', pour le lire. Il lisait alors cet octet et déterminait s'il contenait une instruction complète ou non. Si c'est une instruction complète, il la décodait et l''exécutait, puis envoyait un signal ''Run Next Instruction'' pour commencer le décodage de l'instruction suivante. Sinon, il lit un second octet depuis la ''Prefetch input queue'', le copie dans le registre d'instruction, et relance le décodage. Là encore, le décodeur vérifie s'il a une instruction complète, et lit un troisième octet si besoin, puis rebelote avec un quatrième octet lu, etc. Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Pour cela, le décodeur d'instruction dispose d'une micro-opération qui vide la ''Prefetch input queue'', elle invalide les instructions préchargées. Cette détection ne peut se faire qu'une fois le branchement décodé, qu'une fois que l'on sait que l'instruction décodée est un branchement. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Il faut noter qu'une ''Prefetch input queue'' interagit assez mal avec le ''program counter''. En effet, la ''Prefetch input queue'' précharge les instructions séquentiellement. Pour savoir où elle en est rendue, elle mémorise l'adresse de la prochaine instruction à charger dans un '''registre de préchargement''' dédié. Il serait possible d'utiliser un ''program counter'' en plus du registre de préchargement, mais ce n'est pas la solution qui a été utilisée. Les processeurs Intel anciens ont préféré n'utiliser qu'un seul registre de préchargement en remplacement du ''program counter''. Après tout, le registre de préchargement n'est qu'un ''program counter'' ayant pris une avance de quelques cycles d'horloge, qui a été incrémenté en avance. Et cela ne pose pas de problèmes, sauf avec certains branchements. Par exemple, certains branchements relatifs demandent de connaitre la véritable valeur du ''program counter'', pas celle calculée en avance. Idem avec les instructions d'appel de fonction, qui demandent de sauvegarder l'adresse de retour exacte, donc le vrai ''program counter''. De telles situations demandent de connaitre la valeur réelle du ''program counter'', celle sans préchargement. Pour cela, le décodeur d'instruction dispose d'une instruction pour reconstituer le ''program counter'', à savoir corriger le ''program coutner'' et éliminer l'effet du préchargement. La micro-opération de correction se contente de soustraire le nombre d'octets préchargés au registre de préchargement. Le nombre d'octets préchargés est déduit à partir des deux pointeurs intégré à la FIFO, qui indiquent la position du premier et du dernier octet préchargé. Le bit qui indique si la FIFO est vide était aussi utilisé. Les deux pointeurs sont lus depuis la FIFO, et sont envoyés à un circuit qui détermine le nombre d'octets préchargés. Sur le 8086, ce circuit était implémenté non pas par un circuit combinatoire, mais par une mémoire ROM équivalente. La petite taille de la FIFO faisait que les pointeurs étaient très petits et la ROM l'était aussi. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. Le décodeur d'instruction dispose aussi d'une micro-opération qui stoppe le préchargement des instructions dans la ''Prefetch input queue''. : Pour ceux qui ont déjà lu un cours d'architecture des ordinateurs, la relation entre ''prefetch input queue'' et pipeline est quelque peu complexe. En apparence, la ''prefetch input queue'' permet une certaines forme de pipeline, en chargeant une instruction pendant que la précédente s'exécute. Les problématiques liées aux branchements ressemblent beaucoup à celles de la prédiction de branchement. Cependant, il est possible de dire qu'il s'agit plus d'une technique de préchargement que de pipeline. La différence entre les deux est assez subtile et les frontières sont assez floues, mais le fait est que l'instruction en cours d'exécution et le préchargement peuvent tout deux faire des accès mémoire et que l'instruction en cours a la priorité. Un vrai pipeline se débrouillerait avec une architecture Harvard, non avec un bus mémoire unique pour le chargement des instruction et la lecture/écriture des données. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> m6qgnwudqrjf61xcazxq328jlgrwogz 744085 744084 2025-06-03T20:09:03Z Mewtow 31375 /* La prefetch input queue */ 744085 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement, qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un octet à la fois. En conséquence, le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. L'idée est que pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peut en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. En conséquence, il arrive que la ''prefetch input queue'' n'ait pas préchargé l'instruction suivante, alors que le décodeur d'instruction est prêt pour la décoder. Dans ce cas, le décodeur doit attendre que l'instruction soit chargée. Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser une ''prefetch input queue'' était le 8086. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons expliquer dans quelques paragraphes. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Vous remarquerez que j'ai exprimé la capacité de la ''prefetch input queue'' en octets et non en instructions. La raison est que sur les processeurs x86, les instructions sont de taille variable. Les instructions de ces processeurs ont une taille qui varie entre un octet et 6 octets. Le décodage des instructions se faisait un octet à la fois : le décodeur lisait un octet, puis éventuellement le suivant, et ainsi de suite. Pour gérer les instructions de plus deux octets ou plus, le décodeur pouvait lire une instruction en plusieurs fois dans la ''Prefetch input queue''. Pour cela, le décodeur dispose d'une micro-opération pour lire un octet depuis la ''Prefetch input queue''. Un circuit appelé le ''loader'' synchronisait le décodeur d'instruction et la ''Prefetch input queue''. Il fournissait un bit qui indiquait si le premier octet d'une instruction était disponible dans la ''Prefetch input queue''. Un second bit indiquait si l'octet suivant était disponible, nous verrons pourquoi dans ce qui suit. Le ''loader'' recevait aussi des signaux de la part du décodeur d'instruction, afin de gérer la micro-opération de lecture dans la ''Prefetch input queue''. Le décodeur envoyait le signal ''Run Next Instruction'' pour lire une instruction, qui était alors dépilée de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'', un cycle avant que l'instruction en cours ne termine. Le ''loader'' réagissait en préchargeant l'octet suivant. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Le décodeur devait attendre que qu'un moins un octet soit disponible dans la ''Prefetch input queue'', pour le lire. Il lisait alors cet octet et déterminait s'il contenait une instruction complète ou non. Si c'est une instruction complète, il la décodait et l''exécutait, puis envoyait un signal ''Run Next Instruction'' pour commencer le décodage de l'instruction suivante. Sinon, il lit un second octet depuis la ''Prefetch input queue'', le copie dans le registre d'instruction, et relance le décodage. Là encore, le décodeur vérifie s'il a une instruction complète, et lit un troisième octet si besoin, puis rebelote avec un quatrième octet lu, etc. Le bus de données du 8086 faisait 16 bits, alors que celui du 8088 ne permettait que de lire un octet à la fois. Et cela avait un impact sur la ''prefetch input queue''. La ''prefetch input queue'' était composée de 4 registres de 8 bits, avec un port d'écriture de 8 bits pour précharger les instructions octet par octet, et un port de lecture de 8 bits pour alimenter le décodeur. En clair, tout faisait 8 bits. Le 8086, lui utilisait des registres de 16 bits et un port d'écriture de 16 bits. Sa ''prefetch input queue'' préchargeait les instructions par paquets de 2 octets, non octet par octet, alors que le décodeur consommait les instructions octet par octet. Il s’agissait donc d'une sorte d'intermédiaire entre ''prefetch input queue'' à la 8088 et tampon de préchargement. Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Pour cela, le décodeur d'instruction dispose d'une micro-opération qui vide la ''Prefetch input queue'', elle invalide les instructions préchargées. Cette détection ne peut se faire qu'une fois le branchement décodé, qu'une fois que l'on sait que l'instruction décodée est un branchement. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Il faut noter qu'une ''Prefetch input queue'' interagit assez mal avec le ''program counter''. En effet, la ''Prefetch input queue'' précharge les instructions séquentiellement. Pour savoir où elle en est rendue, elle mémorise l'adresse de la prochaine instruction à charger dans un '''registre de préchargement''' dédié. Il serait possible d'utiliser un ''program counter'' en plus du registre de préchargement, mais ce n'est pas la solution qui a été utilisée. Les processeurs Intel anciens ont préféré n'utiliser qu'un seul registre de préchargement en remplacement du ''program counter''. Après tout, le registre de préchargement n'est qu'un ''program counter'' ayant pris une avance de quelques cycles d'horloge, qui a été incrémenté en avance. Et cela ne pose pas de problèmes, sauf avec certains branchements. Par exemple, certains branchements relatifs demandent de connaitre la véritable valeur du ''program counter'', pas celle calculée en avance. Idem avec les instructions d'appel de fonction, qui demandent de sauvegarder l'adresse de retour exacte, donc le vrai ''program counter''. De telles situations demandent de connaitre la valeur réelle du ''program counter'', celle sans préchargement. Pour cela, le décodeur d'instruction dispose d'une instruction pour reconstituer le ''program counter'', à savoir corriger le ''program coutner'' et éliminer l'effet du préchargement. La micro-opération de correction se contente de soustraire le nombre d'octets préchargés au registre de préchargement. Le nombre d'octets préchargés est déduit à partir des deux pointeurs intégré à la FIFO, qui indiquent la position du premier et du dernier octet préchargé. Le bit qui indique si la FIFO est vide était aussi utilisé. Les deux pointeurs sont lus depuis la FIFO, et sont envoyés à un circuit qui détermine le nombre d'octets préchargés. Sur le 8086, ce circuit était implémenté non pas par un circuit combinatoire, mais par une mémoire ROM équivalente. La petite taille de la FIFO faisait que les pointeurs étaient très petits et la ROM l'était aussi. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. Le décodeur d'instruction dispose aussi d'une micro-opération qui stoppe le préchargement des instructions dans la ''Prefetch input queue''. : Pour ceux qui ont déjà lu un cours d'architecture des ordinateurs, la relation entre ''prefetch input queue'' et pipeline est quelque peu complexe. En apparence, la ''prefetch input queue'' permet une certaines forme de pipeline, en chargeant une instruction pendant que la précédente s'exécute. Les problématiques liées aux branchements ressemblent beaucoup à celles de la prédiction de branchement. Cependant, il est possible de dire qu'il s'agit plus d'une technique de préchargement que de pipeline. La différence entre les deux est assez subtile et les frontières sont assez floues, mais le fait est que l'instruction en cours d'exécution et le préchargement peuvent tout deux faire des accès mémoire et que l'instruction en cours a la priorité. Un vrai pipeline se débrouillerait avec une architecture Harvard, non avec un bus mémoire unique pour le chargement des instruction et la lecture/écriture des données. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> 3n8r252hcdo8mk1fxwskn1wndyvkyr1 744086 744085 2025-06-03T20:11:35Z Mewtow 31375 /* La prefetch input queue */ 744086 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement, qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un octet à la fois. En conséquence, le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. L'idée est que pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peut en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. En conséquence, il arrive que la ''prefetch input queue'' n'ait pas préchargé l'instruction suivante, alors que le décodeur d'instruction est prêt pour la décoder. Dans ce cas, le décodeur doit attendre que l'instruction soit chargée. Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser une ''prefetch input queue'' était le 8086. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons expliquer dans quelques paragraphes. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Vous remarquerez que j'ai exprimé la capacité de la ''prefetch input queue'' en octets et non en instructions. La raison est que sur les processeurs x86, les instructions sont de taille variable, avec une taille qui varie entre un octet et 6 octets. Cependant, le décodage des instructions se fait un octet à la fois : le décodeur lit un octet, puis éventuellement le suivant, et ainsi de suite jusqu'à atteindre la fin de l'instruction. En clair, le décodeur lits les instructions longues octet par octet dans la ''Prefetch input queue''. Pour cela, le décodeur dispose d'une micro-opération pour lire un octet depuis la ''Prefetch input queue''. Le décodeur devait attendre que qu'un moins un octet soit disponible dans la ''Prefetch input queue'', pour le lire. Il lisait alors cet octet et déterminait s'il contenait une instruction complète ou non. Si c'est une instruction complète, il la décodait et l''exécutait, puis passait à l'instruction suivante. Sinon, il lit un second octet depuis la ''Prefetch input queue'', le copie dans le registre d'instruction, et relance le décodage. Là encore, le décodeur vérifie s'il a une instruction complète, et lit un troisième octet si besoin, puis rebelote avec un quatrième octet lu, etc. Un circuit appelé le ''loader'' synchronisait le décodeur d'instruction et la ''Prefetch input queue''. Il fournissait un bit qui indiquait si le premier octet d'une instruction était disponible dans la ''Prefetch input queue''. Un second bit indiquait si l'octet suivant était disponible, nous verrons pourquoi dans ce qui suit. Le ''loader'' recevait aussi des signaux de la part du décodeur d'instruction. Le décodeur envoyait le signal ''Run Next Instruction'' pour lire une instruction, qui était alors dépilée de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'', un cycle avant que l'instruction en cours ne termine. Le ''loader'' réagissait en préchargeant l'octet suivant. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Le bus de données du 8086 faisait 16 bits, alors que celui du 8088 ne permettait que de lire un octet à la fois. Et cela avait un impact sur la ''prefetch input queue''. La ''prefetch input queue'' était composée de 4 registres de 8 bits, avec un port d'écriture de 8 bits pour précharger les instructions octet par octet, et un port de lecture de 8 bits pour alimenter le décodeur. En clair, tout faisait 8 bits. Le 8086, lui utilisait des registres de 16 bits et un port d'écriture de 16 bits. Sa ''prefetch input queue'' préchargeait les instructions par paquets de 2 octets, non octet par octet, alors que le décodeur consommait les instructions octet par octet. Il s’agissait donc d'une sorte d'intermédiaire entre ''prefetch input queue'' à la 8088 et tampon de préchargement. Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Pour cela, le décodeur d'instruction dispose d'une micro-opération qui vide la ''Prefetch input queue'', elle invalide les instructions préchargées. Cette détection ne peut se faire qu'une fois le branchement décodé, qu'une fois que l'on sait que l'instruction décodée est un branchement. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Il faut noter qu'une ''Prefetch input queue'' interagit assez mal avec le ''program counter''. En effet, la ''Prefetch input queue'' précharge les instructions séquentiellement. Pour savoir où elle en est rendue, elle mémorise l'adresse de la prochaine instruction à charger dans un '''registre de préchargement''' dédié. Il serait possible d'utiliser un ''program counter'' en plus du registre de préchargement, mais ce n'est pas la solution qui a été utilisée. Les processeurs Intel anciens ont préféré n'utiliser qu'un seul registre de préchargement en remplacement du ''program counter''. Après tout, le registre de préchargement n'est qu'un ''program counter'' ayant pris une avance de quelques cycles d'horloge, qui a été incrémenté en avance. Et cela ne pose pas de problèmes, sauf avec certains branchements. Par exemple, certains branchements relatifs demandent de connaitre la véritable valeur du ''program counter'', pas celle calculée en avance. Idem avec les instructions d'appel de fonction, qui demandent de sauvegarder l'adresse de retour exacte, donc le vrai ''program counter''. De telles situations demandent de connaitre la valeur réelle du ''program counter'', celle sans préchargement. Pour cela, le décodeur d'instruction dispose d'une instruction pour reconstituer le ''program counter'', à savoir corriger le ''program coutner'' et éliminer l'effet du préchargement. La micro-opération de correction se contente de soustraire le nombre d'octets préchargés au registre de préchargement. Le nombre d'octets préchargés est déduit à partir des deux pointeurs intégré à la FIFO, qui indiquent la position du premier et du dernier octet préchargé. Le bit qui indique si la FIFO est vide était aussi utilisé. Les deux pointeurs sont lus depuis la FIFO, et sont envoyés à un circuit qui détermine le nombre d'octets préchargés. Sur le 8086, ce circuit était implémenté non pas par un circuit combinatoire, mais par une mémoire ROM équivalente. La petite taille de la FIFO faisait que les pointeurs étaient très petits et la ROM l'était aussi. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. Le décodeur d'instruction dispose aussi d'une micro-opération qui stoppe le préchargement des instructions dans la ''Prefetch input queue''. : Pour ceux qui ont déjà lu un cours d'architecture des ordinateurs, la relation entre ''prefetch input queue'' et pipeline est quelque peu complexe. En apparence, la ''prefetch input queue'' permet une certaines forme de pipeline, en chargeant une instruction pendant que la précédente s'exécute. Les problématiques liées aux branchements ressemblent beaucoup à celles de la prédiction de branchement. Cependant, il est possible de dire qu'il s'agit plus d'une technique de préchargement que de pipeline. La différence entre les deux est assez subtile et les frontières sont assez floues, mais le fait est que l'instruction en cours d'exécution et le préchargement peuvent tout deux faire des accès mémoire et que l'instruction en cours a la priorité. Un vrai pipeline se débrouillerait avec une architecture Harvard, non avec un bus mémoire unique pour le chargement des instruction et la lecture/écriture des données. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> k8w6zf2i1y3g41vvft5knewnvnucdkc 744087 744086 2025-06-03T20:12:31Z Mewtow 31375 /* La prefetch input queue */ 744087 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement, qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un octet à la fois. En conséquence, le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. L'idée est que pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peut en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. En conséquence, il arrive que la ''prefetch input queue'' n'ait pas préchargé l'instruction suivante, alors que le décodeur d'instruction est prêt pour la décoder. Dans ce cas, le décodeur doit attendre que l'instruction soit chargée. Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser une ''prefetch input queue'' était le 8086. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons expliquer dans quelques paragraphes. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Vous remarquerez que j'ai exprimé la capacité de la ''prefetch input queue'' en octets et non en instructions. La raison est que sur les processeurs x86, les instructions sont de taille variable, avec une taille qui varie entre un octet et 6 octets. Cependant, le décodage des instructions se fait un octet à la fois : le décodeur lit un octet, puis éventuellement le suivant, et ainsi de suite jusqu'à atteindre la fin de l'instruction. En clair, le décodeur lits les instructions longues octet par octet dans la ''Prefetch input queue''. Pour cela, le décodeur dispose d'une micro-opération pour lire un octet depuis la ''Prefetch input queue''. Le décodeur devait attendre que qu'un moins un octet soit disponible dans la ''Prefetch input queue'', pour le lire. Il lisait alors cet octet et déterminait s'il contenait une instruction complète ou non. Si c'est une instruction complète, il la décodait et l''exécutait, puis passait à l'instruction suivante. Sinon, il lit un second octet depuis la ''Prefetch input queue'', le copie dans le registre d'instruction, et relance le décodage. Là encore, le décodeur vérifie s'il a une instruction complète, et lit un troisième octet si besoin, puis rebelote avec un quatrième octet lu, etc. Un circuit appelé le ''loader'' synchronisait le décodeur d'instruction et la ''Prefetch input queue''. Il fournissait un bit qui indiquait si le premier octet d'une instruction était disponible dans la ''Prefetch input queue''. Un second bit indiquait si l'octet suivant était disponible, nous verrons pourquoi dans ce qui suit. Le ''loader'' recevait aussi des signaux de la part du décodeur d'instruction. Le décodeur envoyait le signal ''Run Next Instruction'' pour lire une instruction, qui était alors dépilée de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'', un cycle avant que l'instruction en cours ne termine. Le ''loader'' réagissait en préchargeant l'octet suivant. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Le bus de données du 8086 faisait 16 bits, alors que celui du 8088 ne permettait que de lire un octet à la fois. Et cela avait un impact sur la ''prefetch input queue''. La ''prefetch input queue'' était composée de 4 registres de 8 bits, avec un port d'écriture de 8 bits pour précharger les instructions octet par octet, et un port de lecture de 8 bits pour alimenter le décodeur. En clair, tout faisait 8 bits. Le 8086, lui utilisait des registres de 16 bits et un port d'écriture de 16 bits. le port de lecture restait de 8 bits, et était précédé d'un multiplexeur qui prenait 16 bits et sélectionnait l'octet adéquat. Sa ''prefetch input queue'' préchargeait les instructions par paquets de 2 octets, non octet par octet, alors que le décodeur consommait les instructions octet par octet. Il s’agissait donc d'une sorte d'intermédiaire entre ''prefetch input queue'' à la 8088 et tampon de préchargement. Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Pour cela, le décodeur d'instruction dispose d'une micro-opération qui vide la ''Prefetch input queue'', elle invalide les instructions préchargées. Cette détection ne peut se faire qu'une fois le branchement décodé, qu'une fois que l'on sait que l'instruction décodée est un branchement. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Il faut noter qu'une ''Prefetch input queue'' interagit assez mal avec le ''program counter''. En effet, la ''Prefetch input queue'' précharge les instructions séquentiellement. Pour savoir où elle en est rendue, elle mémorise l'adresse de la prochaine instruction à charger dans un '''registre de préchargement''' dédié. Il serait possible d'utiliser un ''program counter'' en plus du registre de préchargement, mais ce n'est pas la solution qui a été utilisée. Les processeurs Intel anciens ont préféré n'utiliser qu'un seul registre de préchargement en remplacement du ''program counter''. Après tout, le registre de préchargement n'est qu'un ''program counter'' ayant pris une avance de quelques cycles d'horloge, qui a été incrémenté en avance. Et cela ne pose pas de problèmes, sauf avec certains branchements. Par exemple, certains branchements relatifs demandent de connaitre la véritable valeur du ''program counter'', pas celle calculée en avance. Idem avec les instructions d'appel de fonction, qui demandent de sauvegarder l'adresse de retour exacte, donc le vrai ''program counter''. De telles situations demandent de connaitre la valeur réelle du ''program counter'', celle sans préchargement. Pour cela, le décodeur d'instruction dispose d'une instruction pour reconstituer le ''program counter'', à savoir corriger le ''program coutner'' et éliminer l'effet du préchargement. La micro-opération de correction se contente de soustraire le nombre d'octets préchargés au registre de préchargement. Le nombre d'octets préchargés est déduit à partir des deux pointeurs intégré à la FIFO, qui indiquent la position du premier et du dernier octet préchargé. Le bit qui indique si la FIFO est vide était aussi utilisé. Les deux pointeurs sont lus depuis la FIFO, et sont envoyés à un circuit qui détermine le nombre d'octets préchargés. Sur le 8086, ce circuit était implémenté non pas par un circuit combinatoire, mais par une mémoire ROM équivalente. La petite taille de la FIFO faisait que les pointeurs étaient très petits et la ROM l'était aussi. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. Le décodeur d'instruction dispose aussi d'une micro-opération qui stoppe le préchargement des instructions dans la ''Prefetch input queue''. : Pour ceux qui ont déjà lu un cours d'architecture des ordinateurs, la relation entre ''prefetch input queue'' et pipeline est quelque peu complexe. En apparence, la ''prefetch input queue'' permet une certaines forme de pipeline, en chargeant une instruction pendant que la précédente s'exécute. Les problématiques liées aux branchements ressemblent beaucoup à celles de la prédiction de branchement. Cependant, il est possible de dire qu'il s'agit plus d'une technique de préchargement que de pipeline. La différence entre les deux est assez subtile et les frontières sont assez floues, mais le fait est que l'instruction en cours d'exécution et le préchargement peuvent tout deux faire des accès mémoire et que l'instruction en cours a la priorité. Un vrai pipeline se débrouillerait avec une architecture Harvard, non avec un bus mémoire unique pour le chargement des instruction et la lecture/écriture des données. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> btix6ekccls2l2glnwwiv883dacktsf 744088 744087 2025-06-03T20:16:04Z Mewtow 31375 /* La prefetch input queue */ 744088 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement, qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un ou deux octet à la fois. En conséquence, le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. Pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec un tampond e préchargement, le processeur chargeait plusieurs instruction en une seule fois , puis les exécutait les unes après les autres. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peut en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. En conséquence, il arrive que la ''prefetch input queue'' n'ait pas préchargé l'instruction suivante, alors que le décodeur d'instruction est prêt pour la décoder. Dans ce cas, le décodeur doit attendre que l'instruction soit chargée. Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser une ''prefetch input queue'' était le 8086. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons expliquer dans quelques paragraphes. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Vous remarquerez que j'ai exprimé la capacité de la ''prefetch input queue'' en octets et non en instructions. La raison est que sur les processeurs x86, les instructions sont de taille variable, avec une taille qui varie entre un octet et 6 octets. Cependant, le décodage des instructions se fait un octet à la fois : le décodeur lit un octet, puis éventuellement le suivant, et ainsi de suite jusqu'à atteindre la fin de l'instruction. En clair, le décodeur lits les instructions longues octet par octet dans la ''Prefetch input queue''. Pour cela, le décodeur dispose d'une micro-opération pour lire un octet depuis la ''Prefetch input queue''. Le décodeur devait attendre que qu'un moins un octet soit disponible dans la ''Prefetch input queue'', pour le lire. Il lisait alors cet octet et déterminait s'il contenait une instruction complète ou non. Si c'est une instruction complète, il la décodait et l''exécutait, puis passait à l'instruction suivante. Sinon, il lit un second octet depuis la ''Prefetch input queue'', le copie dans le registre d'instruction, et relance le décodage. Là encore, le décodeur vérifie s'il a une instruction complète, et lit un troisième octet si besoin, puis rebelote avec un quatrième octet lu, etc. Un circuit appelé le ''loader'' synchronisait le décodeur d'instruction et la ''Prefetch input queue''. Il fournissait un bit qui indiquait si le premier octet d'une instruction était disponible dans la ''Prefetch input queue''. Un second bit indiquait si l'octet suivant était disponible, nous verrons pourquoi dans ce qui suit. Le ''loader'' recevait aussi des signaux de la part du décodeur d'instruction. Le décodeur envoyait le signal ''Run Next Instruction'' pour lire une instruction, qui était alors dépilée de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'', un cycle avant que l'instruction en cours ne termine. Le ''loader'' réagissait en préchargeant l'octet suivant. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Le bus de données du 8086 faisait 16 bits, alors que celui du 8088 ne permettait que de lire un octet à la fois. Et cela avait un impact sur la ''prefetch input queue''. La ''prefetch input queue'' était composée de 4 registres de 8 bits, avec un port d'écriture de 8 bits pour précharger les instructions octet par octet, et un port de lecture de 8 bits pour alimenter le décodeur. En clair, tout faisait 8 bits. Le 8086, lui utilisait des registres de 16 bits et un port d'écriture de 16 bits. le port de lecture restait de 8 bits, et était précédé d'un multiplexeur qui prenait 16 bits et sélectionnait l'octet adéquat. Sa ''prefetch input queue'' préchargeait les instructions par paquets de 2 octets, non octet par octet, alors que le décodeur consommait les instructions octet par octet. Il s’agissait donc d'une sorte d'intermédiaire entre ''prefetch input queue'' à la 8088 et tampon de préchargement. Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Pour cela, le décodeur d'instruction dispose d'une micro-opération qui vide la ''Prefetch input queue'', elle invalide les instructions préchargées. Cette détection ne peut se faire qu'une fois le branchement décodé, qu'une fois que l'on sait que l'instruction décodée est un branchement. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Il faut noter qu'une ''Prefetch input queue'' interagit assez mal avec le ''program counter''. En effet, la ''Prefetch input queue'' précharge les instructions séquentiellement. Pour savoir où elle en est rendue, elle mémorise l'adresse de la prochaine instruction à charger dans un '''registre de préchargement''' dédié. Il serait possible d'utiliser un ''program counter'' en plus du registre de préchargement, mais ce n'est pas la solution qui a été utilisée. Les processeurs Intel anciens ont préféré n'utiliser qu'un seul registre de préchargement en remplacement du ''program counter''. Après tout, le registre de préchargement n'est qu'un ''program counter'' ayant pris une avance de quelques cycles d'horloge, qui a été incrémenté en avance. Et cela ne pose pas de problèmes, sauf avec certains branchements. Par exemple, certains branchements relatifs demandent de connaitre la véritable valeur du ''program counter'', pas celle calculée en avance. Idem avec les instructions d'appel de fonction, qui demandent de sauvegarder l'adresse de retour exacte, donc le vrai ''program counter''. De telles situations demandent de connaitre la valeur réelle du ''program counter'', celle sans préchargement. Pour cela, le décodeur d'instruction dispose d'une instruction pour reconstituer le ''program counter'', à savoir corriger le ''program coutner'' et éliminer l'effet du préchargement. La micro-opération de correction se contente de soustraire le nombre d'octets préchargés au registre de préchargement. Le nombre d'octets préchargés est déduit à partir des deux pointeurs intégré à la FIFO, qui indiquent la position du premier et du dernier octet préchargé. Le bit qui indique si la FIFO est vide était aussi utilisé. Les deux pointeurs sont lus depuis la FIFO, et sont envoyés à un circuit qui détermine le nombre d'octets préchargés. Sur le 8086, ce circuit était implémenté non pas par un circuit combinatoire, mais par une mémoire ROM équivalente. La petite taille de la FIFO faisait que les pointeurs étaient très petits et la ROM l'était aussi. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. Le décodeur d'instruction dispose aussi d'une micro-opération qui stoppe le préchargement des instructions dans la ''Prefetch input queue''. : Pour ceux qui ont déjà lu un cours d'architecture des ordinateurs, la relation entre ''prefetch input queue'' et pipeline est quelque peu complexe. En apparence, la ''prefetch input queue'' permet une certaines forme de pipeline, en chargeant une instruction pendant que la précédente s'exécute. Les problématiques liées aux branchements ressemblent beaucoup à celles de la prédiction de branchement. Cependant, il est possible de dire qu'il s'agit plus d'une technique de préchargement que de pipeline. La différence entre les deux est assez subtile et les frontières sont assez floues, mais le fait est que l'instruction en cours d'exécution et le préchargement peuvent tout deux faire des accès mémoire et que l'instruction en cours a la priorité. Un vrai pipeline se débrouillerait avec une architecture Harvard, non avec un bus mémoire unique pour le chargement des instruction et la lecture/écriture des données. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> 7opblxsu3i2l2l09pdrb037b4uiisvq 744089 744088 2025-06-03T20:16:39Z Mewtow 31375 /* La prefetch input queue */ 744089 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement, qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un ou deux octet à la fois. En conséquence, le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. Pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec un tampon de préchargement, le processeur chargeait plusieurs instruction en une seule fois, puis les exécutait les unes après les autres. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peut en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. En conséquence, il arrive que la ''prefetch input queue'' n'ait pas préchargé l'instruction suivante, alors que le décodeur d'instruction est prêt pour la décoder. Dans ce cas, le décodeur doit attendre que l'instruction soit chargée. Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser une ''prefetch input queue'' était le 8086. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons expliquer dans quelques paragraphes. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Vous remarquerez que j'ai exprimé la capacité de la ''prefetch input queue'' en octets et non en instructions. La raison est que sur les processeurs x86, les instructions sont de taille variable, avec une taille qui varie entre un octet et 6 octets. Cependant, le décodage des instructions se fait un octet à la fois : le décodeur lit un octet, puis éventuellement le suivant, et ainsi de suite jusqu'à atteindre la fin de l'instruction. En clair, le décodeur lits les instructions longues octet par octet dans la ''Prefetch input queue''. Pour cela, le décodeur dispose d'une micro-opération pour lire un octet depuis la ''Prefetch input queue''. Le décodeur devait attendre que qu'un moins un octet soit disponible dans la ''Prefetch input queue'', pour le lire. Il lisait alors cet octet et déterminait s'il contenait une instruction complète ou non. Si c'est une instruction complète, il la décodait et l''exécutait, puis passait à l'instruction suivante. Sinon, il lit un second octet depuis la ''Prefetch input queue'', le copie dans le registre d'instruction, et relance le décodage. Là encore, le décodeur vérifie s'il a une instruction complète, et lit un troisième octet si besoin, puis rebelote avec un quatrième octet lu, etc. Un circuit appelé le ''loader'' synchronisait le décodeur d'instruction et la ''Prefetch input queue''. Il fournissait un bit qui indiquait si le premier octet d'une instruction était disponible dans la ''Prefetch input queue''. Un second bit indiquait si l'octet suivant était disponible, nous verrons pourquoi dans ce qui suit. Le ''loader'' recevait aussi des signaux de la part du décodeur d'instruction. Le décodeur envoyait le signal ''Run Next Instruction'' pour lire une instruction, qui était alors dépilée de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'', un cycle avant que l'instruction en cours ne termine. Le ''loader'' réagissait en préchargeant l'octet suivant. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Le bus de données du 8086 faisait 16 bits, alors que celui du 8088 ne permettait que de lire un octet à la fois. Et cela avait un impact sur la ''prefetch input queue''. La ''prefetch input queue'' était composée de 4 registres de 8 bits, avec un port d'écriture de 8 bits pour précharger les instructions octet par octet, et un port de lecture de 8 bits pour alimenter le décodeur. En clair, tout faisait 8 bits. Le 8086, lui utilisait des registres de 16 bits et un port d'écriture de 16 bits. le port de lecture restait de 8 bits, et était précédé d'un multiplexeur qui prenait 16 bits et sélectionnait l'octet adéquat. Sa ''prefetch input queue'' préchargeait les instructions par paquets de 2 octets, non octet par octet, alors que le décodeur consommait les instructions octet par octet. Il s’agissait donc d'une sorte d'intermédiaire entre ''prefetch input queue'' à la 8088 et tampon de préchargement. Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Pour cela, le décodeur d'instruction dispose d'une micro-opération qui vide la ''Prefetch input queue'', elle invalide les instructions préchargées. Cette détection ne peut se faire qu'une fois le branchement décodé, qu'une fois que l'on sait que l'instruction décodée est un branchement. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Il faut noter qu'une ''Prefetch input queue'' interagit assez mal avec le ''program counter''. En effet, la ''Prefetch input queue'' précharge les instructions séquentiellement. Pour savoir où elle en est rendue, elle mémorise l'adresse de la prochaine instruction à charger dans un '''registre de préchargement''' dédié. Il serait possible d'utiliser un ''program counter'' en plus du registre de préchargement, mais ce n'est pas la solution qui a été utilisée. Les processeurs Intel anciens ont préféré n'utiliser qu'un seul registre de préchargement en remplacement du ''program counter''. Après tout, le registre de préchargement n'est qu'un ''program counter'' ayant pris une avance de quelques cycles d'horloge, qui a été incrémenté en avance. Et cela ne pose pas de problèmes, sauf avec certains branchements. Par exemple, certains branchements relatifs demandent de connaitre la véritable valeur du ''program counter'', pas celle calculée en avance. Idem avec les instructions d'appel de fonction, qui demandent de sauvegarder l'adresse de retour exacte, donc le vrai ''program counter''. De telles situations demandent de connaitre la valeur réelle du ''program counter'', celle sans préchargement. Pour cela, le décodeur d'instruction dispose d'une instruction pour reconstituer le ''program counter'', à savoir corriger le ''program coutner'' et éliminer l'effet du préchargement. La micro-opération de correction se contente de soustraire le nombre d'octets préchargés au registre de préchargement. Le nombre d'octets préchargés est déduit à partir des deux pointeurs intégré à la FIFO, qui indiquent la position du premier et du dernier octet préchargé. Le bit qui indique si la FIFO est vide était aussi utilisé. Les deux pointeurs sont lus depuis la FIFO, et sont envoyés à un circuit qui détermine le nombre d'octets préchargés. Sur le 8086, ce circuit était implémenté non pas par un circuit combinatoire, mais par une mémoire ROM équivalente. La petite taille de la FIFO faisait que les pointeurs étaient très petits et la ROM l'était aussi. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. Le décodeur d'instruction dispose aussi d'une micro-opération qui stoppe le préchargement des instructions dans la ''Prefetch input queue''. : Pour ceux qui ont déjà lu un cours d'architecture des ordinateurs, la relation entre ''prefetch input queue'' et pipeline est quelque peu complexe. En apparence, la ''prefetch input queue'' permet une certaines forme de pipeline, en chargeant une instruction pendant que la précédente s'exécute. Les problématiques liées aux branchements ressemblent beaucoup à celles de la prédiction de branchement. Cependant, il est possible de dire qu'il s'agit plus d'une technique de préchargement que de pipeline. La différence entre les deux est assez subtile et les frontières sont assez floues, mais le fait est que l'instruction en cours d'exécution et le préchargement peuvent tout deux faire des accès mémoire et que l'instruction en cours a la priorité. Un vrai pipeline se débrouillerait avec une architecture Harvard, non avec un bus mémoire unique pour le chargement des instruction et la lecture/écriture des données. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> hj8zq9a97hto7uddt4ao3kyn9of9e6j 744090 744089 2025-06-03T20:21:32Z Mewtow 31375 /* La prefetch input queue */ 744090 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement, qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un ou deux octet à la fois. En conséquence, le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. Pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec un tampon de préchargement, le processeur chargeait plusieurs instruction en une seule fois, puis les exécutait les unes après les autres. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peut en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. En conséquence, il arrive que la ''prefetch input queue'' n'ait pas préchargé l'instruction suivante, alors que le décodeur d'instruction est prêt pour la décoder. Dans ce cas, le décodeur doit attendre que l'instruction soit chargée. Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser une ''prefetch input queue'' était le 8086. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons expliquer dans quelques paragraphes. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Vous remarquerez que j'ai exprimé la capacité de la ''prefetch input queue'' en octets et non en instructions. La raison est que sur les processeurs x86, les instructions sont de taille variable, avec une taille qui varie entre un octet et 6 octets. Cependant, le décodage des instructions se fait un octet à la fois : le décodeur lit un octet, puis éventuellement le suivant, et ainsi de suite jusqu'à atteindre la fin de l'instruction. En clair, le décodeur lits les instructions longues octet par octet dans la ''Prefetch input queue''. Pour cela, le décodeur dispose d'une micro-opération pour lire un octet depuis la ''Prefetch input queue''. Le décodeur devait attendre que qu'un moins un octet soit disponible dans la ''Prefetch input queue'', pour le lire. Il lisait alors cet octet et déterminait s'il contenait une instruction complète ou non. Si c'est une instruction complète, il la décodait et l''exécutait, puis passait à l'instruction suivante. Sinon, il lit un second octet depuis la ''Prefetch input queue'', le copie dans le registre d'instruction, et relance le décodage. Là encore, le décodeur vérifie s'il a une instruction complète, et lit un troisième octet si besoin, puis rebelote avec un quatrième octet lu, etc. Les octets lus pouvaient être accumulés dans le registre d'instruction, mais aussi ailleurs. Par exemple, prenons le cas d'une addition entre le registre AX et une constante immédiate. L'instruction fait trois octets : un opcode suivie par une constante immédiate codée sur deux octets. L'opcode était envoyé au décodeur, mais pas la constante immédiate. Elle était lue octet par octet et mémorisée dans un registre temporaire placé en entrée de l'ALU. Tout se passait du décodage : l'instruction était composée de quatre micro-opérations : une qui lisait le premier octet de la constante immédiate, une seconde pour le second, une troisième micro-opération qui commande l'ALU et fait le calcul. Un circuit appelé le ''loader'' synchronisait le décodeur d'instruction et la ''Prefetch input queue''. Il fournissait un bit qui indiquait si le premier octet d'une instruction était disponible dans la ''Prefetch input queue''. Un second bit indiquait si l'octet suivant était disponible, nous verrons pourquoi dans ce qui suit. Le ''loader'' recevait aussi des signaux de la part du décodeur d'instruction. Le décodeur envoyait le signal ''Run Next Instruction'' pour lire une instruction, qui était alors dépilée de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'', un cycle avant que l'instruction en cours ne termine. Le ''loader'' réagissait en préchargeant l'octet suivant. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Le bus de données du 8086 faisait 16 bits, alors que celui du 8088 ne permettait que de lire un octet à la fois. Et cela avait un impact sur la ''prefetch input queue''. La ''prefetch input queue'' était composée de 4 registres de 8 bits, avec un port d'écriture de 8 bits pour précharger les instructions octet par octet, et un port de lecture de 8 bits pour alimenter le décodeur. En clair, tout faisait 8 bits. Le 8086, lui utilisait des registres de 16 bits et un port d'écriture de 16 bits. le port de lecture restait de 8 bits, et était précédé d'un multiplexeur qui prenait 16 bits et sélectionnait l'octet adéquat. Sa ''prefetch input queue'' préchargeait les instructions par paquets de 2 octets, non octet par octet, alors que le décodeur consommait les instructions octet par octet. Il s’agissait donc d'une sorte d'intermédiaire entre ''prefetch input queue'' à la 8088 et tampon de préchargement. Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Pour cela, le décodeur d'instruction dispose d'une micro-opération qui vide la ''Prefetch input queue'', elle invalide les instructions préchargées. Cette détection ne peut se faire qu'une fois le branchement décodé, qu'une fois que l'on sait que l'instruction décodée est un branchement. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Il faut noter qu'une ''Prefetch input queue'' interagit assez mal avec le ''program counter''. En effet, la ''Prefetch input queue'' précharge les instructions séquentiellement. Pour savoir où elle en est rendue, elle mémorise l'adresse de la prochaine instruction à charger dans un '''registre de préchargement''' dédié. Il serait possible d'utiliser un ''program counter'' en plus du registre de préchargement, mais ce n'est pas la solution qui a été utilisée. Les processeurs Intel anciens ont préféré n'utiliser qu'un seul registre de préchargement en remplacement du ''program counter''. Après tout, le registre de préchargement n'est qu'un ''program counter'' ayant pris une avance de quelques cycles d'horloge, qui a été incrémenté en avance. Et cela ne pose pas de problèmes, sauf avec certains branchements. Par exemple, certains branchements relatifs demandent de connaitre la véritable valeur du ''program counter'', pas celle calculée en avance. Idem avec les instructions d'appel de fonction, qui demandent de sauvegarder l'adresse de retour exacte, donc le vrai ''program counter''. De telles situations demandent de connaitre la valeur réelle du ''program counter'', celle sans préchargement. Pour cela, le décodeur d'instruction dispose d'une instruction pour reconstituer le ''program counter'', à savoir corriger le ''program coutner'' et éliminer l'effet du préchargement. La micro-opération de correction se contente de soustraire le nombre d'octets préchargés au registre de préchargement. Le nombre d'octets préchargés est déduit à partir des deux pointeurs intégré à la FIFO, qui indiquent la position du premier et du dernier octet préchargé. Le bit qui indique si la FIFO est vide était aussi utilisé. Les deux pointeurs sont lus depuis la FIFO, et sont envoyés à un circuit qui détermine le nombre d'octets préchargés. Sur le 8086, ce circuit était implémenté non pas par un circuit combinatoire, mais par une mémoire ROM équivalente. La petite taille de la FIFO faisait que les pointeurs étaient très petits et la ROM l'était aussi. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. Le décodeur d'instruction dispose aussi d'une micro-opération qui stoppe le préchargement des instructions dans la ''Prefetch input queue''. : Pour ceux qui ont déjà lu un cours d'architecture des ordinateurs, la relation entre ''prefetch input queue'' et pipeline est quelque peu complexe. En apparence, la ''prefetch input queue'' permet une certaines forme de pipeline, en chargeant une instruction pendant que la précédente s'exécute. Les problématiques liées aux branchements ressemblent beaucoup à celles de la prédiction de branchement. Cependant, il est possible de dire qu'il s'agit plus d'une technique de préchargement que de pipeline. La différence entre les deux est assez subtile et les frontières sont assez floues, mais le fait est que l'instruction en cours d'exécution et le préchargement peuvent tout deux faire des accès mémoire et que l'instruction en cours a la priorité. Un vrai pipeline se débrouillerait avec une architecture Harvard, non avec un bus mémoire unique pour le chargement des instruction et la lecture/écriture des données. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> 7d9gi09tk0ue7jiwylj88abuw16ke5k 744091 744090 2025-06-03T20:27:49Z Mewtow 31375 /* La prefetch input queue */ 744091 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement, qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un ou deux octet à la fois. En conséquence, le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. Pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec un tampon de préchargement, le processeur chargeait plusieurs instruction en une seule fois, puis les exécutait les unes après les autres. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peut en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. En conséquence, il arrive que la ''prefetch input queue'' n'ait pas préchargé l'instruction suivante, alors que le décodeur d'instruction est prêt pour la décoder. Dans ce cas, le décodeur doit attendre que l'instruction soit chargée. Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser une ''prefetch input queue'' était le 8086. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons expliquer dans quelques paragraphes. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Vous remarquerez que j'ai exprimé la capacité de la ''prefetch input queue'' en octets et non en instructions. La raison est que sur les processeurs x86, les instructions sont de taille variable, avec une taille qui varie entre un octet et 6 octets. Cependant, le décodage des instructions se fait un octet à la fois : le décodeur lit un octet, puis éventuellement le suivant, et ainsi de suite jusqu'à atteindre la fin de l'instruction. En clair, le décodeur lit les instructions longues octet par octet dans la ''Prefetch input queue''. Pour cela, le décodeur dispose d'une micro-opération pour lire un octet depuis la ''prefetch input queue''. Les instructions varient entre 1 et 6 octets, mais tous ne sont pas utile au décodeur d'instruction. Par exemple, le décodeur d'instruction n'a pas besoin d'analyser les constantes immédiates intégrées dans une instruction, ni les adresses mémoires en adressage absolu. Il a besoin de deux octets : l'opcode, et l'octet Mod/RM qui précise le mode d'adressage. Le second est facultatif. En clair, le décodeur a besoin de lire deux octets maximum depuis la ''prefetch input queue'', avant de passer à l’instruction suivante. Les octets n'étant ni un opcode ni l'octet Mod/RN étaient envoyés ailleurs. Par exemple, prenons le cas d'une addition entre le registre AX et une constante immédiate. L'instruction fait trois octets : un opcode suivie par une constante immédiate codée sur deux octets. L'opcode était envoyé au décodeur, mais pas la constante immédiate. Elle était lue octet par octet et mémorisée dans un registre temporaire placé en entrée de l'ALU. Tout se passait du décodage : l'instruction était composée de quatre micro-opérations : une qui lisait le premier octet de la constante immédiate, une seconde pour le second, une troisième micro-opération qui commande l'ALU et fait le calcul. Idem avec les adresses immédiates, qui étaient envoyées dans un registre d’interfaçage mémoire sans passer par le décodeur d'instruction. En clair, la ''prefetch input queue'' était connectée au bus interne du processeur ! Le décodeur devait attendre que qu'un moins un octet soit disponible dans la ''Prefetch input queue'', pour le lire. Il lisait alors cet octet et déterminait s'il contenait une instruction complète ou non. Si c'est une instruction complète, il la décodait et l''exécutait, puis passait à l'instruction suivante. Sinon, il lit un second octet depuis la ''Prefetch input queue'' et relance le décodage. Là encore, le décodeur vérifie s'il a une instruction complète, et lit un troisième octet si besoin, puis rebelote avec un quatrième octet lu, etc. Un circuit appelé le ''loader'' synchronisait le décodeur d'instruction et la ''Prefetch input queue''. Il fournissait un bit qui indiquait si le premier octet d'une instruction était disponible dans la ''Prefetch input queue''. Un second bit indiquait si l'octet suivant était disponible, nous verrons pourquoi dans ce qui suit. Le ''loader'' recevait aussi des signaux de la part du décodeur d'instruction. Le décodeur envoyait le signal ''Run Next Instruction'' pour lire une instruction, qui était alors dépilée de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'', un cycle avant que l'instruction en cours ne termine. Le ''loader'' réagissait en préchargeant l'octet suivant. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Le bus de données du 8086 faisait 16 bits, alors que celui du 8088 ne permettait que de lire un octet à la fois. Et cela avait un impact sur la ''prefetch input queue''. La ''prefetch input queue'' était composée de 4 registres de 8 bits, avec un port d'écriture de 8 bits pour précharger les instructions octet par octet, et un port de lecture de 8 bits pour alimenter le décodeur. En clair, tout faisait 8 bits. Le 8086, lui utilisait des registres de 16 bits et un port d'écriture de 16 bits. le port de lecture restait de 8 bits, et était précédé d'un multiplexeur qui prenait 16 bits et sélectionnait l'octet adéquat. Sa ''prefetch input queue'' préchargeait les instructions par paquets de 2 octets, non octet par octet, alors que le décodeur consommait les instructions octet par octet. Il s’agissait donc d'une sorte d'intermédiaire entre ''prefetch input queue'' à la 8088 et tampon de préchargement. Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Pour cela, le décodeur d'instruction dispose d'une micro-opération qui vide la ''Prefetch input queue'', elle invalide les instructions préchargées. Cette détection ne peut se faire qu'une fois le branchement décodé, qu'une fois que l'on sait que l'instruction décodée est un branchement. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Il faut noter qu'une ''Prefetch input queue'' interagit assez mal avec le ''program counter''. En effet, la ''Prefetch input queue'' précharge les instructions séquentiellement. Pour savoir où elle en est rendue, elle mémorise l'adresse de la prochaine instruction à charger dans un '''registre de préchargement''' dédié. Il serait possible d'utiliser un ''program counter'' en plus du registre de préchargement, mais ce n'est pas la solution qui a été utilisée. Les processeurs Intel anciens ont préféré n'utiliser qu'un seul registre de préchargement en remplacement du ''program counter''. Après tout, le registre de préchargement n'est qu'un ''program counter'' ayant pris une avance de quelques cycles d'horloge, qui a été incrémenté en avance. Et cela ne pose pas de problèmes, sauf avec certains branchements. Par exemple, certains branchements relatifs demandent de connaitre la véritable valeur du ''program counter'', pas celle calculée en avance. Idem avec les instructions d'appel de fonction, qui demandent de sauvegarder l'adresse de retour exacte, donc le vrai ''program counter''. De telles situations demandent de connaitre la valeur réelle du ''program counter'', celle sans préchargement. Pour cela, le décodeur d'instruction dispose d'une instruction pour reconstituer le ''program counter'', à savoir corriger le ''program coutner'' et éliminer l'effet du préchargement. La micro-opération de correction se contente de soustraire le nombre d'octets préchargés au registre de préchargement. Le nombre d'octets préchargés est déduit à partir des deux pointeurs intégré à la FIFO, qui indiquent la position du premier et du dernier octet préchargé. Le bit qui indique si la FIFO est vide était aussi utilisé. Les deux pointeurs sont lus depuis la FIFO, et sont envoyés à un circuit qui détermine le nombre d'octets préchargés. Sur le 8086, ce circuit était implémenté non pas par un circuit combinatoire, mais par une mémoire ROM équivalente. La petite taille de la FIFO faisait que les pointeurs étaient très petits et la ROM l'était aussi. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. Le décodeur d'instruction dispose aussi d'une micro-opération qui stoppe le préchargement des instructions dans la ''Prefetch input queue''. : Pour ceux qui ont déjà lu un cours d'architecture des ordinateurs, la relation entre ''prefetch input queue'' et pipeline est quelque peu complexe. En apparence, la ''prefetch input queue'' permet une certaines forme de pipeline, en chargeant une instruction pendant que la précédente s'exécute. Les problématiques liées aux branchements ressemblent beaucoup à celles de la prédiction de branchement. Cependant, il est possible de dire qu'il s'agit plus d'une technique de préchargement que de pipeline. La différence entre les deux est assez subtile et les frontières sont assez floues, mais le fait est que l'instruction en cours d'exécution et le préchargement peuvent tout deux faire des accès mémoire et que l'instruction en cours a la priorité. Un vrai pipeline se débrouillerait avec une architecture Harvard, non avec un bus mémoire unique pour le chargement des instruction et la lecture/écriture des données. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> 5vet1d38ownpjhyh29uqsl5k4ilsu2x 744092 744091 2025-06-03T20:30:05Z Mewtow 31375 /* La prefetch input queue */ 744092 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement, qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un ou deux octet à la fois. En conséquence, le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. Pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec un tampon de préchargement, le processeur chargeait plusieurs instruction en une seule fois, puis les exécutait les unes après les autres. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peut en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. En conséquence, il arrive que la ''prefetch input queue'' n'ait pas préchargé l'instruction suivante, alors que le décodeur d'instruction est prêt pour la décoder. Dans ce cas, le décodeur doit attendre que l'instruction soit chargée. Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser une ''prefetch input queue'' était le 8086. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons expliquer dans quelques paragraphes. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Vous remarquerez que j'ai exprimé la capacité de la ''prefetch input queue'' en octets et non en instructions. La raison est que sur les processeurs x86, les instructions sont de taille variable, avec une taille qui varie entre un octet et 6 octets. Cependant, le décodage des instructions se fait un octet à la fois : le décodeur lit un octet, puis éventuellement le suivant, et ainsi de suite jusqu'à atteindre la fin de l'instruction. En clair, le décodeur lit les instructions longues octet par octet dans la ''Prefetch input queue''. Les instructions varient entre 1 et 6 octets, mais tous ne sont pas utile au décodeur d'instruction. Par exemple, le décodeur d'instruction n'a pas besoin d'analyser les constantes immédiates intégrées dans une instruction, ni les adresses mémoires en adressage absolu. Il n'a besoin que de deux octets : l'opcode et l'octet Mod/RM qui précise le mode d'adressage. Le second est facultatif. En clair, le décodeur a besoin de lire deux octets maximum depuis la ''prefetch input queue'', avant de passer à l’instruction suivante. Les autres octets étaient envoyés ailleurs, typiquement dans le chemin de données. Par exemple, prenons le cas d'une addition entre le registre AX et une constante immédiate. L'instruction fait trois octets : un opcode suivie par une constante immédiate codée sur deux octets. L'opcode était envoyé au décodeur, mais pas la constante immédiate. Elle était lue octet par octet et mémorisée dans un registre temporaire placé en entrée de l'ALU. Idem avec les adresses immédiates, qui étaient envoyées dans un registre d’interfaçage mémoire sans passer par le décodeur d'instruction. Pour cela, la ''prefetch input queue'' était connectée au bus interne du processeur ! Le décodeur dispose d'une micro-opération pour lire un octet depuis la ''prefetch input queue'' et le copier ailleurs dans le chemin de données. Par exemple, l'instruction d'addition entre le registre AX et une constante immédiate était composée de quatre micro-opérations : une qui lisait le premier octet de la constante immédiate, une seconde pour le second, une troisième micro-opération qui commande l'ALU et fait le calcul. Le décodeur devait attendre que qu'un moins un octet soit disponible dans la ''Prefetch input queue'', pour le lire. Il lisait alors cet octet et déterminait s'il contenait une instruction complète ou non. Si c'est une instruction complète, il la décodait et l''exécutait, puis passait à l'instruction suivante. Sinon, il lit un second octet depuis la ''Prefetch input queue'' et relance le décodage. Là encore, le décodeur vérifie s'il a une instruction complète, et lit un troisième octet si besoin, puis rebelote avec un quatrième octet lu, etc. Un circuit appelé le ''loader'' synchronisait le décodeur d'instruction et la ''Prefetch input queue''. Il fournissait un bit qui indiquait si le premier octet d'une instruction était disponible dans la ''Prefetch input queue''. Un second bit indiquait si l'octet suivant était disponible, nous verrons pourquoi dans ce qui suit. Le ''loader'' recevait aussi des signaux de la part du décodeur d'instruction. Le décodeur envoyait le signal ''Run Next Instruction'' pour lire une instruction, qui était alors dépilée de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'', un cycle avant que l'instruction en cours ne termine. Le ''loader'' réagissait en préchargeant l'octet suivant. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Le bus de données du 8086 faisait 16 bits, alors que celui du 8088 ne permettait que de lire un octet à la fois. Et cela avait un impact sur la ''prefetch input queue''. La ''prefetch input queue'' était composée de 4 registres de 8 bits, avec un port d'écriture de 8 bits pour précharger les instructions octet par octet, et un port de lecture de 8 bits pour alimenter le décodeur. En clair, tout faisait 8 bits. Le 8086, lui utilisait des registres de 16 bits et un port d'écriture de 16 bits. le port de lecture restait de 8 bits, et était précédé d'un multiplexeur qui prenait 16 bits et sélectionnait l'octet adéquat. Sa ''prefetch input queue'' préchargeait les instructions par paquets de 2 octets, non octet par octet, alors que le décodeur consommait les instructions octet par octet. Il s’agissait donc d'une sorte d'intermédiaire entre ''prefetch input queue'' à la 8088 et tampon de préchargement. Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Pour cela, le décodeur d'instruction dispose d'une micro-opération qui vide la ''Prefetch input queue'', elle invalide les instructions préchargées. Cette détection ne peut se faire qu'une fois le branchement décodé, qu'une fois que l'on sait que l'instruction décodée est un branchement. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Il faut noter qu'une ''Prefetch input queue'' interagit assez mal avec le ''program counter''. En effet, la ''Prefetch input queue'' précharge les instructions séquentiellement. Pour savoir où elle en est rendue, elle mémorise l'adresse de la prochaine instruction à charger dans un '''registre de préchargement''' dédié. Il serait possible d'utiliser un ''program counter'' en plus du registre de préchargement, mais ce n'est pas la solution qui a été utilisée. Les processeurs Intel anciens ont préféré n'utiliser qu'un seul registre de préchargement en remplacement du ''program counter''. Après tout, le registre de préchargement n'est qu'un ''program counter'' ayant pris une avance de quelques cycles d'horloge, qui a été incrémenté en avance. Et cela ne pose pas de problèmes, sauf avec certains branchements. Par exemple, certains branchements relatifs demandent de connaitre la véritable valeur du ''program counter'', pas celle calculée en avance. Idem avec les instructions d'appel de fonction, qui demandent de sauvegarder l'adresse de retour exacte, donc le vrai ''program counter''. De telles situations demandent de connaitre la valeur réelle du ''program counter'', celle sans préchargement. Pour cela, le décodeur d'instruction dispose d'une instruction pour reconstituer le ''program counter'', à savoir corriger le ''program coutner'' et éliminer l'effet du préchargement. La micro-opération de correction se contente de soustraire le nombre d'octets préchargés au registre de préchargement. Le nombre d'octets préchargés est déduit à partir des deux pointeurs intégré à la FIFO, qui indiquent la position du premier et du dernier octet préchargé. Le bit qui indique si la FIFO est vide était aussi utilisé. Les deux pointeurs sont lus depuis la FIFO, et sont envoyés à un circuit qui détermine le nombre d'octets préchargés. Sur le 8086, ce circuit était implémenté non pas par un circuit combinatoire, mais par une mémoire ROM équivalente. La petite taille de la FIFO faisait que les pointeurs étaient très petits et la ROM l'était aussi. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. Le décodeur d'instruction dispose aussi d'une micro-opération qui stoppe le préchargement des instructions dans la ''Prefetch input queue''. : Pour ceux qui ont déjà lu un cours d'architecture des ordinateurs, la relation entre ''prefetch input queue'' et pipeline est quelque peu complexe. En apparence, la ''prefetch input queue'' permet une certaines forme de pipeline, en chargeant une instruction pendant que la précédente s'exécute. Les problématiques liées aux branchements ressemblent beaucoup à celles de la prédiction de branchement. Cependant, il est possible de dire qu'il s'agit plus d'une technique de préchargement que de pipeline. La différence entre les deux est assez subtile et les frontières sont assez floues, mais le fait est que l'instruction en cours d'exécution et le préchargement peuvent tout deux faire des accès mémoire et que l'instruction en cours a la priorité. Un vrai pipeline se débrouillerait avec une architecture Harvard, non avec un bus mémoire unique pour le chargement des instruction et la lecture/écriture des données. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> b5ghgr3billegb8wdkidggqcf2lheib 744093 744092 2025-06-03T20:32:21Z Mewtow 31375 /* La prefetch input queue */ 744093 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement, qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un ou deux octet à la fois. En conséquence, le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. Pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec un tampon de préchargement, le processeur chargeait plusieurs instruction en une seule fois, puis les exécutait les unes après les autres. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peut en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. En conséquence, il arrive que la ''prefetch input queue'' n'ait pas préchargé l'instruction suivante, alors que le décodeur d'instruction est prêt pour la décoder. Dans ce cas, le décodeur doit attendre que l'instruction soit chargée. Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser une ''prefetch input queue'' était le 8086. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons expliquer dans quelques paragraphes. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Vous remarquerez que j'ai exprimé la capacité de la ''prefetch input queue'' en octets et non en instructions. La raison est que sur les processeurs x86, les instructions sont de taille variable, avec une taille qui varie entre un octet et 6 octets. Cependant, le décodage des instructions se fait un octet à la fois : le décodeur lit un octet, puis éventuellement le suivant, et ainsi de suite jusqu'à atteindre la fin de l'instruction. En clair, le décodeur lit les instructions longues octet par octet dans la ''Prefetch input queue''. Les instructions varient entre 1 et 6 octets, mais tous ne sont pas utile au décodeur d'instruction. Par exemple, le décodeur d'instruction n'a pas besoin d'analyser les constantes immédiates intégrées dans une instruction, ni les adresses mémoires en adressage absolu. Il n'a besoin que de deux octets : l'opcode et l'octet Mod/RM qui précise le mode d'adressage. Le second est facultatif. En clair, le décodeur a besoin de lire deux octets maximum depuis la ''prefetch input queue'', avant de passer à l’instruction suivante. Les autres octets étaient envoyés ailleurs, typiquement dans le chemin de données. Par exemple, prenons le cas d'une addition entre le registre AX et une constante immédiate. L'instruction fait trois octets : un opcode suivie par une constante immédiate codée sur deux octets. L'opcode était envoyé au décodeur, mais pas la constante immédiate. Elle était lue octet par octet et mémorisée dans un registre temporaire placé en entrée de l'ALU. Idem avec les adresses immédiates, qui étaient envoyées dans un registre d’interfaçage mémoire sans passer par le décodeur d'instruction. Pour cela, la ''prefetch input queue'' était connectée au bus interne du processeur ! Le décodeur dispose d'une micro-opération pour lire un octet depuis la ''prefetch input queue'' et le copier ailleurs dans le chemin de données. Par exemple, l'instruction d'addition entre le registre AX et une constante immédiate était composée de quatre micro-opérations : une qui lisait le premier octet de la constante immédiate, une seconde pour le second, une troisième micro-opération qui commande l'ALU et fait le calcul. Le décodeur devait attendre que qu'un moins un octet soit disponible dans la ''Prefetch input queue'', pour le lire. Il lisait alors cet octet et déterminait s'il contenait une instruction complète ou non. Si c'est une instruction complète, il la décodait et l''exécutait, puis passait à l'instruction suivante. Sinon, il lit un second octet depuis la ''Prefetch input queue'' et relance le décodage. Là encore, le décodeur vérifie s'il a une instruction complète, et lit un troisième octet si besoin, puis rebelote avec un quatrième octet lu, etc. Un circuit appelé le ''loader'' synchronisait le décodeur d'instruction et la ''Prefetch input queue''. Il fournissait deux bits : un premier bit pour indiquer que le premier octet d'une instruction était disponible dans la ''Prefetch input queue'', un second bit pour le second octet. Le ''loader'' recevait aussi des signaux de la part du décodeur d'instruction. Le signal ''Run Next Instruction'' entrainait la lecture d'une nouvelle instruction, d'un premier octet, qui était alors dépilé de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'', un cycle avant que l'instruction en cours ne termine. Le ''loader'' réagissait en préchargeant l'octet suivant. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Le bus de données du 8086 faisait 16 bits, alors que celui du 8088 ne permettait que de lire un octet à la fois. Et cela avait un impact sur la ''prefetch input queue''. La ''prefetch input queue'' était composée de 4 registres de 8 bits, avec un port d'écriture de 8 bits pour précharger les instructions octet par octet, et un port de lecture de 8 bits pour alimenter le décodeur. En clair, tout faisait 8 bits. Le 8086, lui utilisait des registres de 16 bits et un port d'écriture de 16 bits. le port de lecture restait de 8 bits, et était précédé d'un multiplexeur qui prenait 16 bits et sélectionnait l'octet adéquat. Sa ''prefetch input queue'' préchargeait les instructions par paquets de 2 octets, non octet par octet, alors que le décodeur consommait les instructions octet par octet. Il s’agissait donc d'une sorte d'intermédiaire entre ''prefetch input queue'' à la 8088 et tampon de préchargement. Les branchements posent des problèmes avec la ''Prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''Prefetch input queue'' est vidée quand le processeur détecte un branchement. Pour cela, le décodeur d'instruction dispose d'une micro-opération qui vide la ''Prefetch input queue'', elle invalide les instructions préchargées. Cette détection ne peut se faire qu'une fois le branchement décodé, qu'une fois que l'on sait que l'instruction décodée est un branchement. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Il faut noter qu'une ''Prefetch input queue'' interagit assez mal avec le ''program counter''. En effet, la ''Prefetch input queue'' précharge les instructions séquentiellement. Pour savoir où elle en est rendue, elle mémorise l'adresse de la prochaine instruction à charger dans un '''registre de préchargement''' dédié. Il serait possible d'utiliser un ''program counter'' en plus du registre de préchargement, mais ce n'est pas la solution qui a été utilisée. Les processeurs Intel anciens ont préféré n'utiliser qu'un seul registre de préchargement en remplacement du ''program counter''. Après tout, le registre de préchargement n'est qu'un ''program counter'' ayant pris une avance de quelques cycles d'horloge, qui a été incrémenté en avance. Et cela ne pose pas de problèmes, sauf avec certains branchements. Par exemple, certains branchements relatifs demandent de connaitre la véritable valeur du ''program counter'', pas celle calculée en avance. Idem avec les instructions d'appel de fonction, qui demandent de sauvegarder l'adresse de retour exacte, donc le vrai ''program counter''. De telles situations demandent de connaitre la valeur réelle du ''program counter'', celle sans préchargement. Pour cela, le décodeur d'instruction dispose d'une instruction pour reconstituer le ''program counter'', à savoir corriger le ''program coutner'' et éliminer l'effet du préchargement. La micro-opération de correction se contente de soustraire le nombre d'octets préchargés au registre de préchargement. Le nombre d'octets préchargés est déduit à partir des deux pointeurs intégré à la FIFO, qui indiquent la position du premier et du dernier octet préchargé. Le bit qui indique si la FIFO est vide était aussi utilisé. Les deux pointeurs sont lus depuis la FIFO, et sont envoyés à un circuit qui détermine le nombre d'octets préchargés. Sur le 8086, ce circuit était implémenté non pas par un circuit combinatoire, mais par une mémoire ROM équivalente. La petite taille de la FIFO faisait que les pointeurs étaient très petits et la ROM l'était aussi. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. Le décodeur d'instruction dispose aussi d'une micro-opération qui stoppe le préchargement des instructions dans la ''Prefetch input queue''. : Pour ceux qui ont déjà lu un cours d'architecture des ordinateurs, la relation entre ''prefetch input queue'' et pipeline est quelque peu complexe. En apparence, la ''prefetch input queue'' permet une certaines forme de pipeline, en chargeant une instruction pendant que la précédente s'exécute. Les problématiques liées aux branchements ressemblent beaucoup à celles de la prédiction de branchement. Cependant, il est possible de dire qu'il s'agit plus d'une technique de préchargement que de pipeline. La différence entre les deux est assez subtile et les frontières sont assez floues, mais le fait est que l'instruction en cours d'exécution et le préchargement peuvent tout deux faire des accès mémoire et que l'instruction en cours a la priorité. Un vrai pipeline se débrouillerait avec une architecture Harvard, non avec un bus mémoire unique pour le chargement des instruction et la lecture/écriture des données. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> a5hpzf9x4qobw5p2fgzc8b4xnysp3s6 744094 744093 2025-06-03T20:40:41Z Mewtow 31375 /* La prefetch input queue */ 744094 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement, qui a été utilisée sur les processeurs Intel assez ancien. Elle est apparue sur le 8086 et le 8088, des processeurs respectivement 8 et 16 bits. Elle été présente sur le 286 et le 386, mais était un peu améliorée. Elle est apparue sur ces processeurs à une époque où le processeur devenait plus rapide que la mémoire. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un ou deux octet à la fois. En conséquence, le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. Pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec un tampon de préchargement, le processeur chargeait plusieurs instruction en une seule fois, puis les exécutait les unes après les autres. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peut en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. En conséquence, il arrive que la ''prefetch input queue'' n'ait pas préchargé l'instruction suivante, alors que le décodeur d'instruction est prêt pour la décoder. Dans ce cas, le décodeur doit attendre que l'instruction soit chargée. Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser une ''prefetch input queue'' était le 8086. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. Le 386 avait une ''prefetch input queue'' de 16 octets. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons expliquer dans quelques paragraphes. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Vous remarquerez que j'ai exprimé la capacité de la ''prefetch input queue'' en octets et non en instructions. La raison est que sur les processeurs x86, les instructions sont de taille variable, avec une taille qui varie entre un octet et 6 octets. Cependant, le décodage des instructions se fait un octet à la fois : le décodeur lit un octet, puis éventuellement le suivant, et ainsi de suite jusqu'à atteindre la fin de l'instruction. En clair, le décodeur lit les instructions longues octet par octet dans la ''Prefetch input queue''. Les instructions varient entre 1 et 6 octets, mais tous ne sont pas utiles au décodeur d'instruction. Par exemple, le décodeur d'instruction n'a pas besoin d'analyser les constantes immédiates intégrées dans une instruction, ni les adresses mémoires en adressage absolu. Il n'a besoin que de deux octets : l'opcode et l'octet Mod/RM qui précise le mode d'adressage. Le second est facultatif. En clair, le décodeur a besoin de lire deux octets maximum depuis la ''prefetch input queue'', avant de passer à l’instruction suivante. Les autres octets étaient envoyés ailleurs, typiquement dans le chemin de données. Par exemple, prenons le cas d'une addition entre le registre AX et une constante immédiate. L'instruction fait trois octets : un opcode suivie par une constante immédiate codée sur deux octets. L'opcode était envoyé au décodeur, mais pas la constante immédiate. Elle était lue octet par octet et mémorisée dans un registre temporaire placé en entrée de l'ALU. Idem avec les adresses immédiates, qui étaient envoyées dans un registre d’interfaçage mémoire sans passer par le décodeur d'instruction. Pour cela, la ''prefetch input queue'' était connectée au bus interne du processeur ! Le décodeur dispose d'une micro-opération pour lire un octet depuis la ''prefetch input queue'' et le copier ailleurs dans le chemin de données. Par exemple, l'instruction d'addition entre le registre AX et une constante immédiate était composée de quatre micro-opérations : une qui lisait le premier octet de la constante immédiate, une seconde pour le second, une troisième micro-opération qui commande l'ALU et fait le calcul. Le décodeur devait attendre que qu'un moins un octet soit disponible dans la ''Prefetch input queue'', pour le lire. Il lisait alors cet octet et déterminait s'il contenait une instruction complète ou non. Si c'est une instruction complète, il la décodait et l''exécutait, puis passait à l'instruction suivante. Sinon, il lit un second octet depuis la ''Prefetch input queue'' et relance le décodage. Là encore, le décodeur vérifie s'il a une instruction complète, et lit un troisième octet si besoin, puis rebelote avec un quatrième octet lu, etc. Un circuit appelé le ''loader'' synchronisait le décodeur d'instruction et la ''Prefetch input queue''. Il fournissait deux bits : un premier bit pour indiquer que le premier octet d'une instruction était disponible dans la ''Prefetch input queue'', un second bit pour le second octet. Le ''loader'' recevait aussi des signaux de la part du décodeur d'instruction. Le signal ''Run Next Instruction'' entrainait la lecture d'une nouvelle instruction, d'un premier octet, qui était alors dépilé de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'', un cycle avant que l'instruction en cours ne termine. Le ''loader'' réagissait en préchargeant l'octet suivant. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Le bus de données du 8086 faisait 16 bits, alors que celui du 8088 ne permettait que de lire un octet à la fois. Et cela avait un impact sur la ''prefetch input queue''. La ''prefetch input queue'' du 8088 était composée de 4 registres de 8 bits, avec un port d'écriture de 8 bits pour précharger les instructions octet par octet, et un port de lecture de 8 bits pour alimenter le décodeur. En clair, tout faisait 8 bits. Le 8086, lui utilisait des registres de 16 bits et un port d'écriture de 16 bits. le port de lecture restait de 8 bits, grâce à un multiplexeur sélectionnait l'octet adéquat dans un registre 16 bits. Sa ''prefetch input queue'' préchargeait les instructions par paquets de 2 octets, non octet par octet, alors que le décodeur consommait les instructions octet par octet. Il s’agissait donc d'une sorte d'intermédiaire entre ''prefetch input queue'' à la 8088 et tampon de préchargement. Le 386 était dans un cas à part. C'était un processeur 32 bits, sa ''prefetch input queue'' contenait 4 registres de 32 bits, un port d'écriture de 32 bits. Mais il ne lisait pas les instructions octet par cotet. A la place, son décodeur d'instruction avait une entrée de 32 bits. Cependant, il gérait des instructions de 8 et 16 bits. Il fallait alors dépiler des instructions de 8, 16 et 32 bits dans la ''prefetch input queue''. De plus, les instructions préchargées n'étaient pas parfaitement alignées sur 32 bits : une instruction pouvait être à cheval sur deux registres 32 bits. Le processeur incorporait donc des circuits d'alignement, semblables à ceux utilisés pour gérer des instructions de longueur variable avec un registre d'instruction. Les branchements posent des problèmes avec la ''prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''prefetch input queue'' est vidée quand le processeur détecte un branchement. Pour cela, le décodeur d'instruction dispose d'une micro-opération qui vide la ''Prefetch input queue'', elle invalide les instructions préchargées. Cette détection ne peut se faire qu'une fois le branchement décodé, qu'une fois que l'on sait que l'instruction décodée est un branchement. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Il faut noter qu'une ''Prefetch input queue'' interagit assez mal avec le ''program counter''. En effet, la ''Prefetch input queue'' précharge les instructions séquentiellement. Pour savoir où elle en est rendue, elle mémorise l'adresse de la prochaine instruction à charger dans un '''registre de préchargement''' dédié. Il serait possible d'utiliser un ''program counter'' en plus du registre de préchargement, mais ce n'est pas la solution qui a été utilisée. Les processeurs Intel anciens ont préféré n'utiliser qu'un seul registre de préchargement en remplacement du ''program counter''. Après tout, le registre de préchargement n'est qu'un ''program counter'' ayant pris une avance de quelques cycles d'horloge, qui a été incrémenté en avance. Et cela ne pose pas de problèmes, sauf avec certains branchements. Par exemple, certains branchements relatifs demandent de connaitre la véritable valeur du ''program counter'', pas celle calculée en avance. Idem avec les instructions d'appel de fonction, qui demandent de sauvegarder l'adresse de retour exacte, donc le vrai ''program counter''. De telles situations demandent de connaitre la valeur réelle du ''program counter'', celle sans préchargement. Pour cela, le décodeur d'instruction dispose d'une instruction pour reconstituer le ''program counter'', à savoir corriger le ''program coutner'' et éliminer l'effet du préchargement. La micro-opération de correction se contente de soustraire le nombre d'octets préchargés au registre de préchargement. Le nombre d'octets préchargés est déduit à partir des deux pointeurs intégré à la FIFO, qui indiquent la position du premier et du dernier octet préchargé. Le bit qui indique si la FIFO est vide était aussi utilisé. Les deux pointeurs sont lus depuis la FIFO, et sont envoyés à un circuit qui détermine le nombre d'octets préchargés. Sur le 8086, ce circuit était implémenté non pas par un circuit combinatoire, mais par une mémoire ROM équivalente. La petite taille de la FIFO faisait que les pointeurs étaient très petits et la ROM l'était aussi. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. Le décodeur d'instruction dispose aussi d'une micro-opération qui stoppe le préchargement des instructions dans la ''Prefetch input queue''. : Pour ceux qui ont déjà lu un cours d'architecture des ordinateurs, la relation entre ''prefetch input queue'' et pipeline est quelque peu complexe. En apparence, la ''prefetch input queue'' permet une certaines forme de pipeline, en chargeant une instruction pendant que la précédente s'exécute. Les problématiques liées aux branchements ressemblent beaucoup à celles de la prédiction de branchement. Cependant, il est possible de dire qu'il s'agit plus d'une technique de préchargement que de pipeline. La différence entre les deux est assez subtile et les frontières sont assez floues, mais le fait est que l'instruction en cours d'exécution et le préchargement peuvent tout deux faire des accès mémoire et que l'instruction en cours a la priorité. Un vrai pipeline se débrouillerait avec une architecture Harvard, non avec un bus mémoire unique pour le chargement des instruction et la lecture/écriture des données. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> lu50g3obx7oh5kyy3scsfhc3vbbasyv 744095 744094 2025-06-03T20:46:32Z Mewtow 31375 /* La prefetch input queue */ 744095 wikitext text/x-wiki L'unité de contrôle s'occupe du chargement des instructions et de leur interprétation, leur décodage. Elle contient deux circuits : l''''unité de chargement''' qui charge l'instruction depuis la mémoire, et le '''séquenceur''' qui commande le chemin de données. Les deux circuits sont séparés, mais ils communiquent entre eux, notamment pour gérer les branchements. Dans ce chapitre, nous allons nous intéresser au chargement d'une instruction depuis la RAM/ROM, nous verrons l'étape de décodage de l'instruction au prochain chapitre. ==Le chargement d'une instruction== [[File:Étape de chargement.png|vignette|upright=1|Étape de chargement.]] L'étape de chargement (ou ''fetch'') doit faire deux choses : mettre à jour le ''program counter'' et lire l'instruction en mémoire RAM ou en ROM. Les deux étapes peuvent être faites en parallèle, dans des circuits séparés. Pendant que l'instruction est lue depuis la mémoire RAM/ROM, le ''program counter'' est incrémenté et/ou altéré par un branchement. Pour lire l'instruction, on envoie le ''program counter'' sur le bus d'adresse et on récupère l'instruction sur le bus de données pour l'envoyer sur l'entrée du séquenceur. Et cela demande de connecter le séquenceur au bus mémoire, à travers l'interface mémoire. Et sur ce point, la situation est différente selon que l'on parler d'une architecture Harvard ou Von Neumann. ===Les interconnexions entre séquenceur et bus mémoire=== Sur les architectures Harvard, le séquenceur et le chemin de donnée utilisent des interfaces mémoire séparées. Le séquenceur est directement relié au bus mémoire de la ROM, alors que le chemin de données est connecté à la RAM. [[File:Microarchitecture de l'interface mémoire d'une architecture Harvard.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture Harvard]] Mais sur les architectures Von-Neumann et affiliées, le séquenceur et le chemin de donnée partagent la même interface mémoire. Et cela pose deux problèmes. Le premier problème est que le bus mémoire doit être libéré une fois l'instruction chargée, pour un éventuel accès mémoire. Mais le séquenceur doit conserver une copie de l'instruction chargée, sans quoi il ne peut pas décoder l'instruction correctement. Par exemple, si l'instruction met plusieurs cycles à s'exécuter, le séquenceur doit conserver une copie de l'instruction durant ces plusieurs cycles. La solution à ce problème est un '''registre d'instruction''' situé juste avant le séquenceur, qui mémorise l'instruction chargée. [[File:Registre d'instruction.png|centre|vignette|upright=2|Registre d'instruction.]] Le second problème est de gérer le flot des instructions/données entre le bus mémoire, le chemin de données et le séquenceur. Le processeur doit connecter l'interface mémoire soit au séquenceur, soit au chemin de données et cela complique le réseau d'interconnexion interne au processeur. Une première solution utilise un bus unique qui relie l'interface mémoire, le séquenceur et le chemin de données. Pour charger une instruction, le séquenceur copie le ''program counter'' sur le bus d'adresse, attend que l'instruction lue soit disponible sur le bus de données, puis la copie dans le registre d'instruction. Le bus mémoire est alors libre et peut être utilisé pour lire ou écrire des données, si le besoin s'en fait sentir. Il faut noter que l'usage d'un bus unique a un impact sur l'organisation interne du chemin de données. Par exemple, le chapitre précédent nous a montré comment implémenter un chemin de données basique, avec des multiplexeurs et démultiplexeurs. Et bien ces chemins de données ne marchent pas vraiment avec un bus interne unique. Il est possible de les adapter, mais au prix d'une complexité largement supérieure. Un bus interne unique marche mieux quand le banc de registre est mono-port. C'est pourquoi il a été utilisé sur d'anciennes architectures appelées des architectures à accumulateur et à pile, que nous verrons dans quelques chapitres, qui utilisaient un banc de registre mono-port. [[File:Microarchitecture de l'interface mémoire d'une architecture von neumann.png|centre|vignette|upright=2|Microarchitecture de l'interface mémoire d'une architecture von neumann]] Une autre solution utilise deux bus interne séparés : un connecté au bus d'adresse, l'autre au bus de données. Le ''program counter'' est alors connecté au bus interne d'adresse, le séquenceur est relié au bus interne de données. Notons que la technique marche bien si le ''program counter'' est dans le banc de registre : les interconnexions utilisées pour gérer l'adressage indirect permettent d'envoyer le ''program counter'' sur le bus d'adresse sans ajout de circuit. Le tout peut être amélioré en remplaçant les deux bus par des multiplexeurs et démultiplexeurs. Le bus d'adresse est précédé par un multiplexeur, qui permet de faire le choix entre ''Program Counter'', adresse venant du chemin de données, ou adresse provenant du séquenceur (adressage absolu). De même, le bus de données est suivi par un démultiplexeur qui envoie la donnée/instruction lue soit au registre d'instruction, soit au chemin de données. Le tout se marie très bien avec les chemins de donnée vu dans le chapitre précédent. Au passage, il faut noter que cette solution nécessite un banc de registre multi-port. [[File:Connexion du program counter sur les bus avec PC isolé.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC isolé]] ===Le chargement des instructions de longueur variable=== Le chargement des instructions de longueur variable pose de nombreux problèmes. Le premier est que mettre à jour le ''program counter'' demande de connaitre la longueur de l'instruction chargée, pour l'ajouter au ''program counter''. Si la longueur d'une instruction est variable, on doit connaitre cette longueur d'une manière où d'une autre. La solution la plus simple indique la longueur de l'instruction dans une partie de l'opcode ou de la représentation en binaire de l'instruction. Mais les processeurs haute performance de nos PC utilisent d'autres solutions, qui n'encodent pas explicitement la taille de l'instruction. Les processeurs récents utilisent un registre d'instruction de grande taille, capable de mémoriser l'instruction la plus longue du processeur. Par exemple, si un processeur supporte des instructions allant de 1 à 8 octets, comme les CPU x86, le registre d'instruction fera 8 octets. Le décodeur d'instruction vérifie à chaque cycle le contenu du registre d'instruction. Si une instruction est détectée dedans, son décodage commence, peu importe la taille de l'instruction. Une fois l'instruction exécutée, elle est retirée du registre d'instruction. Reste à alimenter le registre d'instruction, à charger des instructions dedans. Et pour cela deux solutions : soit on charge l'instruction en plusieurs fois, soit d'un seul coup. La solution la plus simple charge les instructions par mots de 8, 16, 32, 64 bits. Ils sont accumulés dans le registre d'instruction jusqu'à détecter une instruction complète. La technique marche nettement mieux si les instructions sont très longues. Par exemple, les CPU x86 ont des instructions qui vont de 1 à 15 octets, ce qui fait qu'ils utilisent cette technique. Précisément, elle marche si les instructions les plus longues sont plus grandes que le bus mémoire. Une autre solution charge un bloc de mots mémoire aussi grand que la plus grande instruction. Par exemple, si le processeur gère des instructions allant de 1 à 4 octets, il charge 4 octets d'un seul coup dans le registre d'instruction. Il va de soit que cette solution ne marche que si les instructions du processeur sont assez courtes, au plus aussi courtes que le bus mémoire. Ainsi, on est sûr de charger obligatoirement au moins une instruction complète, et peut-être même plusieurs. Le contenu du registre d'instruction est alors découpé en instructions au fil de l'eau. Utiliser un registre d'instruction large pose problème avec des instructions à cheval entre deux blocs. Il se peut qu'on n'ait pas une instruction complète lorsque l'on arrive à la fin du bloc, mais seulement un morceau. Le problème se manifeste peu importe que l'instruction soit chargée d'un seul coup ou bien en plusieurs fois. [[File:Instructions non alignées.png|centre|vignette|upright=2|Instructions non alignées.]] Dans ce cas, on doit décaler le morceau de bloc pour le mettre au bon endroit (au début du registre d'instruction), et charger le prochain bloc juste à côté. On a donc besoin d'un circuit qui décale tous les bits du registre d'instruction, couplé à un circuit qui décide où placer dans le registre d'instruction ce qui a été chargé, avec quelques circuits autour pour configurer les deux circuits précédents. [[File:Décaleur d’instruction.png|centre|vignette|upright=2|Décaleur d’instruction.]] Une autre solution se passe de registre d'instruction en utilisant à la place l'état interne du séquenceur. Là encore, elle charge l'instruction morceau par morceau, typiquement par blocs de 8, 16 ou 32 bits. Les morceaux ne sont pas accumulés dans le registre d'instruction, la solution utilise à la place l'état interne du séquenceur. Les mots mémoire de l'instruction sont chargés à chaque cycle, faisant passer le séquenceur d'un état interne à un autre à chaque mot mémoire. Tant qu'il n'a pas reçu tous les mots mémoire de l'instruction, chaque mot mémoire non terminal le fera passer d'un état interne à un autre, chaque état interne encodant les mots mémoire chargés auparavant. S'il tombe sur le dernier mot mémoire d'une instruction, il rentre dans un état de décodage. ==L'incrémentation du ''program counter''== À chaque chargement, le ''program counter'' est mis à jour afin de pointer sur la prochaine instruction à charger. Sur la quasi-totalité des processeurs, les instructions sont placées dans l'ordre d’exécution dans la RAM. En faisant ainsi, on peut mettre à jour le ''program counter'' en lui ajoutant la longueur de l'instruction courante. Déterminer la longueur de l'instruction est simple quand les instructions ont toutes la même taille, mais certains processeurs ont des instructions de taille variable, ce qui complique le calcul. Dans ce qui va suivre, nous allons supposer que les instructions sont de taille fixe, ce qui fait que le ''program counter'' est toujours incrémenté de la même valeur. Il existe deux méthodes principales pour incrémenter le ''program counter'' : soit le ''program counter'' a son propre additionneur, soit le ''program counter'' est mis à jour par l'ALU. Pour ce qui est de l'organisation des registres, soit le ''program counter'' est un registre séparé des autres, soit il est regroupé avec d'autres registres dans un banc de registre. En tout, cela donne quatre organisations possibles. * Un ''program counter'' séparé relié à un incrémenteur séparé. * Un ''program counter'' séparé des autres registres, incrémenté par l'ALU. * Un ''program counter'' intégré au banc de registre, relié à un incrémenteur séparé. * Un ''program counter'' intégré au banc de registre, incrémenté par l'ALU. [[File:Calcul du program counter.png|centre|vignette|upright=2|les différentes méthodes de calcul du program counter.]] Les processeurs haute performance modernes utilisent tous la première méthode. Les autres méthodes étaient surtout utilisées sur les processeurs 8 ou 16 bits, elles sont encore utilisées sur quelques microcontrôleurs de faible puissance. Nous auront l'occasion de donner des exemples quand nous parlerons des processeurs 8 bits anciens, dans le chapitre sur les architectures à accumulateur et affiliées. ===Le ''program counter'' mis à jour par l'ALU=== Sur certains processeurs, le calcul de l'adresse de la prochaine instruction est effectué par l'ALU. L'avantage de cette méthode est qu'elle économise un incrémenteur dédié au ''program counter''. Ce qui explique que cette méthode était utilisée sur les processeurs assez anciens, à une époque où un additionneur pouvait facilement prendre 10 à 20% des transistors disponibles. Le désavantage principal est une augmentation de la complexité du séquenceur, qui doit gérer la mise à jour du ''program counter''. De plus, la mise à jour du ''program counter'' ne peut pas se faire en même temps qu'une opération arithmétique, ce qui réduit les performances. Si on incrémente le ''program counter'' avec l'ALU, il est intéressant de le placer dans le banc de registres. Un désavantage est qu'on perd un registre. Par exemple, avec un banc de registre de 16 registres, on ne peut adresser que 15 registres généraux. De plus ce n'est pas l'idéal pour le décodage des instructions et pour le séquenceur. Si le processeur dispose de plusieurs bancs de registres, le ''program counter'' est généralement placé dans le banc de registre dédié aux adresses. Sinon, il est placé avec les nombres entiers/adresses. D'anciens processeurs incrémentaient le ''program counter'' avec l'ALU, mais utilisaient bien un registre séparé pour le ''program counter''. Cette méthode est relativement simple à implémenter : il suffit de connecter/déconnecter le ''program counter'' du bus interne suivant les besoins. Le ''program counter'' est déconnecté pendant l’exécution d'une instruction, il est connecté au bus interne pour l'incrémenter. C'est le séquenceur qui gère le tout. L'avantage de cette séparation est qu'elle est plus facile à gérer pour le séquenceur. De plus, on gagne un registre général/entier dans le banc de registre. ===Le compteur programme=== Dans la quasi-totalité des processeurs modernes, le ''program counter'' est un vulgaire compteur comme on en a vu dans les chapitres sur les circuits, ce qui fait qu'il passe automatiquement d'une adresse à la suivante. Dans ce qui suit, nous allons appeler ce registre compteur : le '''compteur ordinal'''. L'usage d'un compteur simplifie fortement la conception du séquenceur. Le séquenceur n'a pas à gérer la mise à jour du ''program counter'', sauf en cas de branchements. De plus, il est possible d'incrémenter le ''program counter'' pendant que l'unité de calcul effectue une opération arithmétique, ce qui améliore grandement les performances. Le seul désavantage est qu'elle demande d'ajouter un incrémenteur dédié au ''program counter''. Sur les processeurs très anciens, les instructions faisaient toutes un seul mot mémoire et le compteur ordinal était un circuit incrémenteur des plus basique. Sur les processeurs modernes, le compteur est incrémenté par pas de 4 si les instructions sont codées sur 4 octets, 8 si les instructions sont codées sur 8 octets, etc. Concrètement, le compteur est un circuit incrémenteur auquel on aurait retiré quelques bits de poids faible. Par exemple, si les instructions sont codées sur 4 octets, on coupe les 2 derniers bits du compteur. Si les instructions sont codées sur 8 octets, on coupe les 3 derniers bits du compteur. Et ainsi de suite. Il a existé quelques processeurs pour lesquelles le ''program counter'' était non pas un compteur binaire classique, mais un ''linear feedback shift register''. L'avantage est que le circuit d'incrémentation utilisait bien moins de portes logiques, l'économie était substantielle. Mais un défaut est que des instructions consécutives dans le programme n'étaient pas consécutives en mémoire. Il existait cependant une table de correspondance pour dire : la première instruction est à telle adresse, la seconde à telle autre, etc. Un exemple de processeur de ce type est le TMS 1000 de Texas Instrument, un des premiers microcontrôleur 4 bits datant des années 70. Une amélioration de la solution précédente utilise un circuit incrémenteur partagé entre le ''program counter'' et d'autres registres. L'incrémenteur est utilisé pour incrémenter le ''program counter'', mais aussi pour effectuer d'autres calculs d'adresse. Par exemple, sur les architectures avec une pile d'adresse de retour, il est possible de partager l'incrémenteur/décrémenteur avec le pointeur de pile ( la technique ne marche pas avec une pile d'appel). Un autre exemple est celui des processeurs qui gèrent automatiquement le rafraichissement mémoire, grâce à, un compteur intégré dans le processeur. Il est possible de partager l'incrémenteur du ''program counter'' avec le compteur de rafraichissement mémoire, qui mémorise la prochaine adresse mémoire à rafraichir. Nous avions déjà abordé ce genre de partage dans le chapitre sur le chemin de données, dans l'annexe sur le pointeur de pile, mais nous verrons d'autres exemples dans le chapitre sur les architectures hybride accumulateur-registre 8/16 bits. ===Quand est mis à jour le ''program counter'' ?=== Le ''program counter'' est mis à jour quand il faut charger une nouvelle instruction. Reste qu'il faut savoir quand le mettre à jour. Incrémenter le ''program counter'' à intervalle régulier, par exemple à chaque cycle d’horloge, fonctionne sur les processeurs où toutes les instructions mettent le même temps pour s’exécuter. Mais de tels processeurs sont très rares. Sur la quasi-totalité des processeurs, les instructions ont une durée d’exécution variable, elles ne prennent pas le même nombre de cycle d'horloge pour s’exécuter. Le temps d’exécution d'une instruction varie selon l'instruction, certaines sont plus longues que d'autres. Tout cela amène un problème : comment incrémenter le ''program counter'' avec des instructions avec des temps d’exécution variables ? La réponse est que la mise à jour du ''program counter'' démarre quand l'instruction précédente a terminée de s’exécuter, plus précisément un cycle avant. C'est un cycle avant pour que l'instruction chargée soit disponible au prochain cycle pour le décodeur. Pour cela, le séquenceur doit déterminer quand l'instruction est terminée et prévenir le ''program counter'' au bon moment. Il faut donc une interaction entre séquenceur et circuit de chargement. Le circuit de chargement contient une entrée Enable, qui autorise la mise à jour du ''program counter''. Le séquenceur met à 1 cette entrée pour prévenir au ''program counter'' qu'il doit être incrémenté au cycle suivant ou lors du cycle courant. Cela permet de gérer simplement le cas des instructions multicycles. [[File:Commande de la mise à jour du program counter.png|centre|vignette|upright=2|Commande de la mise à jour du program counter.]] Toute la difficulté est alors reportée dans le séquenceur, qui doit déterminer la durée d'une instruction. Pour gérer la mise à jour du ''program counter'', le séquenceur doit déterminer la durée d'une instruction. Cela est simple pour les instructions arithmétiques et logiques, qui ont un nombre de cycles fixe, toujours le même. Une fois l'instruction identifiée par le séquenceur, il connait son nombre de cycles et peut programmer un compteur interne au séquenceur, qui compte le nombre de cycles de l'instruction, et fournit le signal Enable au ''program counter''. Mais cette technique ne marche pas vraiment pour les accès mémoire, dont la durée n'est pas connue à l'avance, surtout sur les processeurs avec des mémoires caches. Pour cela, le séquenceur détermine quand l'instruction mémoire est finie et prévient le ''program counter'' quand c'est le cas. Il existe quelques processeurs pour lesquels le temps de calcul dépend des opérandes de l'instruction. On peut par exemple avoir une division qui prend 10 cycles avec certaines opérandes, mais 40 cycles avec d'autres opérandes. Mais ces processeurs sont rares et cela est surtout valable pour les opérations de multiplication/division, guère plus. Le problème est alors le même qu'avec les accès mémoire et la solution est la même : l'ALU prévient le séquenceur quand le résultat est disponible. ==Les branchements et le ''program counter''== Un branchement consiste juste à écrire l'adresse de destination dans le ''program counter''. L'implémentation des branchements demande d'extraire l'adresse de destination et d'altérer le ''program counter'' quand un branchement est détecté. Pour cela, le décodeur d'instruction détecte si l'instruction exécutée est un branchement ou non, et il en déduit où trouver l'adresse de destination. L'adresse de destination se trouve à un endroit qui dépend du mode d'adressage du branchement. Pour rappel, on distingue quatre modes d'adressage pour les branchements : direct, indirect, relatif et implicite. Pour les branchements directs, l'adresse est intégrée dans l'instruction de branchement elle-même et est extraite par le séquenceur. Pour les branchements indirects, l'adresse de destination est dans le banc de registre. Pour les branchements relatifs, il faut ajouter un décalage au ''program counter'', décalage extrait de l'instruction par le séquenceur. Enfin, les instructions de retour de fonction lisent l'adresse de destination depuis la pile. L'implémentation de ces quatre types de branchements est très différente. L'altération du ''program counter'' dépend de si le ''program counter'' est dans un compteur séparé ou s'il est dans le banc de registre. Nous avons vu plus haut qu'il y a quatre cas différents, mais nous n'allons voir que deux cas : celui où le ''program counter'' est dans le banc de registre et est incrémenté par l'unité de calcul, celui avec un ''program counter'' séparé avec son propre incrémenteur. Les deux autres cas ne sont utilisés que sur des architectures à accumulateur ou à pile spécifiques, que nous n'avons pas encore vu à ce stade du cours et que nous verrons en temps voulu dans le chapitre sur ces architectures. ===L’implémentation des branchements avec un ''program counter'' intégré au banc de registres=== Le cas le plus simple est celui où le ''program counter'' est intégré au banc de registre, avec une incrémentation faite par l'unité de calcul. Charger une instruction revient alors à effectuer une instruction LOAD en adressage indirect, à deux différences près : le registre sélectionné est le ''program counter'', l’instruction est copiée dans le registre d'instruction et non dans le banc de registre. L'incrémentation du ''porgram counter'' est implémenté avec des micro-opérations qui agissent sur le chemin de données, au même titre que les branchements indirects, relatifs et directs. * Les branchements indirects copient un registre dans le ''program counter'', ce qui revient simplement à faire une opération MOV entre deux registres, dont le ''program counter'' est la destination. * L'opération inverse d'un branchement indirect, qui copie le ''program counter'' dans un registre général, est utile pour sauvegarder l'adresse de retour d'une fonction. * Les branchements directs copient une adresse dans le ''program counter'', ce qui les rend équivalents à une opération MOV avec une constante immédiate, dont le ''program counter'' est la destination. * Les branchements relatifs sont une opération arithmétique entre le ''program counter'' et un opérande en adressage immédiat. En clair, à partir du moment où le chemin de données supporte les instructions MOV et l'addition, avec les modes d'adressage adéquat, il supporte les branchements. Aucune modification du chemin de données n'est nécessaire, le séquenceur gére le chargement d'une instruction avec les micro-instructions adéquates : une micro-opération ADD pour incrémenter le ''program counter'', une micro-opération LOAD pour le chargement de l'instruction. Notons que sur certaines architectures, le ''program counter'' est adressable au même titre que les autres registres du banc de registre. Les instructions de branchement sont alors remplacées par des instructions MOV ou des instructions arithmétique équivalentes, comme décrit plus haut. ===L’implémentation des branchements avec un ''program counter'' séparé=== Étudions maintenant le cas où le ''program counter'' est dans un registre/compteur séparé. Rappelons que tout compteur digne de ce nom possède une entrée de réinitialisation, qui remet le compteur à zéro. De plus, on peut préciser à quelle valeur il doit être réinitialisé. Ici, la valeur à laquelle on veut réinitialiser le compteur n'est autre que l'adresse de destination du branchement. Implémenter un branchement est donc simple : l'entrée de réinitialisation est commandée par le circuit de détection des branchements, alors que la valeur de réinitialisation est envoyée sur l'entrée adéquate. En clair, nous partons du principe que le ''program counter'' est implémenté avec ce type de compteur : [[File:Fonctionnement d'un compteur (décompteur), schématique.jpg|centre|vignette|upright=1.5|Fonctionnement d'un compteur (décompteur), schématique]] Toute la difficulté est de présenter l'adresse de destination au ''program counter''. Pour les branchements directs, l'adresse de destination est fournie par le séquenceur. L'adresse de destination du branchement sort du séquenceur et est présentée au ''program counter'' sur l'entrée adéquate. Voici donc comment sont implémentés les branchements directs avec un ''program counter'' séparé du banc de registres. Le schéma ci-dessous marche peu importe que le ''program counter'' soit incrémenté par l'ALU ou par un additionneur dédié. [[File:Unité de détection des branchements dans le décodeur.png|centre|vignette|upright=2|Unité de détection des branchements dans le décodeur]] Les branchements relatifs sont ceux qui font sauter X instructions plus loin dans le programme. Leur implémentation demande d'ajouter une constante au ''program counter'', la constante étant fournie dans l’instruction. Là encore, deux solutions sont possibles : réutiliser l'ALU pour calculer l'adresse, ou utiliser un additionneur séparé. L'additionneur séparé peut être fusionné avec l'additionneur qui incrémente le ''program counter'' pour passer à l’instruction suivante. [[File:Unité de chargement qui gère les branchements relatifs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements relatifs.]] Pour les branchements indirects, il suffit de lire le registre voulu et d'envoyer le tout sur l'entrée adéquate du ''program counter''. Il faut alors rajouter un multiplexeur pour que l'entrée de réinitialisationr ecoive la bonne adresse de destination. [[File:Unité de chargement qui gère les branchements directs.png|centre|vignette|upright=2|Unité de chargement qui gère les branchements directs et indirects.]] Toute la difficulté de l'implémentation des branchements est de configurer les multiplexeurs, ce qui est réalisé par le séquenceur en fonction du mode d'adressage du branchement. ==Les optimisations du chargement des instructions== Charger une instruction est techniquement une forme d'accès mémoire un peu particulier. En clair, charger une instruction prend au minimum un cycle d'horloge, et cela peut rapidement monter à 3-5 cycles, si ce n'est plus. L'exécution des instructions est alors fortement ralentit par la mémoire. Par exemple, imaginez que la mémoire mette 3 cycles d'horloges pour charger une instruction, alors qu'une instruction s’exécute en 1 cycle (si les opérandes sont dans les registres). La perte de performance liée au chargement des instructions est alors substantielle. Heureusement, il est possible de limiter la casse en utilisant des mémoires caches, ainsi que d'autres optimisations, que nous allons voir dans ce qui suit. ===Le tampon de préchargement=== La technique dite du '''préchargement''' est utilisée dans le cas où la mémoire a un temps d'accès important. Mais si la latence de la RAM est un problème, le débit ne l'est pas. Il est possible d'avoir une RAM lente, mais à fort débit. Par exemple, supposons que la mémoire puisse charger 4 instructions (de taille fixe) en 3 cycles. Le processeur peut alors charger 4 instructions en un seul accès mémoire, et les exécuter l'une après l'autre, une par cycle d'horloge. Les temps d'attente sont éliminés : le processeur peut décoder une nouvelle instruction à chaque cycle. Et quand la dernière instruction préchargée est exécutée, la mémoire est de nouveau libre, ce qui masque la latence des accès mémoire. [[File:Tampon de préchargement d'instruction.png|vignette|Tampon de préchargement d'instruction]] La seule contrainte est de mettre les instructions préchargées en attente. La solution pour cela est d'utiliser un registre d'instruction très large, capable de mémoriser plusieurs instructions à la fois. Ce registre est de plus connecté à un multiplexeur qui permet de sélectionner l'instruction adéquate dans ce registre. Ce multiplexeur est commandé par le ''program counter'' et quelques circuits annexes. Ce super-registre d'instruction est appelé un '''tampon de préchargement'''. La méthode a une implémentation nettement plus simple avec des instructions de taille fixe, alignées en mémoire. La commande du multiplexeur de sélection de l'instruction est alors beaucoup plus simple : il suffit d'utiliser les bits de poids fort du ''program counter''. Par exemple, prenons le cas d'un registre d'instruction de 32 octets pour des instructions de 4 octets, soit 8 instructions. Le choix de l'instruction à sélectionner se fait en utilisant les 3 bits de poids faible du ''program counter''. Mais cette méthode ajoute de nouvelles contraintes d'alignement, similaires à celles vues dans le chapitre sur l'alignement et le boutisme, sauf que l'alignement porte ici sur des blocs d'instructions de même taille que le tampon de préchargement. Si on prend l'exemple d'un tampon de préchargement de 128 bits, les instructions devront être alignées par blocs de 128 bits. C'est à dire qu'idéalement, les fonctions et autres blocs de code isolés doivent commencer à des adresses multiples de 128, pour pouvoir charger un bloc d'instruction en une seule fois. Sans cela, les performances seront sous-optimales. : Il arrive que le tampon de préchargement ait la même taille qu'une ligne de cache. Lorsque l'on passe d'un bloc d'instruction à un autre, le tampon de préchargement est mis à jour. Par exemple, si on prend un tampon de préchargement de 4 instructions, on doit changer son contenu toutes les 4 instructions. La seule exception est l'exécution d'un branchement. En effet, lors d'un branchement, la destination du branchement n'est pas dans le tampon de préchargement et elle doit être chargée dedans (sauf si le branchement pointe vers une instruction très proche, ce qui est improbable). Pour cela, le tampon de préchargement est mis à jour précocement quand le processeur détecte un branchement. Le même problème survient avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans le tampon de préchargement sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas demande de vider le tampon de préchargement si le cas arrive, mais ça ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place. Le code automodifiant est alors buggé. ===La ''prefetch input queue''=== La ''prefetch input queue'' est une sorte de cousine du tampon de préchargement, qui a été utilisée sur les processeurs Intel 8 et 16 bits, ainsi que sur le 286 et le 386. L'idée est là encore de précharger des instructions en avance. Sauf que cette fois-ci, on ne charge pas plusieurs instructions à la fois. Au contraire, les instructions sont préchargées séquentiellement, un ou deux octet à la fois. En conséquence, le tampon de préchargement est remplacé par une mémoire FIFO appelée la '''''Prefetch Input Queue''''', terme abrévié en PIQ. Les instructions sont accumulées une par une dans la PIQ, elles en sortent une par une au fur et à mesure pour alimenter le décodeur d'instruction. Pendant que le processeur exécute une instruction, on précharge la suivante. Sans ''prefetch input queue'', le processeur chargeait une instruction, la décodait et l'exécutait, puis chargeait la suivante, et ainsi de suite. Avec un tampon de préchargement, le processeur chargeait plusieurs instruction en une seule fois, puis les exécutait les unes après les autres. Avec la ''prefetch input queue'', pendant qu'une instruction est en cours de décodage/exécution, le processeur précharge l'instruction suivante. Si une instruction prend vraiment beaucoup de temps pour s'exécuter, le processeur peut en profiter pour précharger l'instruction encore suivante, et ainsi de suite, jusqu'à une limite de 4/6 instructions (la limite dépend du processeur). La ''prefetch input queue'' permet de précharger l'instruction suivante à condition qu'aucun autre accès mémoire n'ait lieu. Si l'instruction en cours d'exécution effectue des accès mémoire, ceux-ci sont prioritaires sur tout le reste, le préchargement de l'instruction suivante est alors mis en pause ou inhibé. Par contre, si la mémoire n'est pas utilisée par l'instruction en cours d'exécution, le processeur lit l'instruction suivante en RAM et la copie dans la ''prefetch input queue''. En conséquence, il arrive que la ''prefetch input queue'' n'ait pas préchargé l'instruction suivante, alors que le décodeur d'instruction est prêt pour la décoder. Dans ce cas, le décodeur doit attendre que l'instruction soit chargée. Les instructions préchargées dans la ''Prefetch input queue'' y attendent que le processeur les lise et les décode. Les instructions préchargées sont conservées dans leur ordre d'arrivée, afin qu'elles soient exécutées dans le bon ordre, ce qui fait que la ''Prefetch input queue'' est une mémoire de type FIFO. L'étape de décodage pioche l'instruction à décoder dans la ''Prefetch input queue'', cette instruction étant par définition la plus ancienne, puis la retire de la file. Le premier processeur commercial grand public à utiliser une ''prefetch input queue'' était le 8086. Il pouvait précharger à l'avance 6 octets d’instruction. L'Intel 8088 avait lui aussi une ''Prefetch input queue'', mais qui ne permettait que de précharger 4 instructions. Le 386 avait une ''prefetch input queue'' de 16 octets. La taille idéale de la FIFO dépend de nombreux paramètres. On pourrait croire que plus elle peut contenir d'instructions, mieux c'est, mais ce n'est pas le cas, pour des raisons que nous allons expliquer dans quelques paragraphes. [[File:80186 arch.png|centre|vignette|700px|upright=2|Architecture du 8086, du 80186 et de ses variantes.]] Vous remarquerez que j'ai exprimé la capacité de la ''prefetch input queue'' en octets et non en instructions. La raison est que sur les processeurs x86, les instructions sont de taille variable, avec une taille qui varie entre un octet et 6 octets. Cependant, le décodage des instructions se fait un octet à la fois : le décodeur lit un octet, puis éventuellement le suivant, et ainsi de suite jusqu'à atteindre la fin de l'instruction. En clair, le décodeur lit les instructions longues octet par octet dans la ''Prefetch input queue''. Les instructions varient entre 1 et 6 octets, mais tous ne sont pas utiles au décodeur d'instruction. Par exemple, le décodeur d'instruction n'a pas besoin d'analyser les constantes immédiates intégrées dans une instruction, ni les adresses mémoires en adressage absolu. Il n'a besoin que de deux octets : l'opcode et l'octet Mod/RM qui précise le mode d'adressage. Le second est facultatif. En clair, le décodeur a besoin de lire deux octets maximum depuis la ''prefetch input queue'', avant de passer à l’instruction suivante. Les autres octets étaient envoyés ailleurs, typiquement dans le chemin de données. Par exemple, prenons le cas d'une addition entre le registre AX et une constante immédiate. L'instruction fait trois octets : un opcode suivie par une constante immédiate codée sur deux octets. L'opcode était envoyé au décodeur, mais pas la constante immédiate. Elle était lue octet par octet et mémorisée dans un registre temporaire placé en entrée de l'ALU. Idem avec les adresses immédiates, qui étaient envoyées dans un registre d’interfaçage mémoire sans passer par le décodeur d'instruction. Pour cela, la ''prefetch input queue'' était connectée au bus interne du processeur ! Le décodeur dispose d'une micro-opération pour lire un octet depuis la ''prefetch input queue'' et le copier ailleurs dans le chemin de données. Par exemple, l'instruction d'addition entre le registre AX et une constante immédiate était composée de quatre micro-opérations : une qui lisait le premier octet de la constante immédiate, une seconde pour le second, une troisième micro-opération qui commande l'ALU et fait le calcul. Le décodeur devait attendre que qu'un moins un octet soit disponible dans la ''Prefetch input queue'', pour le lire. Il lisait alors cet octet et déterminait s'il contenait une instruction complète ou non. Si c'est une instruction complète, il la décodait et l''exécutait, puis passait à l'instruction suivante. Sinon, il lit un second octet depuis la ''Prefetch input queue'' et relance le décodage. Là encore, le décodeur vérifie s'il a une instruction complète, et lit un troisième octet si besoin, puis rebelote avec un quatrième octet lu, etc. Un circuit appelé le ''loader'' synchronisait le décodeur d'instruction et la ''Prefetch input queue''. Il fournissait deux bits : un premier bit pour indiquer que le premier octet d'une instruction était disponible dans la ''Prefetch input queue'', un second bit pour le second octet. Le ''loader'' recevait aussi des signaux de la part du décodeur d'instruction. Le signal ''Run Next Instruction'' entrainait la lecture d'une nouvelle instruction, d'un premier octet, qui était alors dépilé de la ''Prefetch input queue''. Le décodeur d'instruction pouvait aussi envoyer un signal ''Next-to-last (NXT)'', un cycle avant que l'instruction en cours ne termine. Le ''loader'' réagissait en préchargeant l'octet suivant. En clair, ce signal permettait de précharger l'instruction suivante avec un cycle d'avance, si celle-ci n'était pas déjà dans la ''Prefetch input queue''. Le bus de données du 8086 faisait 16 bits, alors que celui du 8088 ne permettait que de lire un octet à la fois. Et cela avait un impact sur la ''prefetch input queue''. La ''prefetch input queue'' du 8088 était composée de 4 registres de 8 bits, avec un port d'écriture de 8 bits pour précharger les instructions octet par octet, et un port de lecture de 8 bits pour alimenter le décodeur. En clair, tout faisait 8 bits. Le 8086, lui utilisait des registres de 16 bits et un port d'écriture de 16 bits. le port de lecture restait de 8 bits, grâce à un multiplexeur sélectionnait l'octet adéquat dans un registre 16 bits. Sa ''prefetch input queue'' préchargeait les instructions par paquets de 2 octets, non octet par octet, alors que le décodeur consommait les instructions octet par octet. Il s’agissait donc d'une sorte d'intermédiaire entre ''prefetch input queue'' à la 8088 et tampon de préchargement. Le 386 était dans un cas à part. C'était un processeur 32 bits, sa ''prefetch input queue'' contenait 4 registres de 32 bits, un port d'écriture de 32 bits. Mais il ne lisait pas les instructions octet par cotet. A la place, son décodeur d'instruction avait une entrée de 32 bits. Cependant, il gérait des instructions de 8 et 16 bits. Il fallait alors dépiler des instructions de 8, 16 et 32 bits dans la ''prefetch input queue''. De plus, les instructions préchargées n'étaient pas parfaitement alignées sur 32 bits : une instruction pouvait être à cheval sur deux registres 32 bits. Le processeur incorporait donc des circuits d'alignement, semblables à ceux utilisés pour gérer des instructions de longueur variable avec un registre d'instruction. Les branchements posent des problèmes avec la ''prefetch input queue'' : à cause d'eux, on peut charger à l'avance des instructions qui sont zappées par un branchement et ne sont pas censées être exécutées. Si un branchement est chargé, toutes les instructions préchargées après sont potentiellement invalides. Si le branchement est non-pris, les instructions chargées sont valides, elles sont censées s’exécuter. Mais si le branchement est pris, elles ont été chargées à tort et ne doivent pas s’exécuter. Pour éviter cela, la ''prefetch input queue'' est vidée quand le processeur détecte un branchement. Pour cela, le décodeur d'instruction dispose d'une micro-opération qui vide la ''Prefetch input queue'', elle invalide les instructions préchargées. Cette détection ne peut se faire qu'une fois le branchement décodé, qu'une fois que l'on sait que l'instruction décodée est un branchement. En clair, le décodeur invalide la ''Prefetch input queue'' quand il détecte un branchement. Les interruptions posent le même genre de problèmes. Il faut impérativement vider la ''Prefetch input queue'' quand une interruption survient, avant de la traiter. Il faut noter qu'une ''Prefetch input queue'' interagit assez mal avec le ''program counter''. En effet, la ''Prefetch input queue'' précharge les instructions séquentiellement. Pour savoir où elle en est rendue, elle mémorise l'adresse de la prochaine instruction à charger dans un '''registre de préchargement''' dédié. Il serait possible d'utiliser un ''program counter'' en plus du registre de préchargement, mais ce n'est pas la solution qui a été utilisée. Les processeurs Intel anciens ont préféré n'utiliser qu'un seul registre de préchargement en remplacement du ''program counter''. Après tout, le registre de préchargement n'est qu'un ''program counter'' ayant pris une avance de quelques cycles d'horloge, qui a été incrémenté en avance. Et cela ne pose pas de problèmes, sauf avec certains branchements. Par exemple, certains branchements relatifs demandent de connaitre la véritable valeur du ''program counter'', pas celle calculée en avance. Idem avec les instructions d'appel de fonction, qui demandent de sauvegarder l'adresse de retour exacte, donc le vrai ''program counter''. De telles situations demandent de connaitre la valeur réelle du ''program counter'', celle sans préchargement. Pour cela, le décodeur d'instruction dispose d'une instruction pour reconstituer le ''program counter'', à savoir corriger le ''program coutner'' et éliminer l'effet du préchargement. La micro-opération de correction se contente de soustraire le nombre d'octets préchargés au registre de préchargement. Le nombre d'octets préchargés est déduit à partir des deux pointeurs intégré à la FIFO, qui indiquent la position du premier et du dernier octet préchargé. Le bit qui indique si la FIFO est vide était aussi utilisé. Les deux pointeurs sont lus depuis la FIFO, et sont envoyés à un circuit qui détermine le nombre d'octets préchargés. Sur le 8086, ce circuit était implémenté non pas par un circuit combinatoire, mais par une mémoire ROM équivalente. La petite taille de la FIFO faisait que les pointeurs étaient très petits et la ROM l'était aussi. Un autre défaut est que la ''Prefetch input queue'' se marie assez mal avec du code auto-modifiant. Un code auto-modifiant est un programme qui se modifie lui-même, en remplaçant certaines instructions par d'autres, en en retirant, en en ajoutant, lors de sa propre exécution. De tels programmes sont rares, mais la technique était utilisée dans quelques cas au tout début de l'informatique sur des ordinateurs rudimentaires. Ceux-ci avaient des modes d'adressages tellement limités que gérer des tableaux de taille variable demandait d'utiliser du code auto-modifiant pour écrire des boucles. Le problème avec la ''Prefetch input queue'' survient quand des instructions sont modifiées immédiatement après avoir été préchargées. Les instructions dans la ''Prefetch input queue'' sont l'ancienne version, alors que la mémoire RAM contient les instructions modifiées. Gérer ce genre de cas est quelque peu complexe. Il faut en effet vider la ''Prefetch input queue'' si le cas arrive, ce qui demande d'identifier les écritures qui écrasent des instructions préchargées. C'est parfaitement possible, mais demande de transformer la ''Prefetch input queue'' en une mémoire hybride, à la fois mémoire associative et mémoire FIFO. Cela ne vaut que très rarement le coup, aussi les ingénieurs ne s’embêtent pas à mettre ce correctif en place, le code automodifiant est alors buggé. Le décodeur d'instruction dispose aussi d'une micro-opération qui stoppe le préchargement des instructions dans la ''Prefetch input queue''. : Pour ceux qui ont déjà lu un cours d'architecture des ordinateurs, la relation entre ''prefetch input queue'' et pipeline est quelque peu complexe. En apparence, la ''prefetch input queue'' permet une certaines forme de pipeline, en chargeant une instruction pendant que la précédente s'exécute. Les problématiques liées aux branchements ressemblent beaucoup à celles de la prédiction de branchement. Cependant, il est possible de dire qu'il s'agit plus d'une technique de préchargement que de pipeline. La différence entre les deux est assez subtile et les frontières sont assez floues, mais le fait est que l'instruction en cours d'exécution et le préchargement peuvent tout deux faire des accès mémoire et que l'instruction en cours a la priorité. Un vrai pipeline se débrouillerait avec une architecture Harvard, non avec un bus mémoire unique pour le chargement des instruction et la lecture/écriture des données. ===Le ''Zero-overhead looping''=== Nous avions vu dans le chapitre sur les instructions machines, qu'il existe des instructions qui permettent de grandement faciliter l'implémentation des boucles. Il s'agit de l'instruction REPEAT, utilisée sur certains processeurs de traitement de signal. Elle répète l'instruction suivante, voire une série d'instructions, un certain nombre de fois. Le nombre de répétitions est mémorisé dans un registre décrémenté à chaque itération de la boucle. Elle permet donc d'implémenter une boucle FOR facilement, sans recourir à des branchements ou des conditions. Une technique en lien avec cette instruction permet de grandement améliorer les performances et la consommation d'énergie. L'idée est de mémoriser la boucle, les instructions à répéter, dans une petite mémoire cache située entre l'unité de chargement et le séquenceur. Le cache en question s'appelle un '''tampon de boucle''', ou encore un ''hardware loop buffer''. Grâce à lui, il n'y a pas besoin de charger les instructions à chaque fois qu'on les exécute, on les charge une bonne fois pour toute : c'est plus rapide. Bien sûr, il ne fonctionne que pour de petites boucles, mais il en est de même avec l'instruction REPEAT. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=Le chemin de données | prevText=Le chemin de données | next=L'unité de contrôle | nextText=L'unité de contrôle }} </noinclude> 2j2c0fl62nn1m9v81aqg2ixu2g94m57 Les cartes graphiques/La microarchitecture des processeurs de shaders 0 81538 744012 742652 2025-06-02T20:53:04Z Mewtow 31375 /* L'Operand Collector et les caches de register reuse */ 744012 wikitext text/x-wiki La conception interne (aussi appelée microarchitecture) des processeurs de ''shaders'' possède quelques particularités idiosyncratiques. La microarchitecture des processeurs de ''shaders'' est particulièrement simple. On n'y retrouve pas les fioritures des CPU modernes, tant utiles pour du calcul séquentiel : pas d’exécution dans le désordre, de renommage de registres, et autres techniques avancées. En conséquence, les unités de décodage et/ou de contrôle sont relativement simples, peu complexes. La majeure partie du processeur est dédié aux unités de calcul. [[File:Cpu-gpu.svg|centre|vignette|upright=2.0|Comparaison entre l'architecture d'un processeur généraliste et d'un processeur de shaders.]] ==Les unités de calcul d'un processeur de shader SIMD== Pour rappel, un processeur de shader supporte plusieurs types d'instructions. Au minimum, il supporte des ''instructions SIMD''. Mais il peut aussi gérer des ''instructions scalaires'', à savoir qu'elles travaillent sur des entiers/flottants isolés, non-regroupés dans un vecteur SIMD. Typiquement, il y a plusieurs types d'instructions scalaires : les calculs entiers, les calculs flottants simples, les calculs flottants complexes dit transcendantaux (calculs trigonométriques, des exponentielles, des logarithmes, des racines carrées ou racines carrées inverse). Et ces différentes instructions ont toutes des unités de calcul dédiées, ce qui fait qu'un processeur de shader contient un grand nombre d'unités de calcul très différentes. Le cœur est une unité de calcul SIMD, qui se charge des instructions SIMD. Mais d'autres unités de calcul sont présentes, surtout sur les architectures modernes. Il n'est pas rare de trouver une unité de calcul entière, ou des unités de calcul flottantes spécialisées pour les opérations transcendantales. ===Les unités de calcul SIMD=== [[File:SIMD2.svg|vignette|Une unité de calcul SIMD.]] Un processeur de shader incorpore une unité de calcul SIMD, qui effectue plusieurs calculs en parallèle. Elle regroupe plusieurs ALU flottantes regroupées ensemble et avec quelques circuits pour gérer les débordements et d'autres situations. En théorie, une unité de calcul SIMD regroupe autant d'unité de calcul qu'il y a d'entiers/flottants dans un vecteur. Par exemple, pour additionner deux vecteurs contenant chacun 16 flottants, il faut utilise 16 additionneurs flottants. Ce qui fait qu'une opération sur un vecteur est traité en une seule fois, en un cycle d'horloge. Une contrainte importante est que toutes les sous-ALU effectuent la même opération : ce ne sont pas des ALU séparées qu'on peut commander indépendamment, mais une seule ALU regroupant des circuits de calcul distinct. Le cout en circuit est d'autant plus grand que les vecteurs sont longs et le cout est approximativement proportionnel à la taille des vecteurs. Entre des vecteurs de 128 et 256 bits, l'unité de calcul utilisera globalement deux fois plus de circuits avec 256 bits qu'avec 128. Même chose pour les registres, mais c'est là un cout commun à toutes les architectures. Il y a quelques unités de calcul SIMD où le calcul se fait en deux fois, car on n'a que la moitié des unités de calcul. Par exemple, pour un vecteur de 32 flottants, on peut utiliser 16 unités de calcul, mais le temps de calcul se fait en deux cycles d'horloge. Les opérations sur les vecteurs sont donc faites en deux fois : une première passe pour les 16 premiers éléments, une seconde passe pour les 16 restants. L'implémentation demande cependant qu'une instruction de calcul soit décodée en deux micro-opérations. Par exemple, une instruction SIMD sur des vecteurs de 32 éléments est exécutée par deux micro-instructions travaillant sur des vecteurs de 16 éléments. On économise ainsi pas mal de circuits, mais cela se fait au détriment de la performance globale. L'avantage est que cela se marie bien avec l'abandon des opérations pour lesquelles masques dont tous les bits sont à 0. Par exemple, prenons une instruction travaillant sur 16 flottants, exécutée en deux fois sur 8 flottants. Si le masque dit que les 8 premières opérations ne sont pas à exécuter, alors l'ALU ne fera que le calcul des 8 derniers flottants. Pour cela, le décodeur doit lire le registre de masque lors du décodage pour éliminer une micro-instruction si besoin, voire les deux si le masque est coopératif. ===Plusieurs unités SIMD, liées au format des données=== Il faut préciser qu'il y a une séparation entre unités SIMD flottantes simple et double précision. Pour le dire plus clairement, il y a des unités SIMD pour les flottants 32 bits, d'autres pour les flottants 64 bits, et même d'autres pour les flottants 16 bits. Les flottants 64 bits sont utilisés dans les applications GPGPU, les flottants 16 et 32 bits le sont dans le rendu 3D, et les flottants 16 bits pour tout ce qui lié à l'IA. Malheureusement, on doit utiliser des ALU flottantes séparées pour chaque taille, le format des flottants n'aidant pas. Depuis plus d'une décennie, les cartes graphiques ont des unités SIMD à la fois pour les calculs entiers et flottants. Elles sont censées être séparées. Pour NVIDIA, avant l'architecture Turing, les unités SIMD entières et flottantes sont décrites comme séparées dans leurs ''white papers'', avec des unités INT32 et FLOAT32 séparées, combinées à d'autres unités de calcul. L'architecture Volta a notamment des unités INT32, FLOAT32 et FLOAT64 séparées. A partir de l'architecture Ampere, il semblerait que les unités SIMD soient devenues capables de faire à la fois des calculs flottants et entiers, pour la moitié d'entre elles. Mais il se pourrait simplement qu'elles soient physiquement séparées, mais reliées aux reste du processeur de manière à ne pas être utilisables en même temps. Il est cependant possible que sur d'anciennes architectures, les unités entières et flottantes partagent des circuits, notamment pour ce qui est de la multiplication. En effet, une unité de calcul flottante contient des circuits pour faire des calculs entiers pour additionner/multiplier les mantisses et les exposants. Il est possible d'utiliser ce circuit Un exemple est le cas de l'architecture GT200 d'NVIDIA, sur laquelle les "pseudo-ALU" entières SIMD étaient limitées à des multiplications d'opérandes 24 bits, ce qui correspond à la taille d'une mantisse d'un flottant 32 bits. Le design exact des ALU n'est pas connu. ===Les unités de calcul scalaires=== Les GPU modernes incorporent une '''unité de calcul entière scalaire''', séparée de l'unité de calcul SIMD. Elle gère des calculs scalaires, à savoir qu'elle ne travaille pas sur des vecteurs. Elle gère divers calculs, comme des additions, soustractions, comparaisons, opérations bit à bit, etc. Elle exécute les instructions de calcul entière sur des nombres entiers isolés, de plus en plus fréquentes dans les shaders. Elle est parfois accompagnée d'une unité de calcul pour les branchements. Par branchements, on veut parler des vrais branchements similaires à ceux des CPU, qui effectuent des tests sur des entiers et effectuent des branchements conditionnels. Ils n'ont rien à voir avec les instructions à prédicat qui elles sont spécifiques à l'unité de calcul vectorielles. Ce sont des instructions séparées, totalement distinctes Les processeurs de shaders incorporent aussi une '''unité de calcul flottante scalaire''', utilisée pour faire des calculs sur des flottants isolés. L'unité de calcul gère généralement des calculs simples, comme les additions, soustractions, multiplications et divisions. Il s'agit typiquement d'une unité de calcul spécialisée dans l’opération ''Multiply-And-Add'' (une multiplication suivie d'une addition, opération très courante en 3D, notamment dans le calcul de produits scalaires), qui ne gère pas la division. L'unité de calcul flottante est souvent accompagnée d'une unité de calcul spécialisée qui gère les calculs transcendantaux, avec une gestion des calculs trigonométriques, de produits scalaires ou d'autres opérations. Elle porte le nom d''''unité de calcul spéciale''' (''Special Function Unit''), ou encore d'unité de calcul transcendantale, et elle a d'autres appellations. Elle est composée de circuits de calculs accompagnés par une table contenant des constantes nécessaires pour faire les calculs. Rappelons que les registres SIMD et les registres scalaires sont séparés et ne sont pas adressés par les mêmes instructions. Les registres scalaires sont placés dans un banc de registre physiquement séparé du banc de registres SIMD. Le banc de registre scalaire est relié à sa propre ALU scalaire, il y a vraiment une séparation physique entre registres scalaires et SIMD. Il existe cependant un système d'interconnexion qui permet d'envoyer un scalaire aux unités SIMD, ce qui est utile pour les opérations de produits scalaire ou autres. ===L'unité de texture/lecture/écriture=== L'unité d'accès mémoire s'occupe des lectures et écriture en général, et elle prend en charge les accès aux textures, le filtrage de textures et tout un tas de fonctionnalités liées aux textures. La seule différence entre un accès aux textures et une lecture/écriture en mémoire est que les circuits de filtrage de texture sont contournés dans une lecture/écriture normale. Dans ce qui suit, nous allons l'appeler l'unité de texture par souci de simplification. ==La gestion des dépendances de données== Un processeur de ''shaders'' SIMD contient donc beaucoup d'unité de calcul, qui peuvent en théorie fonctionner en parallèle. Il est en théorie possible d'exécuter des instructions séparés dans des unités de calcul séparées. Par exemple, reprenons l'exemple de l'unité de vertices de la Geforce 6800, mentionné au-dessus. Elle dispose d'une unité de calcul SIMD MAD, et d'une unité de texture, ainsi que d'une unité de calcul scalaire transcendantale. Il en en théorie possible de faire, en même temps, un calcul dans chaque ALU. Pendant que l'unité transcendantale fait un calcul trigonométrique quelconque, l'autre ALU effectue des calculs SIMD sur d'autres données. Pour cela, une possibilité est d'utiliser des instructions à ''co-issue''. Le problème est que ces instructions sont surtout utiles pour exécuter des instructions scalaires en parallèle d'instruction SIMD, mais guère plus. Aussi, nous allons mettre la ''co-issue'' de côté. Dans ce qui suit, nous allons partir du principe que le processeur peut démarrer une nouvelle instruction par cycle d'horloge. Et cela permet malgré tout d’exécuter plusieurs instructions en même temps dans des unités de calcul séparées. La raison est que la plupart des instructions prend plusieurs cycles d'horloge à s’exécuter. Ainsi, pendant qu'une instruction en est à son second ou troisième cycle dans une ALU, il est possible de démarrer une nouvelle instruction dans une ALU inoccupée, s'il y en a une. La seule contrainte est que les deux instructions soient indépendantes. Les processeurs de ''shaders'' en sont capables, tout comme les CPU. Mais les CPU utilisent au mieux cette possibilité. Ils intègrent des circuits d'exécution dans le désordre, de renommage de registre, et bien d'autres. Mais leur implémentation demande un budget en transistors conséquent, que les GPU ne peuvent pas se permettre. A la place, ils utilisent une technique appelée le '''''multithreading'' matériel''', une technique qui vient du monde des processeurs, où cette technique a été appliquée à de nombreuses reprises. Vous connaissez sans doute l'''hyperthreading'' d'Intel ? C'est une version basique du ''multithreading'' matériel. L'idée est d'exécuter plusieurs programmes en même temps sur le même processeur, le processeur commutant de l'un à l'autre suivant les besoins. Par exemple, si un ''thread'' est bloqué par un accès mémoire, d'autres ''threads'' exécutent des calculs dans l'unité de calcul en parallèle de l'accès mémoire. Les programmes en question sont appelés des ''threads'', l'équivalent sur un GPU est un ''warp'', ni plus ni moins. Un processeur de ''shader'' commute donc régulièrement d'un ''warp'' à l'autre, suivant les besoins. Dans ce qui va suivre, nous allons voir dans quelles situations un processeur de 'shader'' change de ''thread''/''warp'' en cours d'exécution. Suivant le GPU, les situations ne sont pas les mêmes. ===Les lectures non-bloquantes avec ''multithreading'' matériel=== Les processeurs de ''shader'' sont connectés à une mémoire vidéo très lente, avec un temps d'accès élevé, qui se rattrape avec un débit binaire important. La conséquence est qu'un accès à une texture, c'est long : si celle-ci est lue depuis la mémoire vidéo, le temps d'attente est d'une bonne centaine de cycles d'horloges. Pour limiter la casse, les unités de texture incorporent un cache de texture, mais cela ne suffit pas toujours à alimenter les processeurs de ''shaders'' en données. Et cs derniers ne peuvent pas recourir à des techniques avancées communes sur les CPU, comme l’exécution dans le désordre : le cout en circuit serait trop important. Fort heureusement, les processeurs de ''shaders'' disposent d'optimisations pour remplir ces temps d'attente avec des calculs indépendants de la texture lue. Les anciennes cartes graphiques d'avant les années 2000 géraient une forme particulière de '''lectures non-bloquantes'''. L'idée est simple : pendant qu'on effectue une lecture dans l'unité de texture, on peut faire des calculs en parallèle dans les ALU de calcul. Mais la technique n'est possible que si les instructions de calcul n'ont pas comme opérande un texel en cours de lecture. Il ne faut pas qu'il y a ai une dépendance entre les instructions exécutées dans l'ALU et un texel pas encore lu. Pour cela, la carte graphique fait des vérifications sur les registres. La lecture charge le texel dans un registre, appelé le registre de destination (sous entendu, de destination de la lecture). Les instructions qui n'utilisent pas ce registre peuvent s'exécuter sans problèmes : elles sont indépendantes de la lecture. Mais les autres ont une dépendance et ne sont pas exécutées. Détecter les dépendances demande juste de mémoriser le registre de destination dans un registre temporaire, et de faire des comparaisons. Pour cela, le processeur de ''shader'' incorpore un circuit situé juste après le décodeur d'instruction, appelé l'unité d'émission. Elle compare les registres utilisés par l'instruction avec le registre de destination. Si il y a correspondance, l'instruction est mise en attente. La mise en attente bloque alors toutes les instructions suivantes. En clair, dès qu'on tombe sur une instruction dépendante, le processeur cesse d'émettre des instructions dans l'ALU, et attend la fin de la lecture. Il n'a pas vraiment le choix. Faire autrement serait possible, mais demanderait d'implémenter des techniques d'exécution dans le désordre très gourmandes en circuits. Depuis l'époque de Direct X 9, les GPU combinent les lectures non-bloquantes avec le ''multithreading'' matériel. L'idée est que si un ''thread'' effectue un accès mémoire, le ''thread'' est mis en pause pendant l'accès mémoire et laisse la place à un autre. Le ''thread'' est réveillé une fois que l'accès mémoire est terminé. L'avantage est que si un ''thread'' est mis en pause par une lecture, les autres ''threads'' récupèrent les cycles d'horloge du ''thread'' mis en pause. Par exemple, sur un processeur qui gère 16 ''threads'' concurrents, si l'un d'eux est mis en pause, le processeur changera de ''thread'' tous les 15 cycles au lieu de 16. Ou encore, un ''thread'' aura droit à deux cycles consécutifs pour s’exécuter. Faire ainsi marche assez bien si on a beaucoup de ''threads'' dont peu d'entre eux font des lectures/écritures. L'avantage est que si un thread est mis en pause par une lecture, les autres threads récupèrent les cycles d'horloge du thread mis en pause. Par exemple, sur un processeur qui gère 16 threads concurrents, si l'un d'eux est mis en pause, le processeur changera de thread tous les 15 cycles au lieu de 16. Ou encore, un thread aura droit à deux cycles consécutifs pour s’exécuter. Faire ainsi marche assez bien si on a beaucoup de threads dont peu d'entre eux font des lectures/écritures. L'implémentation de cette technique est assez simple au premier abord. L'unité de chargement a plusieurs ''program counter'', un par ''thread''. Un circuit dédié sait quels ''threads'' sont mis en pause, et en envoie un aux unités de calculs. La technique impose cependant que les registres soient dupliqués, pour que chaque ''thread'' ait ses propres registres rien qu'à lui. Sans cela, impossible de passer rapidement d'un ''thread'' à l'autre à chaque cycle. Un processeur de ''shader'' peut exécuter entre 16 et 32 ''thrads''/''warps'', ce qui multiplie le nombre de registres par 16/32. Et il y a la même chose avec d'autres structures matérielles, comme les files de lecture/écriture de l'unité d'accès mémoire. [[File:Aperçu de l'architecture d'un processeur multithreadé.png|centre|vignette|upright=2|Aperçu de l'architecture d'un processeur multithreadé]] ===Le ''scoreboard'' des GPU des années 2000-2010=== Les lectures non-bloquantes permettent de gérer le cas des instructions d'accès mémoire. Mais il y a d'autres instructions qui prennent plus d'un cycle d'horloge pour s'exécuter. Les instructions de calcul basiques d'un GPU prennent 2 à 3 cycles d'horloge dans le meilleur des cas, parfois plus d'une dizaine. De telles instructions sont autant d'opportunités pour exécuter plusieurs instructions en même temps. Pendant qu'une instruction multicycle occupe une ALU, les autres ALU peuvent accepter d'autres instructions. Les processeurs de ''shaders'' SIMD peuvent démarrer une nouvelle instruction scalaire/SIMD par cycle, si les conditions sont réunies. Le problème est alors le suivant : deux instructions démarrées l'une après l'autre doivent occuper des ALU différentes, mais en plus elles doivent manipuler des données différentes. Prenons un exemple simple : une instruction calcule un résultat, qui est utilisé comme opérande par une seconde instruction. La seconde ne doit pas démarrer tant que la première n'a pas enregistré son résultat dans les registres. Il s'agit d'une dépendance dite RAW (''Read After Write'') typique, que la carte graphique doit gérer automatiquement. Il existe aussi d'autres dépendances liées au fait que deux instructions utilisent les mêmes registres, mais laissons-les de côté pour le moment. Il faut dire qu'avec 4096 registres par ''shader'', elles sont plus rares. Les dépendances en question sont regroupées sous le terme de '''dépendances de données'''. S'il y a une dépendance de données entre deux instructions, on ne peut pas les exécuter en parallèle dans des unités de calcul séparées. Sur les cartes graphiques des années 2000-2010, un circuit dédié appelé le '''''scoreboard''''' détectait ces dépendances. Pour cela, il vérifie si deux instructions utilisent les mêmes registres. : Précisons que le grand nombre de registres et de ''threads'' fait qu'un ''scoreboard'' classique, tel que décrit dans les cours d'architecture des ordinateurs, devient rapidement impraticable. Aussi, une implémentation alternative est utilisée, bien que les détails ne soient pas connus à ce jour. Quelques brevets donnent des détails d'implémentation, mais on ne sait pas s'ils sont à jour. Les curieux peuvent tenter de lire le brevet américain numéro #7,634,621, nommé ''"Register File Allocation"'', déposé par NVIDIA durant décembre 2009. A chaque cycle, le ''scoreboard'' reçoit une instruction provenant du décodeur et vérifie si elle peut être exécutée. Il vérifie les dépendances de données, mais aussi d'autres formes de dépendances. Notamment, il vérifie qu'il y a une unité de calcul libre pour exécuter l'instruction.S'il n'y a pas de dépendance, elle est envoyée à une unité de calcul inoccupée, s'il y en a une. Mais s'il y a une dépendance de donnée, le processeur de ''shader'' met en pause le ''thread''/''warp'' et bascule sur un autre ''thread''. Le ''thread'' est mis en pause tant que la dépendance n'est pas résolue. A chaque cycle, le processeur détecte les dépendances et choisit une instruction parmi celles qui peuvent s'exécuter, peu importe leur ''thread''. L'implémentation sépare le processeur de ''shader'' en deux sections séparées par une mémoire tampon qui met en attente les instructions SIMD. Les instructions SIMD sont chargées et décodées, puis sont placées dans une ou plusieurs '''files d'instruction'''. Le cas le plus simple à comprendre utilise une file d'instruction par ''thread''. Les instructions attendent leur tour dans la file d'instruction. L'unité d'émission vérifie à chaque cycle quelles instructions sont prêtes à s'exécuter, dans chaque file d'instruction. L'unité d'émission choisit un ''thread'' et envoie l'instruction la plus ancienne dans la file d'instruction aux unités de calcul. Les instructions qui ont besoin d'un résultat pas encore calculé ou lu depuis la mémoire attendent juste. [[File:FGMT sur un processeur de shaders.png|centre|vignette|upright=2|FGMT sur un processeur de shaders]] Mais pour cela, il faut que ces derniers aient des instructions en attente dans la file d'instruction. Le processeur doit avoir chargé assez d'instructions en avance, il faut que chaque ''thread'' ait assez de réserve pour exécuter plusieurs instructions consécutives. Pour éviter ce problème, le processeur profite du fait que le chargement des instructions depuis la mémoire et leur exécution se font en même temps : le processeur charge des instructions pendant qu'il en exécute d'autres. Plus haut, nous avions dit que l'unité de chargement mémorise plusieurs ''program counter'', un par ''thread'', et choisit à chaque cycle l'un d'entre eux pour charger une instruction. Le choix en question est synchronisé avec l'émission des instructions. Si un ''thread'' émet une instruction, ce même ''thread'' charge une instruction au même moment. Sauf si la file d'instruction du ''thread'' est déjà pleine, auquel cas un autre ''thread'' est choisit. ===L'encodage explicite des dépendances sur les GPU post-2010=== Depuis environ 2010, les GPU n'utilisent plus de ''scoreboard'' proprement dit. A la place, les GPU modernes déportent la détection des dépendances de données à la compilation. L'idée est que chaque instruction contient quelques bits pour dire au processeur : tu peux lancer 1, 2, 3 instructions à la suite sans problème. La technique porte le nom d''''anticipation de dépendances explicite''' (''Explicit-Dependence lookahead''). Un exemple historique assez ancien est le processeur Tera MTA (''MultiThreaded Architecture''), qui utilisait cette technique. Les GPU NVIDIA modernes utilisent plusieurs bits par instruction pour gérer les dépendances de données. Un premire mécanisme est utilisé pour bloquer l'émission d'une nouvelle instruction pendant x cycles. Il utilise un '''''stall counter''''', qui mémorise le nombre de cycles d'attente. Une instruction peut initialiser le ''stall counter'' avec une valeur de base, qui indique combien de cycles attendre. Le ''stall counter'' est décrémenté à chaque cycle d'horloge et une nouvelle instruction s'exécute seulement quand le compteur atteint 0. Il est utilisé quand une instruction productrice prenant X cycles est suivie par une instruction consommatrice. Le ''stall counter'' est alors initialisé à la valeur X. La méthode précédente ne vaut cependant que pour les instructions dont le compilateur peut prédire la durée. En clair, les accès mémoire et certaines instructions spéciales ne sont pas prises en charge. Pour les gérer, les GPU modernes utilisent un autre mécanisme, basé sur des '''compteurs de dépendances'''. Il y en a plusieurs par ''thread'', entre 5 et 10 selon le GPU. Une instruction productrice réserve un de ces compteur, l'incrémente quand elle démarre son exécution/est émise, le décrémente quand la dépendance est résolue. Les instructions consommatrices doivent attendre que le compteur tombe à zéro pour s'exécuter. Elles précisent quels compteurs regarder avec un '''masque de compteurs de dépendance''', encodé directement dans l'instruction elle-même. Le masque est composé de bits à 0/1, un par compteur. Précisément, chaque instruction productrice se réserve deux compteurs, pour gérer les trois types de dépendances de données (RAW, WAR et WAW). Le premier compteur est décrémenté quand le résultat est écrit dans les registres, ce qui gère naturellement les dépendances RAW et WAW. Le second est décrémenté quand l'instruction a lu ses opérandes, ce qui gère les dépendances WAR. Les autres instructions regarde l'un ou l'autre des compteurs selon leur situation. Il arrive même que le switch de ''thread'' soit géré par des bits intégrés dans l'instruction. Par exemple, sur les GPU NVIDIA modernes, chaque instruction contient un bit '''''yield''''' qui indique qu'il faut changer de ''thread'' une fois l'instruction émise. En clair, il indique que l'instruction risque de durer longtemps, a des dépendances avec la mémoire ou autre chose qui fait qu'il est préférable de changer de ''thread''. ==Le banc de registres d'un processeur de ''shader''== Les GPU disposent d'un grand nombre de registres. Les normes de DirectX et Open GL imposent que les shaders modernes gèrent au moins 4096 registres généraux par instance de shader, avec des registres spécialisés en plus. En soi, 4096 est énorme ! Mais au-delà de ces normes, le FGMT implique de dupliquer des registres par le nombre de ''threads hardware'' simultanés. Avec le FGMT, les registres devront être dupliqués pour que chaque ''thread'' ait ses propres registres rien qu'à lui. Sans cela, impossible de passer rapidement d'un ''thread'' à l'autre à chaque cycle. Maintenant, faisons quelques calculs d'épiciers. Un processeur de ''shader'' peut exécuter entre 16 et 32 ''threads''/''warps'', ce qui multiplie le nombre de registres par 16/32. En multipliant par les 4096 registres nécessaires, cela fait 128 kilooctets de mémoire rien que pour les registres. Et c'est pour un seul cœur ! Si on multiplie par le nombre de cœurs, on trouve que les cartes graphiques modernes ayant plusieurs processeurs de ''shaders'' ont facilement entre 32 768 et 65 536 registres de 32 bits, ce qui est énorme ! Il y a plus de mémoire gaspillée dans les registres que dans le cache L1 ou L2 ! Et ce grand nombre de registres par cœur pose quelques problèmes. Les registres sont regroupés dans une petite mémoire SRAM, adressable, appelée le '''banc de registre'''. Et comme toutes les mémoires, plus ce banc de registres est grand, plus il est lent. En conséquence, lire un opérande dans les registres prend beaucoup de temps. Du moins, c'est le cas sans optimisations. Et les GPU implémentent de nombreuses parades pour limiter le nombre de registres réellement présents dans leur silicium. ===L'allocation dynamique/statique des registres par ''thread''=== Les GPU modernes n'implémentent pas le nombre maximal de registres demandés. Par exemple, si je prends les GPU AMD de type RDNA 4, il peuvent gérer 16 ''threads'' hardware simultanés, chacun ayant accès à 256 registres, registres faisant 128 octets chacun. On s'attend à avoir un banc de registre de 16 * 256 * 128 octets, soit 512 Kilo-octets. En somme, un banc de registre de la taille du cache L1. Sauf que les GPUs en question intègrent moins de registres que prévu ! Ils ont précisément une taille de 192 kilo-octets, soit 96 registres pour chacun des 16 ''threads''. En effet, 256 registres est un nombre maximal, que la plupart des ''shaders'' n'utilise pas totalement. La plupart des ''shaders'' utilise entre 64 et 128 registres, rarement moins, rarement plus. Aussi, le GPU partitionne le banc de registres à la demande entre les ''threads'', en leur donnant seulement une partie des registres. Le partitionnement peut être pseudo-statique, à savoir que le banc de registre est découpé en parts égales pour chaque ''thread'', ou dynamique avec un nombre de registre variant d'un ''thread'' à l'autre, selon les besoins. Prenons l'exemple d'un '''partitionnement pseudo-statique''', avec l'exemple des GPU AMD RDNA 1 et 2. Leur banc de registre fait 1024 registres, de 128 octets chacun, soit 128 KB au total. Le GPU gère 16 ''threads'' simultanés maximum. Avec un seul ''thread'' d'exécuté, le ''thread'' unique peut utiliser les 1024 registres du banc de registre pour lui tout seul. Avec deux ''threads'', chacun aura droit à 512 registres, soit la moitié du cas précédent. Avec 16 ''thread'' simultanés, chaque ''thread'' a accès à 64 registres, pas plus. Et ainsi de suite : le nombre de registre par ''thread'' est égal à la taille du banc de registre divisée par le nombre de ''threads''. A l'heure où j'écris ces lignes, courant 2025, les GPU Intel se contentent d'un partitionnement statique très limité. Avant les GPU d'architecture Battlemage, il n'y avait pas de partitionnement du banc de registre, tous les ''threads'' avaient 128 registre à leur disposition. Les GPU Battlemage et ses successeurs ont introduit un partitionnement limité, avec deux modes : un mode sans partitionnement où tous les ''threads'' ont accès à 128 registres, un mode avec partitionnement qui divise le nombre de ''thread'' par deux et leur donne chacun 256 registres. Pas de possibilité de diviser plus le nombre de ''threads''. Les GPU AMD et NVIDIA sont eux plus compétents niveau partitionnement statique. Par exemple, les GPU RDNA 4 supportent les partitionnements suivants : * 16 ''threads'' avec 96 registres chacun ; * 12 ''threads'' avec 120 registres chacun ; * 10 ''threads'' avec 144 registres chacun ; * 9 ''threads'' avec 168 registres chacun ; * 8 ''threads'' avec 192 registres chacun ; * 7 ''threads'' avec 216 registres chacun ; * 6 ''threads'' avec 240 registres chacun ; * 5 ''threads'' avec 256 registres chacun. Le partitionnement pseudo-statique est simple à implémenter, il ne demande pas beaucoup de circuits pour fonctionner. Il est rapide et a de bonnes performances pour le rendu graphique en rastérisation. La raison est qu'en rastérisation, les différents ''threads'' sont souvent des copies/instances d'un même ''shader'' qui travaillent sur des données différentes. Leur donner le même nombre de registres colle bien avec cet état de fait. Cependant, si les différents ''threads'' sont des ''shaders'' différents, les choses ne sont pas optimales. Un ''shader'' utilisera plus de registres que l'autre, leur donner le même nombre de registres n'est pas optimal. Par exemple, imaginons que l'on a deux shaders, nommés shaders 1 et 2, aux besoins différents, l'un étant gourmand en registres et l'autre très économe. Dans ce cas, il faudrait partitionner le banc de registre pour donner plus de registre au premier et moins au second. Il s'agit là d'un '''partitionnement dynamique'''. Le partitionnement dynamique est plus optimal pour gérer des ''shaders'' déséquilibrés niveau registres, mais a une implémentation matérielle plus complexe. Il a été introduit assez tard, car il a fallu attendre que le rayctracing se démocratise. En effet, le partitionnement dynamique du banc de registre est surtout utile pour le raytracing. Exécuter simultanément des shaders déséquilibrés en registres est peu fréquent avec la rastérisation, beaucoup plus courant avec le raytracing. NVIDIA et AMD ont des implémentations différentes du partitionnement dynamique. Les GPU AMD RDNA 4 allouent un nombre minimal de registre à chaque ''thread'', mais ils peuvent demander d'avoir accès à plus de registres si besoin. Quand un ''thread'' a besoin de plus de registres, il exécute une instruction dédiée, qui sert à demander plus de registres, ou au contraire à en libérer s'ils sont inutilisés. La demande d'allocation de nouveaux registres se fait par blocs de 16 à 32 registres, suivant comment est configuré le processeur. Précisons que l'instruction d'allocation n'est disponible que pour les ''compute shaders'' et pas les ''shaders'' graphiques. L'instruction d'allocation de registre précédent peut échouer dans certains cas. Si assez de registres sont disponibles, à savoir inutilisés par d'autres ''threads'', l'instruction réussit. Dans le cas contraire, elle échoue et le ''shader'' est mis en pause avant de retenter cette demande plus tard. Le résultat de l'instruction, échec ou réussite, est mémorisé dans le registre d'état. La technique a pour défaut que certaines situations peuvent mener à un blocage complet du processeur, où chaque ''thread'' ne peut plus poursuivre son exécution, faute de registres disponibles. Des méthodes pour éviter cette situation sont implémentés sur ces GPU, mais la documentation n'est pas très explicite. Sur les GPU NVIDIA, il y a aussi une instruction d'allocation de registre, mais elle fonctionne différemment. Elle permet d'échanger des registres entre ''threads''. Une première différence est que tous les ''threads'' commencent avec une allocation égale des registres. Les ''threads'' démarrent tous avec le même nombre de registres. Un ''thread'' peut libérer des registres, qui sont alors alloués à un autre ''thread'', le ''thread'' en question pouvant être choisit par le ''thread'' qui libère les registres. ===Le banc de registre est multiport de type externe=== Le banc de registre doit permettre de lire deux vecteurs SIMD par opération, soit deux lectures simultanées. Pour cela, le banc de registre contient deux ports de lecture, chacun permettant de lire un opérande dans le banc de registre. Mais plus le nombre de ports augmente, plus la consommation énergétique du banc de registre augmente, sans compter que celui-ci devient plus lent. Les processeurs peuvent utilisent des bancs de registres ayant réellement deux ports par banc de registre. Un port de lecture est implémenté avec un composant appelé un multiplexeur, connecté à tous les registres. [[File:Mémoire multiport faite avec des MUX-DEMUX.png|centre|vignette|upright=2|Mémoire multiport faite avec des MUX-DEMUX]] Les GPU ne peuvent pas se permettre un tel luxe. Leur banc de registre doit alimenter plusieurs unités de calcul en même temps, en parallèle. Le nombre de ports serait plus proche de 4 à 10 ports de lectures. La solution précédente aurait un budget en transistor et un budget thermique trop important. À la place, ils utilisent une autre méthode : ils simulent un banc de registre à plusieurs ports avec un ou plusieurs bancs de registres à un port. On parle alors de '''multiport externe'''. [[File:Mémoire multiport à multiportage externe.png|centre|vignette|upright=2.5|Mémoire multiport à multiportage externe.]] Il existe plusieurs méthodes de multiport externe. Mais celle utilisée sur les GPU simule un banc de registre multiport à partir de plusieurs bancs de registres à un port. Le banc de registre est en réalité formé de plusieurs banques, de plusieurs bancs de registre séparés, chacun mono-port. L'idée est que si l'on accède à deux banques en même temps, on peut lire deux opérandes, une par port/banc de registre. Par contre, si les deux opérandes à lire sont la même banque, il y a un '''conflit d'accès aux banques'''. [[File:Mémoire à multiports par banques.png|centre|vignette|upright=2|Mémoire à multiports par banques.]] ===L'''Operand Collector'' et les caches de ''register reuse''=== Sans conflit d'accès à une banque, les deux opérandes sont disponibles immédiatement. Par contre, en cas de conflit d'accès aux banques, les deux opérandes sont lus l'une après l'autre. En clair, le premier opérande doit être mis en attente quelque part pendant que la seconde est en cours de lecture. Et le problème survient souvent, surtout avec les opérations FMA qui utilisent trois opérandes, encore plus avec les rares opérations qui demandent 4 à 5 opérandes. Pour gérer les conflits d'accès aux banques, les GPU utilise un circuit dédié, appelé le '''collecteur d'opérandes''' (''operand collector''). Le rôle du collecteur d'opérandes est d'accumuler les opérandes en attente, son nom est assez transparent. Il accumule les opérandes en attente, puis les envoie aux unités de calcul quand elles sont toutes prêtes, toutes lues depuis le banc de registres. Les opérandes sont mis en attente dans des entrées, qui contiennent la donnée, l'identifiant du ''thread''/''warp'' pour ne pas confondre des opérandes entre ''threads'', et deux bits d'occupation. Les deux bits d'occupation indiquent si l'entrée est vide, réservée pour un opérande en cours de lecture ou occupée par un opérande. Le collecteur d'opérande est souvent accompagné de '''registres temporaires''', qui mémorisent le résultat d'une instruction précédente. Il y a un registre temporaire par ALU, le résultat fournit par une ALU est mémorisé dans le registre temporaire associé. Une instruction peut lire une opérande dans un registre temporaire, ce qui permet de lire le résultat d'une instruction précédente sans passer par le banc de registres. Le collecteur d'opérande est alors configuré pour récupérer les opérandes adéquats dans les registres temporaires adéquats. : Pour faire une comparaison avec les processeurs modernes, ces registres sont une forme de ''data forwarding'', de contournement, mais qui est rendue explicite pour le logiciel. Une optimisation des GPU récent vise à réduire les accès aux bancs de registres en utilisant une mémoire cache spécialisée. Il s'agit de l'''operand reuse cache'', aussi appelés '''''register reuse cache'''''. L'idée est que quand un opérande est lu depuis le banc de registres, elle peut être stockée dans ce cache pour des utilisations ultérieures. Les architectures Volta, Pascal et Maxwell disposent de 4 caches de ce type, chacun stockant 8 données/opérandes/résultats Il s'agit en réalité de pseudo-caches, car ils sont partiellement commandés par le logiciel. Une instruction précise qu'un opérande doit être stocké dans un ''register reuse cache'', pour une utilisation ultérieure. Pour cela, elle incorpore quelques bits pour préciser qu'elle doit être placée dans le cache. Les bits font en quelque sorte partie du mode d'adressage. Si l'instruction immédiatement suivante lit ce registre dans le même ''slot'' d'opérande lira l'opérande dans le cache. La technique est donc assez limitée, mais elle a des résultats pas négligeables. Les ''register reuse cache'' et le collecteur opérandes sont sans doute fusionnés en un seul circuit, plutôt que d'utiliser deux circuits séparés. La raison est que les deux doivent mémoriser des opérandes les mettre en attente pour une utilisation ultérieure, et sont placés juste après le banc de registre. NVIDIA a publié deux brevets à propos de ces deux techniques, mais rien n'indique que c'est exactement cette technique qui utilisée dans les cartes modernes. Il faut dire que le nombre de banques a changé suivant les cartes graphiques. * [https://patents.google.com/patent/US7834881B2/en Operand collector architecture ] * [https://patents.google.com/patent/US20130159628A1/en Methods and apparatus for source operand collector caching ] ==Les processeurs de shaders VLIW== Une autre forme d'émission multiple est l'usage d'un jeu d'instruction VLIW et/ou d'instructions en ''co-issue'', abordés dans les chapitres précédents. Pour rappel, un processeur VLIW regroupe plusieurs opérations en une seule instruction machine. L'instruction encode les calculs à faire en parallèle, en ''co-issue''. Elle précise les registres, l'opcode de l'instruction, et tout ce qu'il faut pour faire les calculs, et attribue implicitement une unité de calcul à chaque opération. Les opérations regroupées sont garanties indépendantes par le compilateur, ce qui fait que le décodeur d'instruction envoie chaque opération à l'unité de calcul associée, sans avoir à faire la moindre vérification de dépendances entre instructions. L'unité d'émission est donc grandement simplifiée, elle n'a pas à découvrir les dépendances entre instructions. Au passage, cela explique pourquoi les premières cartes graphiques étaient de type VLIW, alors que les modernes sont de type SIMD. Les anciennes cartes graphiques préféraient se passer de ''scoreboard''. Mieux valait utiliser le peu de transistors dont elles disposaient pour des unités de calcul. De plus, DirectX 8 et 9 profitaient pas mal de la présence de ''co-issue''. Par contre, il fallait un compilateur performant pour en profiter, ce qui n'était pas vraiment le cas. Les compilateurs n'exploitaient pas beaucoup la ''co-issue'', ce qui fait que les fabricant de GPU ont préféré déléguer cette tâche à un ''scoreboard'' matériel. ===Les architectures VLIW pures, sans unité SIMD=== Un processeur VLIW contient un grand nombre d'unités de calcul. En théorie, il incorpore plusieurs unités de calcul scalaires séparés et n'a pas d'unité de calcul SIMD. Il y a cependant quelques exceptions, mais nous les verrons plus tard. Pour le moment, concentrons-nous sur les processeurs de shaders VLIW sans aucune unité de calcul SIMD. Un exemple est celui des anciennes cartes graphiques AMD, d'architecture TeraScale/VLIW-5, à savoir les Radeon HD 2000/3000/4000/5000/6000. L'architecture était une architecture VLIW, pas SIMD, d'où la distinction. Il n'y avait pas d'unité de calcul SIMD, mais plusieurs unités de calcul scalaires. Un point important est que les unités de calculs scalaires pouvaient faire des opérations différentes. Par exemple, la première pouvait faire une addition flottante, la seconde une addition entière, la troisième une soustraction, etc. Elles disposaient de six unités de calcul : cinq unités de calcul scalaires, et une unité de calcul dédiée aux branchements. Sur les 5 unités de calcul, une était une unité de calcul hybride scalaire/transcendentale. Nous allons donc faire la distinction entre unité de calcul spéciale et les 4 unités de calcul basiques. Toutes les unités de calculs pouvaient faire les opérations suivantes, sur des flottants et entiers sur 32 bits : comparaisons, additions, soustractions, opérations logiques, décalages, opérations bit à bit et instructions CMOV. Les unités de calcul basiques gèrent aussi les multiplications, opérations MAD et produits vectoriels/scalaires, mais seulement pour des opérandes flottantes. L'unité de calcul spéciale gérait des multiplications et division entières sur des opérandes 32 bits, ainsi que des instructions transcendantales entières/flottantes. Par la suite, avec l'architecture VLIW-4, l'unité de calcul transcendantale a été retirée. Mais les calculs transcendantaux n'ont pas disparus. En effet, il ne resta que 4 ALU flottantes, qui ont été augmentées pour gérer partiellement les opérations transcendantales. Tout se passait comme si l'ALU transcendantale avait été éclatée en morceaux répartis dans chaque ALU flottante/entière. Et c'est globalement ce qui s'est passé : les diverses tables matérielles utilisées pour les calculs transcendantaux ont été dispersés dans les ALU, afin de faire des calculs transcendantaux approchés. En combinant les résultats approchés, on pouvait calculer le résultat exact. ===Les hybrides SIMD/VLIW et les instructions à ''co-issue''=== La gestion des instructions en ''co-issue'' peut aussi utiliser les techniques des processeurs VLIW. Pour rappel, l'exemple typique d'instruction en ''co-issue'' regroupe une opération SIMD avec une opération scalaire, pour profiter de la présence d'une ALU scalaire séparée de l'ALU SIMD. Les cartes graphiques modernes gérent la ''co-issue'' aisni, avec la possibilité de ''co-issue'' une opération scalaire et une opération vectorielle. L'opération scalaire est souvent une opération entière, éventuellement flottante. Les processeurs de shaders qui supportent de telles instructions sont un hybride entre VLIW et SIMD. Sur les anciennes cartes graphiques disposant d'une unité SIMD, la ''co-issue'' fonctionnait différemment, car les unités de calcul entières n'étaient pas présentes. De plus, le faible budget en transistor faisait que l'on ajoutait pas d'unité flottante scalaire, ce qui ne servait pas à grand-chose. Par contre, l'unité de calcul transcendantale était systématiquement présente, car très utile. Aussi, une forme plus limitée de ''co-issue'' était possible : on pouvait exécuter une opération transcendantale en parallèle d'une instruction SIMD. Le cas le plus simple est le processeur de vertices de la Geforce 3, avec une unité SIMD et une unité transcendantale. Il n'y avait pas d'unité de calcul scalaire entière, ni même flottante. Un autre exemple est le processeur de ''vertex shader'' de la Geforce 6800, illustré ci-dessous. On voit que le processeur contient une unité d'accès mémoire/textures, avec deux unités de calcul. La première est une unité de calcul scalaire flottante, qui gère les opérations flottantes transcendantales. Elle travaille sur des opérandes de 32 bits. À côté, on trouve une unité de calcul SIMD, qui gère des vecteurs de 4 nombres flottants 32 bits. Elle permet de faire des additions, des multiplications, des opérations MAD, des produits vectoriels, et quelques autres opérations comme le calcul du maximum/minimum de deux nombres. Il n'y a aucune gestion d'instructions flottantes scalaires ou d'opérations entières, la carte graphique est trop ancienne pour cela. [[File:GeForce 6800 Vertex processor block.png|centre|vignette|upright=2.0|Processeur de shader (vertex shader) d'une GeForce 6800. On voit clairement que celui-ci contient, outre les traditionnelles unités de calcul et registres temporaires, un "cache" d'instructions, des registres d'entrée et de sortie, ainsi que des registres de constante.]] Le processeur de pixel shader de la même carte graphique était lui aussi un hybride entre VLIW et SIMD. Cependant, il lorgnait plus du côté VLIW que SIMD. Il pouvait faire soit une opération SIMD le vecteur, soit couper le vecteur en deux et effectuer deux opérations différentes sur chaque morceau. Par exemple, il pouvait faire une opération sur 3 pixels, et une opération scalaire sur le quatrième, ou deux opérations vectoriels chacune sur deux pixels. Le processeur travaille sur des blocs de 4 pixels, appelés des ''quads''. Chaque pixel est codé avec 4 flottants 32 bits, cela fait en tout 4 vecteurs de 4 flottants, avec ''co-issue'' à l'intérieur de chaque vecteur. Précisons que les registres temporaires du processeur mémorisent chacun un vecteur de 4 flottants, un pixel, par un ''quad''. Niveau unités de calcul, le tout était assez complexe. Il contenait tout d'abord une unité de texture, et plusieurs unités VLIW/SIMD. Elles sont appelées "unités SIMD" dans les schémas qui vont suivre, mais elles sont en réalité un mix entre unité SIMD véritable et unités scalaires du VLIW. La documentation NVIDIA elle-même parle d'unité vectorielle, mais le terme est quelque peu trompeur, car elles sont plus flexibles que de simples unités SIMD. Il y en a deux, la première envoyant son résultat à la seconde. La première est capable de faire des opérations de multiplications/MAD, mais elle peut aussi être utilisée pour la correction de perspective grâce à son support des opérations 1/x. Elle peut aussi normaliser des nombres flottants sur 16 bits. Il faut noter que la première unité SIMD/VLIW ne peut pas être utilisée si un accès mémoire/texture est en cours. La seconde unité SIMD/VLIW est capable de faire des opérations de MAD, et un produit vectoriel/scalaire DOT4. Le résultat de la seconde ALU est ensuite envoyé à une unité de branchement qui décide s'il faut ré-exécuter une autre passe d'instructions ou non. Il s'agit vraisemblablement d'une unité qui gère la prédication des résultats. Une fois le fragment/pixel final calculé, il est envoyé à une unité de calcul du brouillard, qui est une unité de calcul spécialisée travaillant sur des nombres entiers (en réalité, en virgule fixe, mais c'est pareil). [[File:Processeur de pixel shader de la Geforce 6800.png|centre|vignette|upright=2.0|Processeur de pixel shader de la Geforce 6800]] {{NavChapitre | book=Les cartes graphiques | prev=La répartition du travail sur les unités de shaders | prevText=La répartition du travail sur les unités de shaders | next=La mémoire unifiée et la mémoire vidéo dédiée | netxText=La mémoire unifiée et la mémoire vidéo dédiée }}{{autocat}} 5gwz4ih26rnqkmbbh9yzwk89bzloa7i Discussion Wikilivres:Le Bistro/2025 5 82063 744027 743745 2025-06-02T23:54:47Z MediaWiki message delivery 36013 /* Actualités techniques n° 2025-23 */ nouvelle section 744027 wikitext text/x-wiki == Actualités techniques n° 2025-03 == <section begin="technews-2025-W03"/><div class="plainlinks"> Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2025/03|D’autres traductions]] sont disponibles. '''En lumière cette semaine''' * Le système de connexion utilisateur unique (SUL) va être mis à jour durant les prochains mois. Il permet aux utilisateurs et utilisatrices d’être connectés sur tous les sites en même temps après avoir renseigné leurs identifiants sur un site Wikimedia. La mise à jour est nécessaire car les navigateurs restreignent de plus en plus les témoins de connexion inter-domaines. Pour s’adapter à ces restrictions, les pages de connexion et de création de compte seront déplacées vers un domaine central, mais cela apparaitra toujours comme si vous étiez sur le wiki d’origine. Le code mis à jour sera activé cette semaine pour les utilisations sur les wikis de test. Ce changement devrait être déployé pour tous durant février et mars. Consultez [[mw:Special:MyLanguage/MediaWiki Platform Team/SUL3#Deployment|la page du projet SUL3]] pour plus d’informations et un calendrier. '''Actualités pour la contribution''' * Sur les wikis ayant [[mw:Special:MyLanguage/Extension:PageAssessments|PageAssessments]] (évaluation des pages) installée, vous pouvez désormais [[mw:Special:MyLanguage/Extension:PageAssessments#Search|filtrer les résultats de recherche]] aux pages dans un projet donné à l’aide du mot-clé <code dir=ltr>inproject:</code>. (Ces wikis : {{int:project-localized-name-arwiki/fr}}{{int:comma-separator/fr}}{{int:project-localized-name-enwiki/fr}}{{int:comma-separator/fr}}{{int:project-localized-name-enwikivoyage/fr}}{{int:comma-separator/fr}}{{int:project-localized-name-frwiki/fr}}{{int:comma-separator/fr}}{{int:project-localized-name-huwiki/fr}}{{int:comma-separator/fr}}{{int:project-localized-name-newiki/fr}}{{int:comma-separator/fr}}{{int:project-localized-name-trwiki/fr}}{{int:comma-separator/fr}}{{int:project-localized-name-zhwiki/fr}}.) [https://phabricator.wikimedia.org/T378868] * Un nouveau wiki a été créé : une Wikipédia en [[d:Q34129|tigré]] ([[w:tig:|<code>w:tig:</code>]]) [https://phabricator.wikimedia.org/T381377] * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:35|la tâche soumise|les {{formatnum:35}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:35||s}} la semaine dernière]]. Par exemple, il y avait un beugue de mise à jour du compteur de modifications de quelqu’un effectuant une annulation d’une autre modification : cela est maintenant corrigé. [https://phabricator.wikimedia.org/T382592] '''Actualités pour la contribution technique''' * [[File:Octicons-tools.svg|12px|link=|class=skin-invert|Sujet technique]] Les utilisateurs et utilisatrices de l’API REST de Wikimedia (par exemple pour des robots ou des outils) peuvent être impactés par des mises à jour en cours. À partir de la semaine du 13 janvier, nous commencerons à rediriger [[phab:T374683|certains points terminaux de contenu de page]] depuis RESTbase vers les nouveaux points terminaux de l’API REST de MediaWiki pour tous les projets wiki. Ce changement était disponible sur testwiki, et ne devrait pas affecter les fonctionnalités existantes, mais les utilisateurs actifs des points terminaux concernés peuvent signaler directement à l’[[phab:project/view/6931/|équipe des interfaces de MediaWiki]] tout problème qui arriverait. * Les personnes maintenant des outils sur Toolforge peuvent désormais partager leurs retour sur Toolforge UI, un projet visant à fournir une plateforme web pour la création et la gestion d’outils Toolforge depuis une interface graphique, en plus des processus existant par ligne de commande. Ce projet vise à simplifier les tâches des mainteneurs et mainteneuses actifs, ainsi qu’à rendre l’inscription et les procédures de déploiement plus accessibles aux nouveaux et nouvelles créatrices d’outils. Le projet en est encore à ses balbutiements et l’équipe des services en infonuage recueille des retours de la communauté Toolforge pour aiderà concevoir la solution correspondant à leurs besoins. [[wikitech:Wikimedia Cloud Services team/EnhancementProposals/Toolforge UI|En savoir plus et donner son avis sur Toolforge UI]]. * [[File:Octicons-tools.svg|12px|link=|class=skin-invert|Sujet technique]] <span class="mw-translate-fuzzy">Pour le développement d’outil et bibliothèque qui utilisent le système OAuth : le point terminal d’identité utilisé pour [[mw:Special:MyLanguage/OAuth/For Developers#Identifying the user|OAuth 1]] et [[mw:Special:MyLanguage/OAuth/For Developers#Identifying the user 2|OAuth 2]] retournait un objet JSON avec un entier dans le sous-champ, ce qui était incorrect (le champ doit toujours être une chaine de caractère); Cela a été corrigé ; le correctif sera déployé sur les wikis Wikimedia la semaine du 13 janvier.</span> [https://phabricator.wikimedia.org/T382139] * De nombreux wikis utilisent actuellement le [[:mw:Parsoid/Parser Unification/Cite CSS|CSS de Cite]] pour insérer des marqueurs de note de bas de page personnalisés dans la sortie de Parsoid. À partir du 20 janvier, ces règles seront désactivées, mais les développeurs vous demandent de ''ne pas'' nettoyer votre <bdi lang="en" dir="ltr">[[MediaWiki:Common.css]]</bdi> avant le 20 février pour éviter des problèmes pendant la migration. Vos wikis rencontreront peut-être des petits changements dans les marqueurs de notes de bas page dans l’éditeur visuel ou en utilisant le mode de lecture expérimental Parsoid, mais s’il y a des changements, ils devraient garder le rendu cohérent avec la sortie de l’analyseur classique. [https://phabricator.wikimedia.org/T370027] '''Rencontres et évènements''' * Les prochaines réunions de la série des [[c:Special:MyLanguage/Commons:WMF support for Commons/Commons community calls|Discussions communautaires entre Wikimedia Foundation et la communauté de Wikimedia Commons]] aura lieu le [[m:Special:MyLanguage/Event:Commons community discussion - 15 January 2025 08:00 UTC|15 janvier à 8 h UTC]] et [[m:Special:MyLanguage/Event:Commons community discussion - 15 January 2025 16:00 UTC|à 16 h UTC]]. Le sujet de cette conférence porte sur la définition des priorités d’investissement en outils pour Commons. Les contributeurs et contributrices de tous les wikis sont les bienvenus pour participer, notamment celles et ceux qui maintiennent des outils pour Commons. '''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2025/03|Traduire]]&nbsp;• [[m:Tech|Obtenir de l’aide]]&nbsp;• [[m:Talk:Tech/News|Donner son avis]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].'' </div><section end="technews-2025-W03"/> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 14 janvier 2025 à 02:42 (CET) <!-- Message envoyé par User:Quiddity (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=28048614 --> == Launching! Join Us for Wiki Loves Ramadan 2025! == Dear All, We’re happy to announce the launch of [[m:Wiki Loves Ramadan 2025|Wiki Loves Ramadan 2025]], an annual international campaign dedicated to celebrating and preserving Islamic cultures and history through the power of Wikipedia. As an active contributor to the Local Wikipedia, you are specially invited to participate in the launch. This year’s campaign will be launched for you to join us write, edit, and improve articles that showcase the richness and diversity of Islamic traditions, history, and culture. * Topic: [[m:Event:Wiki Loves Ramadan 2025 Campaign Launch|Wiki Loves Ramadan 2025 Campaign Launch]] * When: Jan 19, 2025 * Time: 16:00 Universal Time UTC and runs throughout Ramadan (starting February 25, 2025). * Join Zoom Meeting: https://us02web.zoom.us/j/88420056597?pwd=NdrpqIhrwAVPeWB8FNb258n7qngqqo.1 * Zoom meeting hosted by [[m:Wikimedia Bangladesh|Wikimedia Bangladesh]] To get started, visit the [[m:Wiki Loves Ramadan 2025|campaign page]] for details, resources, and guidelines: Wiki Loves Ramadan 2025. Add [[m:Wiki Loves Ramadan 2025/Participant|your community here]], and organized Wiki Loves Ramadan 2025 in your local language. Whether you’re a first-time editor or an experienced Wikipedian, your contributions matter. Together, we can ensure Islamic cultures and traditions are well-represented and accessible to all. Feel free to invite your community and friends too. Kindly reach out if you have any questions or need support as you prepare to participate. Let’s make Wiki Loves Ramadan 2025 a success! For the [[m:Wiki Loves Ramadan 2025/Team|International Team]] 16 janvier 2025 à 13:08 (CET) <!-- Message envoyé par User:ZI Jony@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=27568454 --> == Actualités techniques n° 2025-04 == <section begin="technews-2025-W04"/><div class="plainlinks"> Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2025/04|D’autres traductions]] sont disponibles. '''Actualités pour la contribution''' * <span lang="en" dir="ltr" class="mw-content-ltr">Administrators can mass-delete multiple pages created by a user or IP address using [[mw:Special:MyLanguage/Extension:Nuke|Extension:Nuke]]. It previously only allowed deletion of pages created in the last 30 days. It can now delete pages from the last 90 days, provided it is targeting a specific user or IP address.</span> [https://phabricator.wikimedia.org/T380846] * <span lang="en" dir="ltr" class="mw-content-ltr">On [[phab:P72148|wikis that use]] the [[mw:Special:MyLanguage/Help:Patrolled edits|Patrolled edits]] feature, when the rollback feature is used to revert an unpatrolled page revision, that revision will now be marked as "manually patrolled" instead of "autopatrolled", which is more accurate. Some editors that use [[mw:Special:MyLanguage/Help:New filters for edit review/Filtering|filters]] on Recent Changes may need to update their filter settings.</span> [https://phabricator.wikimedia.org/T302140] * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:31|la tâche soumise|les {{formatnum:31}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:31||s}} la semaine dernière]]. <span lang="en" dir="ltr" class="mw-content-ltr">For example, the Visual Editor's "Insert link" feature did not always suggest existing pages properly when an editor started typing, which has now been [[phab:T383497|fixed]].</span> '''Actualités pour la contribution technique''' * <span lang="en" dir="ltr" class="mw-content-ltr">The Structured Discussion extension (also known as Flow) is being progressively removed from the wikis. This extension is unmaintained and causes issues. It will be replaced by [[mw:Special:MyLanguage/Help:DiscussionTools|DiscussionTools]], which is used on any regular talk page. [[mw:Special:MyLanguage/Structured Discussions/Deprecation#Deprecation timeline|The last group of wikis]] ({{int:project-localized-name-cawikiquote/en}}{{int:comma-separator/en}}{{int:project-localized-name-fiwikimedia/en}}{{int:comma-separator/en}}{{int:project-localized-name-gomwiki/en}}{{int:comma-separator/en}}{{int:project-localized-name-kabwiki/en}}{{int:comma-separator/en}}{{int:project-localized-name-ptwikibooks/en}}{{int:comma-separator/en}}{{int:project-localized-name-sewikimedia/en}}) will soon be contacted. If you have questions about this process, please ping [[m:User:Trizek (WMF)|Trizek (WMF)]] at your wiki.</span> [https://phabricator.wikimedia.org/T380912] * <span lang="en" dir="ltr" class="mw-content-ltr">The latest quarterly [[mw:Technical_Community_Newsletter/2025/January|Technical Community Newsletter]] is now available. This edition includes: updates about services from the Data Platform Engineering teams, information about Codex from the Design System team, and more.</span> '''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2025/04|Traduire]]&nbsp;• [[m:Tech|Obtenir de l’aide]]&nbsp;• [[m:Talk:Tech/News|Donner son avis]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].'' </div><section end="technews-2025-W04"/> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 21 janvier 2025 à 02:36 (CET) <!-- Message envoyé par User:Quiddity (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=28129769 --> == Universal Code of Conduct annual review: provide your comments on the UCoC and Enforcement Guidelines == <div lang="en" dir="ltr" class="mw-content-ltr"> My apologies for writing in English. {{Int:Please-translate}}. I am writing to you to let you know the annual review period for the Universal Code of Conduct and Enforcement Guidelines is open now. You can make suggestions for changes through 3 February 2025. This is the first step of several to be taken for the annual review. [[m:Special:MyLanguage/Universal_Code_of_Conduct/Annual_review|Read more information and find a conversation to join on the UCoC page on Meta]]. The [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee|Universal Code of Conduct Coordinating Committee]] (U4C) is a global group dedicated to providing an equitable and consistent implementation of the UCoC. This annual review was planned and implemented by the U4C. For more information and the responsibilities of the U4C, [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Charter|you may review the U4C Charter]]. Please share this information with other members in your community wherever else might be appropriate. -- In cooperation with the U4C, [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) 24 janvier 2025 à 02:10 (CET) </div> <!-- Message envoyé par User:Keegan (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=27746256 --> == Actualités techniques n° 2025-05 == <section begin="technews-2025-W05"/><div class="plainlinks"> Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2025/05|D’autres traductions]] sont disponibles. '''En lumière cette semaine''' * <span lang="en" dir="ltr" class="mw-content-ltr">Patrollers and admins - what information or context about edits or users could help you to make patroller or admin decisions more quickly or easily? The Wikimedia Foundation wants to hear from you to help guide its upcoming annual plan. Please consider sharing your thoughts on this and [[m:Special:MyLanguage/Wikimedia Foundation Annual Plan/2025-2026/Product & Technology OKRs|13 other questions]] to shape the technical direction for next year.</span> '''Actualités pour la contribution''' * <span lang="en" dir="ltr" class="mw-content-ltr">iOS Wikipedia App users worldwide can now access a [[mw:Special:MyLanguage/Wikimedia Apps/Team/iOS/Personalized Wikipedia Year in Review/How your data is used|personalized Year in Review]] feature, which provides insights based on their reading and editing history on Wikipedia. This project is part of a broader effort to help welcome new readers as they discover and interact with encyclopedic content.</span> * [[File:Octicons-gift.svg|12px|link=|class=skin-invert|Concerne un souhait]] <span lang="en" dir="ltr" class="mw-content-ltr">Edit patrollers now have a new feature available that can highlight potentially problematic new pages. When a page is created with the same title as a page which was previously deleted, a tag ('Recreated') will now be added, which users can filter for in [[{{#special:RecentChanges}}]] and [[{{#special:NewPages}}]].</span> [https://phabricator.wikimedia.org/T56145] * <span lang="en" dir="ltr" class="mw-content-ltr">Later this week, there will be a new warning for editors if they attempt to create a redirect that links to another redirect (a [[mw:Special:MyLanguage/Help:Redirects#Double redirects|double redirect]]). The feature will recommend that they link directly to the second redirect's target page. Thanks to the user SomeRandomDeveloper for this improvement.</span> [https://phabricator.wikimedia.org/T326056] * [[File:Octicons-tools.svg|12px|link=|class=skin-invert|Sujet technique]] <span lang="en" dir="ltr" class="mw-content-ltr">Wikimedia wikis allow [[w:en:WebAuthn|WebAuthn]]-based second factor checks (such as hardware tokens) during login, but the feature is [[m:Community Wishlist Survey 2023/Miscellaneous/Fix security key (WebAuthn) support|fragile]] and has very few users. The MediaWiki Platform team is temporarily disabling adding new WebAuthn keys, to avoid interfering with the rollout of [[mw:MediaWiki Platform Team/SUL3|SUL3]] (single user login version 3). Existing keys are unaffected.</span> [https://phabricator.wikimedia.org/T378402] * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:30|la tâche soumise|les {{formatnum:30}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:30||s}} la semaine dernière]]. '''Actualités pour la contribution technique''' * <span lang="en" dir="ltr" class="mw-content-ltr">For developers that use the [[wikitech:Data Platform/Data Lake/Edits/MediaWiki history dumps|MediaWiki History dumps]]: The Data Platform Engineering team has added a couple of new fields to these dumps, to support the [[mw:Special:MyLanguage/Trust and Safety Product/Temporary Accounts|Temporary Accounts]] initiative. If you maintain software that reads those dumps, please review your code and the updated documentation, since the order of the fields in the row will change. There will also be one field rename: in the <bdi lang="zxx" dir="ltr"><code>mediawiki_user_history</code></bdi> dump, the <bdi lang="zxx" dir="ltr"><code>anonymous</code></bdi> field will be renamed to <bdi lang="zxx" dir="ltr"><code>is_anonymous</code></bdi>. The changes will take effect with the next release of the dumps in February.</span> [https://lists.wikimedia.org/hyperkitty/list/wikitech-l@lists.wikimedia.org/thread/LKMFDS62TXGDN6L56F4ABXYLN7CSCQDI/] '''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2025/05|Traduire]]&nbsp;• [[m:Tech|Obtenir de l’aide]]&nbsp;• [[m:Talk:Tech/News|Donner son avis]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].'' </div><section end="technews-2025-W05"/> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 27 janvier 2025 à 23:14 (CET) <!-- Message envoyé par User:Quiddity (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=28149374 --> == Reminder: first part of the annual UCoC review closes soon == <div lang="en" dir="ltr" class="mw-content-ltr"> My apologies for writing in English. {{Int:Please-translate}}. This is a reminder that the first phase of the annual review period for the Universal Code of Conduct and Enforcement Guidelines will be closing soon. You can make suggestions for changes through [[d:Q614092|the end of day]], 3 February 2025. This is the first step of several to be taken for the annual review. [[m:Special:MyLanguage/Universal_Code_of_Conduct/Annual_review|Read more information and find a conversation to join on the UCoC page on Meta]]. After review of the feedback, proposals for updated text will be published on Meta in March for another round of community review. Please share this information with other members in your community wherever else might be appropriate. -- In cooperation with the U4C, [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) 3 février 2025 à 01:48 (CET) </div> <!-- Message envoyé par User:Keegan (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=28198931 --> == <span lang="en" dir="ltr">Tech News: 2025-06</span> == <div lang="en" dir="ltr"> <section begin="technews-2025-W06"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2025/06|Translations]] are available. '''Updates for editors''' * Editors who use the "Special characters" editing-toolbar menu can now see the 32 special characters you have used most recently, across editing sessions on that wiki. This change should help make it easier to find the characters you use most often. The feature is in both the 2010 wikitext editor and VisualEditor. [https://phabricator.wikimedia.org/T110722] * Editors using the 2010 wikitext editor can now create sublists with correct indentation by selecting the line(s) you want to indent and then clicking the toolbar buttons.[https://phabricator.wikimedia.org/T380438] You can now also insert <code><nowiki><code></nowiki></code> tags using a new toolbar button.[https://phabricator.wikimedia.org/T383010] Thanks to user stjn for these improvements. * Help is needed to ensure the [[mw:Special:MyLanguage/Citoid/Enabling Citoid on your wiki|citation generator]] works properly on each wiki. ** (1) Administrators should update the local versions of the page <code dir=ltr>MediaWiki:Citoid-template-type-map.json</code> to include entries for <code dir=ltr>preprint</code>, <code dir=ltr>standard</code>, and <code dir=ltr>dataset</code>; Here are example diffs to replicate [https://en.wikipedia.org/w/index.php?title=MediaWiki%3ACitoid-template-type-map.json&diff=1189164774&oldid=1165783565 for 'preprint'] and [https://en.wikipedia.org/w/index.php?title=MediaWiki%3ACitoid-template-type-map.json&diff=1270832208&oldid=1270828390 for 'standard' and 'dataset']. ** (2.1) If the citoid map in the citation template used for these types of references is missing, [[mediawikiwiki:Citoid/Enabling Citoid on your wiki#Step 2.a: Create a 'citoid' maps value for each citation template|one will need to be added]]. (2.2) If the citoid map does exist, the TemplateData will need to be updated to include new field names. Here are example updates [https://en.wikipedia.org/w/index.php?title=Template%3ACitation%2Fdoc&diff=1270829051&oldid=1262470053 for 'preprint'] and [https://en.wikipedia.org/w/index.php?title=Template%3ACitation%2Fdoc&diff=1270831369&oldid=1270829480 for 'standard' and 'dataset']. The new fields that may need to be supported are <code dir=ltr>archiveID</code>, <code dir=ltr>identifier</code>, <code dir=ltr>repository</code>, <code dir=ltr>organization</code>, <code dir=ltr>repositoryLocation</code>, <code dir=ltr>committee</code>, and <code dir=ltr>versionNumber</code>. [https://phabricator.wikimedia.org/T383666] * One new wiki has been created: a {{int:project-localized-name-group-wikipedia/en}} in [[d:Q15637215|Central Kanuri]] ([[w:knc:|<code>w:knc:</code>]]) [https://phabricator.wikimedia.org/T385181] * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:27}} community-submitted {{PLURAL:27|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, the [[mediawikiwiki:Special:MyLanguage/Help:Extension:Wikisource/Wikimedia OCR|OCR (optical character recognition) tool]] used for Wikisource now supports a new language, Church Slavonic. [https://phabricator.wikimedia.org/T384782] '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2025/06|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2025-W06"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 4 février 2025 à 01:08 (CET) <!-- Message envoyé par User:Quiddity (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=28203495 --> == <span lang="en" dir="ltr">Tech News: 2025-07</span> == <div lang="en" dir="ltr"> <section begin="technews-2025-W07"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2025/07|Translations]] are available. '''Weekly highlight''' * The Product and Technology Advisory Council (PTAC) has published [[m:Special:MyLanguage/Product and Technology Advisory Council/February 2025 draft PTAC recommendation for feedback|a draft of their recommendations]] for the Wikimedia Foundation's Product and Technology department. They have recommended focusing on [[m:Special:MyLanguage/Product and Technology Advisory Council/February 2025 draft PTAC recommendation for feedback/Mobile experiences|mobile experiences]], particularly contributions. They request community [[m:Talk:Product and Technology Advisory Council/February 2025 draft PTAC recommendation for feedback|feedback at the talk page]] by 21 February. '''Updates for editors''' * The "Special pages" portlet link will be moved from the "Toolbox" into the "Navigation" section of the main menu's sidebar by default. This change is because the Toolbox is intended for tools relating to the current page, not tools relating to the site, so the link will be more logically and consistently located. To modify this behavior and update CSS styling, administrators can follow the instructions at [[phab:T385346|T385346]]. [https://phabricator.wikimedia.org/T333211] * As part of this year's work around improving the ways readers discover content on the wikis, the Web team will be running an experiment with a small number of readers that displays some suggestions for related or interesting articles within the search bar. Please check out [[mw:Special:MyLanguage/Reading/Web/Content Discovery Experiments#Experiment 1: Display article recommendations in more prominent locations, search|the project page]] for more information. * [[File:Octicons-tools.svg|12px|link=|class=skin-invert|Advanced item]] Template editors who use TemplateStyles can now customize output for users with specific accessibility needs by using accessibility related media queries (<code dir=ltr>[https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion prefers-reduced-motion]</code>, <code dir=ltr>[https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-transparency prefers-reduced-transparency]</code>, <code dir=ltr>[https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-contrast prefers-contrast]</code>, and <code dir=ltr>[https://developer.mozilla.org/en-US/docs/Web/CSS/@media/forced-colors forced-colors]</code>). Thanks to user Bawolff for these improvements. [https://phabricator.wikimedia.org/T384175] * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:22}} community-submitted {{PLURAL:22|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, the global blocks log will now be shown directly on the {{#special:CentralAuth}} page, similarly to global locks, to simplify the workflows for stewards. [https://phabricator.wikimedia.org/T377024] '''Updates for technical contributors''' * Wikidata [[d:Special:MyLanguage/Help:Default values for labels and aliases|now supports a special language as a "default for all languages"]] for labels and aliases. This is to avoid excessive duplication of the same information across many languages. If your Wikidata queries use labels, you may need to update them as some existing labels are getting removed. [https://phabricator.wikimedia.org/T312511] * The function <code dir="ltr">getDescription</code> was invoked on every Wiki page read and accounts for ~2.5% of a page's total load time. The calculated value will now be cached, reducing load on Wikimedia servers. [https://phabricator.wikimedia.org/T383660] * As part of the RESTBase deprecation [[mw:RESTBase/deprecation|effort]], the <code dir="ltr">/page/related</code> endpoint has been blocked as of February 6, 2025, and will be removed soon. This timeline was chosen to align with the deprecation schedules for older Android and iOS versions. The stable alternative is the "<code dir="ltr">morelike</code>" action API in MediaWiki, and [[gerrit:c/mediawiki/services/mobileapps/+/982154/13/pagelib/src/transform/FooterReadMore.js|a migration example]] is available. The MediaWiki Interfaces team [[phab:T376297|can be contacted]] for any questions. [https://lists.wikimedia.org/hyperkitty/list/wikitech-l@lists.wikimedia.org/thread/GFC2IJO7L4BWO3YTM7C5HF4MCCBE2RJ2/] '''In depth''' * The latest quarterly [[mw:Special:MyLanguage/Wikimedia Language and Product Localization/Newsletter/2025/January|Language and Internationalization newsletter]] is available. It includes: Updates about the "Contribute" menu; details on some of the newest language editions of Wikipedia; details on new languages supported by the MediaWiki interface; updates on the Community-defined lists feature; and more. * The latest [[mw:Extension:Chart/Project/Updates#January 2025: Better visibility into charts and tabular data usage|Chart Project newsletter]] is available. It includes updates on the progress towards bringing better visibility into global charts usage and support for categorizing pages in the Data namespace on Commons. '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2025/07|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2025-W07"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 11 février 2025 à 01:11 (CET) <!-- Message envoyé par User:Quiddity (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=28231022 --> == Actualités techniques n° 2025-08 == <section begin="technews-2025-W08"/><div class="plainlinks"> Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2025/08|D’autres traductions]] sont disponibles. '''En lumière cette semaine''' * Les communautés utilisant les outils de croissance peuvent désormais mettre en avant un évènement pour les nouveaux contributeurs sur la <code>{{#special:Homepage}}</code>. Cette fonctionnalité aidera les nouveaux venus à être informés des activités d'édition auxquels ils peuvent participer. Les administrateurs peuvent ajouter un nouvel évènement à mettre en avant sur <code>{{#special:CommunityConfiguration}}</code>. Pour en apprendre davantage sur cette nouvelle fonctionnalité, vous pouvez lire [[diffblog:2025/02/12/community-updates-module-connecting-newcomers-to-your-initiatives/|l'annonce sur Diff]], la [[mw:Special:MyLanguage/Help:Growth/Tools/Community updates module|documentation]] ou [[mw:Talk:Growth|contacter l'équipe Croissance]]. '''Actualités pour la contribution''' [[File:Page Frame Features on desktop.png|thumb|Mise en évidence des améliorations aux pages de discussion]] * À partir de la semaine prochaine, les pages de discussions des wikis suivants recevront [[diffblog:2024/05/02/making-talk-pages-better-for-everyone/|une nouvelle présentation]] : {{int:project-localized-name-eswiki/fr}}{{int:comma-separator/fr}}{{int:project-localized-name-frwiki/fr}}{{int:comma-separator/fr}}{{int:project-localized-name-itwiki/fr}}{{int:comma-separator/fr}}{{int:project-localized-name-jawiki/fr}}. Ce changement a été largement testé en tant que fonctionnalité beta et il s'agit de la dernière étape des [[mw:Special:MyLanguage/Talk pages project/Feature summary|améliorations aux pages de discussion]]. [https://phabricator.wikimedia.org/T379102] * Vous pouvez désormais visualiser une page de redirection directement depuis ses pages d'action, comme la page d'historique. Auparavant, vous étiez automatiquement redirigé vers la page cible et deviez manuellement revenir à la page de redirection. Ce changement devrait aider les rédacteurs travaillant avec les redirections. Merci à stjn pour cette amélioration. [https://phabricator.wikimedia.org/T5324] * Quand une référence est utilisée de nombreuses fois, les wikis affichent actuellement des nombres comme 1.23 ou des marqueurs avec des lettres comme a, b, c dans la liste de références. Avant, quand le nombre de références était trop important et que toutes les lettres avaient été utilisées, un [[MediaWiki:Cite error references no backlink label|message d'erreur]] était affiché. Dans le cadre des travaux pour la [[phab:T383036|modernisation de la personnalisation des références]], ces erreurs ne seront plus affichées et des marqueurs numériques comme 1.27 seront utilisés par défaut après épuisement des marqueurs alphabétiques. * Les entrées de journal pour chaque changement aux groupes utilisateur d'un éditeur ont été clarifiés pour indiquer exactement ce qui a été modifié. Elles contenaient auparavant les deux listes des groupes avant et après le changement. Les traducteurs sont invités à [[phab:T369466|aider à traduire les messages système associés]]. Merci à Msz2001 pour ces améliorations. * Un nouveau filtre a été ajouté à [[{{#special:Nuke}}]] — outil permettant aux administrateurs de supprimer en masse des pages — pour permettre aux utilisateurs de filtrer les pages en fonction de leur taille en octets. Cela permet par exemple de supprimer uniquement des pages inférieures à une certaine taille. [https://phabricator.wikimedia.org/T378488] * Les non-administrateurs peuvent maintenant voir quelles pages peuvent être supprimées à l'aide de [[{{#special:Nuke}}]]. Merci à MolecularPilot pour cette amélioration et les précédentes. [https://phabricator.wikimedia.org/T376378] * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:25|la tâche soumise|les {{formatnum:25}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:25||s}} la semaine dernière]]. Par exemple, un bug a été corrigé dans la configuration du format de fichier vidéo AV1, ce qui permet à ces fichiers d'être lus à nouveau. [https://phabricator.wikimedia.org/T382193] '''Actualités pour la contribution technique''' * Parsoid Read Views sera déployé sur la plupart des Wiktionnaires dans les prochaines semaines, à la suite de la transition avec succès des Wikivoyage à Parsoid l'année dernière. Pour davantage d'informations, voir la page du projet [[mw:Special:MyLanguage/Parsoid/Parser Unification|Parsoid/Parser Unification]]. [https://phabricator.wikimedia.org/T385923][https://phabricator.wikimedia.org/T371640] * Les développeurs d'outils sur wiki sont informés que <code dir=ltr>mw.Uri</code> est obsolète. Les outils nécessitant <code dir=ltr>mw.Uri</code> doivent déclarer explicitement <code dir=ltr>mediawiki.Uri</code> comme une dépendance de ResourceLoader, et devraient migrer vers l'API <code dir=ltr>URL</code> native du navigateur prochainement. [https://phabricator.wikimedia.org/T384515] '''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2025/08|Traduire]]&nbsp;• [[m:Tech|Obtenir de l’aide]]&nbsp;• [[m:Talk:Tech/News|Donner son avis]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].'' </div><section end="technews-2025-W08"/> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 17 février 2025 à 22:16 (CET) <!-- Message envoyé par User:Quiddity (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=28275610 --> == <span lang="en" dir="ltr"> Upcoming Language Community Meeting (Feb 28th, 14:00 UTC) and Newsletter</span> == <div lang="en" dir="ltr"> <section begin="message"/> Hello everyone! [[File:WP20Symbols WIKI INCUBATOR.svg|right|frameless|150x150px|alt=An image symbolising multiple languages]] We’re excited to announce that the next '''Language Community Meeting''' is happening soon, '''February 28th at 14:00 UTC'''! If you’d like to join, simply sign up on the '''[[mw:Wikimedia_Language_and_Product_Localization/Community_meetings#28_February_2025|wiki page]]'''. This is a participant-driven meeting where we share updates on language-related projects, discuss technical challenges in language wikis, and collaborate on solutions. In our last meeting, we covered topics like developing language keyboards, creating the Moore Wikipedia, and updates from the language support track at Wiki Indaba. '''Got a topic to share?''' Whether it’s a technical update from your project, a challenge you need help with, or a request for interpretation support, we’d love to hear from you! Feel free to '''reply to this message''' or add agenda items to the document '''[[etherpad:p/language-community-meeting-feb-2025|here]]'''. Also, we wanted to highlight that the sixth edition of the Language & Internationalization newsletter (January 2025) is available here: [[:mw:Special:MyLanguage/Wikimedia Language and Product Localization/Newsletter/2025/January|Wikimedia Language and Product Localization/Newsletter/2025/January]]. This newsletter provides updates from the October–December 2024 quarter on new feature development, improvements in various language-related technical projects and support efforts, details about community meetings, and ideas for contributing to projects. To stay updated, you can subscribe to the newsletter on its wiki page: [[:mw:Wikimedia Language and Product Localization/Newsletter|Wikimedia Language and Product Localization/Newsletter]]. We look forward to your ideas and participation at the language community meeting, see you there! <section end="message"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 22 février 2025 à 09:28 (CET) <!-- Message envoyé par User:SSethi (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=28217779 --> == Actualités techniques n° 2025-09 == <section begin="technews-2025-W09"/><div class="plainlinks"> Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2025/09|D’autres traductions]] sont disponibles. '''Actualités pour la contribution''' * Les administrateurs peuvent désormais personnaliser la manière dont les catégories de [[m:Special:MyLanguage/User language|Babel]] sont créées en utilisant [[{{#special:CommunityConfiguration/Babel}}]]. Ils peuvent renommer les catégories de langues, choisir si elles doivent être créées automatiquement et ajuster d'autres paramètres. [https://phabricator.wikimedia.org/T374348] * Le portail <bdi lang="en" dir="ltr">[https://www.wikimedia.org/ wikimedia.org]</bdi> a été mis à jour pour moderniser et améliorer l'accessibilité de nos pages de portail. Il dispose désormais d'un meilleur support pour les mises en page mobiles, de meilleures formulations et liens et d'un support linguistique amélioré. De plus, tous les portails du projet Wikimedia, comme <bdi lang="en" dir="ltr">[https://wikibooks.org wikibooks.org]</bdi>, prennent maintenant en charge le mode sombre lorsqu'un lecteur utilise ce paramètre système. [https://phabricator.wikimedia.org/T373204][https://phabricator.wikimedia.org/T368221][https://meta.wikimedia.org/wiki/Project_portals] * Un nouveau wiki a été créé : un {{int:project-localized-name-group-wiktionary/fr}} en [[d:Q33965|Santali]] ([[wikt:sat:|<code>wikt:sat:</code>]]) [https://phabricator.wikimedia.org/T386619] * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:30|la tâche soumise|les {{formatnum:30}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:30||s}} la semaine dernière]]. Par exemple, un bogue qui empêchait de cliquer sur les résultats de recherche de l'interface web sur certaines configurations mobiles avec Firefox a été corrigé. [https://phabricator.wikimedia.org/T381289] '''Rencontres et évènements''' * La prochaine rencontre de la communauté linguistique aura lieu le 28 février à [https://zonestamp.toolforge.org/1740751200 14:00 UTC]. La rencontre de cette semaine couvrira : les points importants et mises-à-jour techniques pour les langues samis, les contributions à translatewiki.net de la part de la communauté Bahasa Lampung en Indonésie et une FAQ technique. Si vous souhaitez participer, inscrivez-vous sur la [[mw:Wikimedia Language and Product Localization/Community meetings#28 February 2025|page wiki]]. '''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2025/09|Traduire]]&nbsp;• [[m:Tech|Obtenir de l’aide]]&nbsp;• [[m:Talk:Tech/News|Donner son avis]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].'' </div><section end="technews-2025-W09"/> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 25 février 2025 à 01:41 (CET) <!-- Message envoyé par User:Quiddity (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=28296129 --> == Actualités techniques n° 2025-10 == <section begin="technews-2025-W10"/><div class="plainlinks"> Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2025/10|D’autres traductions]] sont disponibles. '''Actualités pour la contribution''' * Les utilisateurs et utilisatrices connectés utilisant l’affichage mobile peuvent désormais modifier une page complète. Le lien « {{int:Minerva-page-actions-editfull}} » est accessible dans le menu « {{int:minerva-page-actions-overflow}} » de la barre d’outils. Ce lien était auparavant disponible uniquement lorsque le [[mw:Special:MyLanguage/Reading/Web/Advanced mobile contributions|mode avancé]] était activé. [https://phabricator.wikimedia.org/T387180] * Les admins d’interface peuvent désormais retirer les utilisations de la classe CSS « <code dir="ltr">mw-ref</code> » de leur <bdi lang="en" dir="ltr">[[MediaWiki:Common.css]]</bdi> local. Cette classe de l’extension <span lang="en">Cite</span> est obsolète. La liste des wikis l’utilisant peut être trouvée par [https://global-search.toolforge.org/?q=mw-ref%5B%5E-a-z%5D&regex=1&namespaces=8&title=.*css cette recherche globale] et dans [https://ace.wikipedia.org/w/index.php?title=MediaWiki:Common.css&oldid=145662#L-139--L-144 cet exemple]. D’autres informations sur les manières d’aider sont données sur la [[mw:Parsoid/Parser Unification/Cite CSS|page du projet de migration du CSS]]. Les appels de note (<code dir="ltr">[1]</code>) sont désormais rendus par [[mw:Special:MyLanguage/Parsoid|Parsoid]] ; le CSS obsolète n’est plus nécessaire. Le CSS pour les rétroliens « <code dir="ltr">mw:referencedBy</code> » doit rester en place pour le moment. Ce nettoyage ne devrait pas avoir d’effet visible pour les lecteurs et lectrices. Merci d’aider à retirer ce code avant le 30 mars, après quoi l’équipe de développement le fera pour vous. * Lorsque les contributeurs ajoutent un fichier (par exemple <code><nowiki>[[File:MediaWiki.png]]</nowiki></code>) sur une page protégée par une protection en cascade, le logiciel ne restreindra plus les modifications à la page de description du fichier, mais uniquement aux nouveaux téléchargements de fichiers. [https://phabricator.wikimedia.org/T24521] A l’inverse, la transclusion d’une page de description de fichier (par exemple <code><nowiki>{{:File:MediaWiki.png}}</nowiki></code>) dans une page protégée en cascade provoquera désormais une restriction des modifications à la page.[https://phabricator.wikimedia.org/T62109] * Remettre un fichier dans une version antérieure nécessitera désormais les mêmes autorisations que le téléchargement d'une nouvelle version du fichier. Le logiciel vérifie désormais la possession des droits « <i lang="en">reupload</i> » ou « <i lang="en">reuplod-own</i> » [https://phabricator.wikimedia.org/T304474], et respecte la protection en cascade. [https://phabricator.wikimedia.org/T140010] * Lorsque les admins listent des pages à supprimer avec l’outil Nuke, ils peuvent désormais également répertorier les pages de discussion associées et les redirections à supprimer, en plus des pages créées par la cible, plutôt que de devoir supprimer manuellement ces pages. [https://phabricator.wikimedia.org/T95797] * La mise à jour [[m:Special:MyLanguage/Tech/News/2025/03|mentionnée précédemment]] de la connexion utilisateur unifiée, qui prendra en compte les restrictions du navigateur sur les cookies inter-domaines en déplaçant la connexion et la création de compte vers un domaine central, sera déployée pour tous les utilisateurs et utilisatrices en mars et avril. L'équipe prévoit de l'activer pour toutes les nouvelles créations de compte sur les wikis du [[wikitech:Deployments/Train#Tuesday|groupe 0]] cette semaine. Consultez la [[mw:Special:MyLanguage/MediaWiki Platform Team/SUL3#Deployment|page du projet SUL3]] pour plus de détails et un calendrier mis à jour. * Depuis la semaine dernière, un bogue cause l'affichage de certaines icônes d'interface sous forme de carrés noirs jusqu'à ce que la page soit entièrement chargée. Cela sera corrigé cette semaine. [https://phabricator.wikimedia.org/T387351] * Un nouveau wiki a été créé : une {{int:project-localized-name-group-wikipedia/fr}} en [[d:Q2044560|sylheti]] ([[w:syl:|<code>w:syl:</code>]]) [https://phabricator.wikimedia.org/T386441] * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:23|la tâche soumise|les {{formatnum:23}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:23||s}} la semaine dernière]]. Par exemple, un bogue avec le chargement d'images dans de très anciennes versions du navigateur Firefox sur mobile a été corrigé. [https://phabricator.wikimedia.org/T386400] '''Actualités pour la contribution technique''' * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.44/wmf.19|MediaWiki]] '''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2025/10|Traduire]]&nbsp;• [[m:Tech|Obtenir de l’aide]]&nbsp;• [[m:Talk:Tech/News|Donner son avis]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].'' </div><section end="technews-2025-W10"/> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 4 mars 2025 à 03:30 (CET) <!-- Message envoyé par User:Quiddity (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=28334563 --> == Universal Code of Conduct annual review: proposed changes are available for comment == <div lang="en" dir="ltr" class="mw-content-ltr"> My apologies for writing in English. {{Int:Please-translate}}. I am writing to you to let you know that [[m:Special:MyLanguage/Universal_Code_of_Conduct/Annual_review/Proposed_Changes|proposed changes]] to the [[foundation:Special:MyLanguage/Policy:Universal_Code_of_Conduct/Enforcement_guidelines|Universal Code of Conduct (UCoC) Enforcement Guidelines]] and [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Charter|Universal Code of Conduct Coordinating Committee (U4C) Charter]] are open for review. '''[[m:Special:MyLanguage/Universal_Code_of_Conduct/Annual_review/Proposed_Changes|You can provide feedback on suggested changes]]''' through the [[d:Q614092|end of day]] on Tuesday, 18 March 2025. This is the second step in the annual review process, the final step will be community voting on the proposed changes. [[m:Special:MyLanguage/Universal_Code_of_Conduct/Annual_review|Read more information and find relevant links about the process on the UCoC annual review page on Meta]]. The [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee|Universal Code of Conduct Coordinating Committee]] (U4C) is a global group dedicated to providing an equitable and consistent implementation of the UCoC. This annual review was planned and implemented by the U4C. For more information and the responsibilities of the U4C, [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Charter|you may review the U4C Charter]]. Please share this information with other members in your community wherever else might be appropriate. -- In cooperation with the U4C, [[m:User:Keegan (WMF)|Keegan (WMF)]] 7 mars 2025 à 19:50 (CET) </div> <!-- Message envoyé par User:Keegan (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=28307738 --> == Actualités techniques n° 2025-11 == <section begin="technews-2025-W11"/><div class="plainlinks"> Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2025/11|D’autres traductions]] sont disponibles. '''Actualités pour la contribution''' * Les contributeurs qui utilisent des gestionnaires de mots de passe sur plusieurs wikis peuvent remarquer des changements à l’avenir. La manière dont nos wikis fournissent des informations aux gestionnaires de mots de passe sur la réutilisation des mots de passe entre les domaines a été récemment mise à jour, de sorte que certains gestionnaires de mots de passe peuvent maintenant vous proposer des identifiants de connexion que vous avez sauvegardés pour un autre site Wikimedia. Certains gestionnaires de mots de passe l'ont déjà fait, et le font maintenant pour d'autres domaines de Wikimedia. Cela fait partie du projet [[mw:Special:MyLanguage/MediaWiki Platform Team/SUL3|SUL3]] qui vise à améliorer le fonctionnement de notre connexion unifiée et à la rendre compatible avec les changements en cours dans les navigateurs web que nous utilisons. [https://phabricator.wikimedia.org/T385520][https://phabricator.wikimedia.org/T384844] * L'équipe des applications Wikipédia invite les utilisateurs intéressés à contribuer à l'amélioration de l'utilisation de Wikipédia hors ligne ou en internet limité. Après les discussions de [[m:Afrika Baraza|Afrika Baraza]] et la dernière [[m:Special:MyLanguage/ESEAP Hub/Meetings|conférence ESEAP]], des défis clés comme la recherche, la modification et l'accès hors ligne sont explorés, avec des groupes de discussion à venir pour approfondir ces sujets. Toutes les langues sont les bienvenues et des interprètes seront disponibles. Vous souhaitez partager vos idées ? [[mw:Special:MyLanguage/Wikimedia Apps/Improving Wikipedia Mobile Apps for Offline & Limited Internet Use|Participez à la discussion]] ou envoyez un courriel à <bdi lang="en" dir="ltr">aramadan@wikimedia.org</bdi> ! * Tous les wikis seront en lecture seule pendant quelques minutes le 19 mars, à [https://zonestamp.toolforge.org/1742392800 14 h UTC]. De plus amples informations seront publiées dans les ''Actualités techniques'' et seront également publiées sur chaque wiki dans les semaines à venir. * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:27|la tâche soumise|les {{formatnum:27}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:27||s}} la semaine dernière]]. '''Actualités pour la contribution technique''' * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.44/wmf.20|MediaWiki]] '''En détails''' * La dernière [[mw:Special:MyLanguage/Growth/Newsletters/33|infolettre trimestrielle du département Croissance]] est disponible. Elle présente : le lancement du module Actualités de la communauté, les dernières modifications de la configuration communautaire et le test à venir des suggestions d'articles pour les personnes contribuant pour la première fois. * Une ancienne API utilisée dans l'application Android Wikipedia sera supprimée à la fin du mois de mars. Il n'y a pas d'utilisation logicielle en cours, mais les utilisateurs de l'application dont la version date de plus de 6 mois au moment de la suppression (2025-03-31), n'auront plus accès à la fonction Suggested Edits, jusqu'à ce qu'ils mettent à jour leur application. Vous pouvez [[diffblog:2025/02/24/sunset-of-wikimedia-recommendation-api/|lire plus de détails sur ce changement]]. '''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2025/11|Traduire]]&nbsp;• [[m:Tech|Obtenir de l’aide]]&nbsp;• [[m:Talk:Tech/News|Donner son avis]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].'' </div><section end="technews-2025-W11"/> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 11 mars 2025 à 00:09 (CET) <!-- Message envoyé par User:Quiddity (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=28372257 --> == Votre wiki sera bientôt en lecture seule == <section begin="server-switch"/><div class="plainlinks"> [[:m:Special:MyLanguage/Tech/Server switch|Lire ce message dans une autre langue]] • [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-Tech%2FServer+switch&language=&action=page&filter= {{int:please-translate}}] La [[foundation:|Fondation Wikimedia]] va basculer le trafic entre ses centres de données. Cela permettra de s’assurer que Wikipédia et les autres wikis de Wikimedia peuvent rester en ligne même après une catastrophe. Le trafic sera basculé le '''{{#time:j xg|2025-03-19|fr}}'''. La bascule débutera à '''[https://zonestamp.toolforge.org/{{#time:U|2025-03-19T14:00|en}} {{#time:H:i e|2025-03-19T14:00}}]'''. Malheureusement, en raison de certaines limites de [[mw:Special:MyLanguage/Manual:What is MediaWiki?|MediaWiki]], toutes les modifications de pages devront être arrêtées durant le passage d’un centre de données à l’autre. Nous nous excusons pour ce dérangement, que nous nous efforçons de réduire pour le futur. Une bannière sera affichée sur tous les wikis 30 minutes avant le début de l’opération. Cette bannière restera visible jusqu’à la fin de l’opération. '''Pendant une courte période, vous pourrez lire les wikis mais pas les modifier.''' *Vous ne pourrez pas effectuer de modification pendant une durée pouvant aller jusqu’à une heure, le {{#time:l j xg Y|2025-03-19|fr}}. *Si vous essayez de faire une modification ou de sauvegarder pendant cette période, vous verrez un message d’erreur. Nous espérons qu’aucune modification ne sera perdue durant ce temps, mais nous ne pouvons le garantir. Si vous voyez un message d’erreur, merci de patienter jusqu’au retour à la normale. Vous pourrez alors enregistrer votre modification. Nous vous conseillons cependant de faire une copie de votre modification avant, au cas où. ''Autres conséquences :'' *Les tâches de fond seront ralenties et certaines pourraient être stoppées. Les liens rouges ne seront pas mis à jour aussi vite que d’habitude. Si vous créez un article qui est déjà lié depuis une autre page, le lien rouge pourrait rester rouge plus longtemps que d’habitude. Certains scripts ayant un long temps d’exécution devront être stoppés. * Le déploiement de code devrait se dérouler comme chaque semaine. Cependant, certains codes particuliers pourraient être gelés si l’opération le nécessitait. * [[mw:Special:MyLanguage/GitLab|GitLab]] sera indisponible durant environ 90 minutes. Ce projet pourra être reporté si nécessaire. Vous pouvez [[wikitech:Switch_Datacenter|consulter le calendrier sur wikitech.wikimedia.org]]. Tout changement sera annoncé dans le calendrier. '''Merci de partager ces informations avec votre communauté.'''</div><section end="server-switch"/> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 15 mars 2025 à 00:14 (CET) <!-- Message envoyé par User:Quiddity (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=28307742 --> == <span lang="en" dir="ltr">Tech News: 2025-12</span> == <div lang="en" dir="ltr"> <section begin="technews-2025-W12"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2025/12|Translations]] are available. '''Weekly highlight''' * Twice a year, around the equinoxes, the Wikimedia Foundation's Site Reliability Engineering (SRE) team performs [[m:Special:MyLanguage/Tech/Server switch|a datacenter server switchover]], redirecting all traffic from one primary server to its backup. This provides reliability in case of a crisis, as we can always fall back on the other datacenter. [http://listen.hatnote.com/ Thanks to the Listen to Wikipedia] tool, you can hear the switchover take place: Before it begins, you'll hear the steady stream of edits; Then, as the system enters a brief read-only phase, the sound stops for a couple of minutes, before resuming after the switchover. You can [[diffblog:2025/03/12/hear-that-the-wikis-go-silent-twice-a-year/|read more about the background and details of this process on the Diff blog]]. If you want to keep an ear out for the next server switchover, listen to the wikis on [https://zonestamp.toolforge.org/1742392800 March 19 at 14:00 UTC]. '''Updates for editors''' * The [https://test.wikipedia.org/w/index.php?title=Special:ContentTranslation&filter-type=automatic&filter-id=previous-edits&active-list=suggestions&from=en&to=es improved Content Translation tool dashboard] is now available in [[phab:T387820|10 Wikipedias]] and will be available for all Wikipedias [[phab:T387821|soon]]. With [[mw:Special:MyLanguage/Content translation#Improved translation experience|the unified dashboard]], desktop users can now: Translate new sections of an article; Discover and access topic-based [https://ig.m.wikipedia.org/w/index.php?title=Special:ContentTranslation&active-list=suggestions&from=en&to=ig&filter-type=automatic&filter-id=previous-edits article suggestion filters] (initially available only for mobile device users); Discover and access the [[mw:Special:MyLanguage/Translation suggestions: Topic-based & Community-defined lists|Community-defined lists]] filter, also known as "Collections", from wiki-projects and campaigns. * On Wikimedia Commons, a [[c:Commons:WMF support for Commons/Upload Wizard Improvements#Improve category selection|new system to select the appropriate file categories]] has been introduced: if a category has one or more subcategories, users will be able to click on an arrow that will open the subcategories directly within the form, and choose the correct one. The parent category name will always be shown on top, and it will always be possible to come back to it. This should decrease the amount of work for volunteers in fixing/creating new categories. The change is also available on mobile. These changes are part of planned improvements to the UploadWizard. * The Community Tech team is seeking wikis to join a pilot for the [[m:Special:MyLanguage/Community Wishlist Survey 2023/Multiblocks|Multiblocks]] feature and a refreshed Special:Block page in late March. Multiblocks enables administrators to impose multiple different types of blocks on the same user at the same time. If you are an admin or steward and would like us to discuss joining the pilot with your community, please leave a message on the [[m:Talk:Community Wishlist Survey 2023/Multiblocks|project talk page]]. * Starting March 25, the Editing team will test a new feature for Edit Check at [[phab:T384372|12 Wikipedias]]: [[mw:Special:MyLanguage/Help:Edit check#Multi-check|Multi-Check]]. Half of the newcomers on these wikis will see all [[mw:Special:MyLanguage/Help:Edit check#ref|Reference Checks]] during their edit session, while the other half will continue seeing only one. The goal of this test is to see if users are confused or discouraged when shown multiple Reference Checks (when relevant) within a single editing session. At these wikis, the tags used on edits that show References Check will be simplified, as multiple tags could be shown within a single edit. Changes to the tags are documented [[phab:T373949|on Phabricator]]. [https://phabricator.wikimedia.org/T379131] * The [[m:Special:MyLanguage/Global reminder bot|Global reminder bot]], which is a service for notifying users that their temporary user-rights are about to expire, now supports using the localized name of the user-rights group in the message heading. Translators can see the [[m:Global reminder bot/Translation|listing of existing translations and documentation]] to check if their language needs updating or creation. * The [[Special:GlobalPreferences|GlobalPreferences]] gender setting, which is used for how the software should refer to you in interface messages, now works as expected by overriding the local defaults. [https://phabricator.wikimedia.org/T386584] * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:26}} community-submitted {{PLURAL:26|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, the Wikipedia App for Android had a bug fixed for when a user is browsing and searching in multiple languages. [https://phabricator.wikimedia.org/T379777] '''Updates for technical contributors''' * Later this week, the way that Codex styles are loaded will be changing. There is a small risk that this may result in unstyled interface message boxes on certain pages. User generated content (e.g. templates) is not impacted. Gadgets may be impacted. If you see any issues [[phab:T388847|please report them]]. See the linked task for details, screenshots, and documentation on how to fix any affected gadgets. * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.44/wmf.21|MediaWiki]] '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2025/12|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2025-W12"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 18 mars 2025 à 00:48 (CET) <!-- Message envoyé par User:Quiddity (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=28412594 --> == Actualités techniques n° 2025-13 == <section begin="technews-2025-W13"/><div class="plainlinks"> Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2025/13|D’autres traductions]] sont disponibles. '''En lumière cette semaine''' * La Fondation Wikimédia souhaite recueillir vos commentaires sur les [[m:Special:MyLanguage/Wikimedia Foundation Annual Plan/2025-2026/Product & Technology OKRs|ébauches des objectifs et des résultats-clés qui façonneront les priorités de la Fondation en matière de produits et de technologies]] pour la prochaine année fiscale (commençant en juillet). Les objectifs sont des domaines généraux et les résultats-clés permettent de mesurer leur réalisation. N'hésitez pas à partager vos commentaires sur la page de discussion, dans n'importe quelle langue, idéalement avant fin avril. '''Actualités pour la contribution''' * L'extension [[mw:Special:MyLanguage/Help:Extension:CampaignEvents|CampaignEvents]] sera déployée sur plusieurs wikis (voir le [[m:Special:MyLanguage/CampaignEvents/Deployment status#Global Deployment Plan|plan de déploiement]] pour plus de détails) en avril 2025, et l'équipe a commencé le processus d'engagement des communautés sur les wikis identifiés. L'extension fournit des outils pour organiser, gérer et promouvoir des activités collaboratives (comme des événements, des edit-a-thons et des WikiProjects) sur les wikis. L'extension comporte trois outils : [[m:Special:MyLanguage/Event Center/Registration|Inscription à l'événement]], [[m:Special:MyLanguage/CampaignEvents/Collaboration list|Liste de collaboration]] et [[m:Special:MyLanguage/Campaigns/Foundation Product Team/Invitation list|Liste d'invitation]]. Elle est actuellement présente sur 13 Wikipédias, dont la Wikipédia en anglais, la Wikipédia en français et la Wikipédia en espagnol, ainsi que sur Wikidata. Les questions ou demandes peuvent être adressées sur la [[mw:Help talk:Extension:CampaignEvents|page de discussion de l'extension]] ou sur Phabricator (avec l'étiquette <bdi lang="en" dir="ltr" style="white-space: nowrap;">#campaigns-product-team</bdi>). * À partir de la semaine du 31 mars, les wikis pourront définir quels groupes d'utilisateurs peuvent voir les inscriptions privées dans [[m:Special:MyLanguage/Event Center/Registration|Inscription à l'événement]], dans le cadre de l'extension [[mw:Special:MyLanguage/Help:Extension:CampaignEvents|CampaignEvents]]. Par défaut, les organisateurs d'événements et les administrateurs du wiki local pourront voir les inscriptions privées. Il s'agit d'un changement par rapport au réglage actuel qui permet seulement aux organisateurs de l'événement de voir les inscriptions privées. Les wikis peuvent modifier la configuration par défaut en demandant un changement de configuration dans Phabricator (et en ajoutant l'étiquette <bdi lang="en" dir="ltr" style="white-space: nowrap;">#campaigns-product-team</bdi>). Les participants aux événements passés peuvent annuler leur inscription à tout moment. * Les administrateurs des wikis qui disposent d'une barre latérale <bdi lang="en" dir="ltr">[[MediaWiki:Sidebar]]</bdi> personnalisée doivent vérifier si elle contient une entrée pour la liste {{int:specialpages}}. Si ce n'est pas le cas, ils doivent l'ajouter en utilisant <code dir=ltr style="white-space: nowrap;">* specialpages-url|specialpages</code>. Les wikis disposant d'une barre latérale par défaut verront le lien déplacé de la boîte à outils de la page vers le menu de la barre latérale en avril. [https://phabricator.wikimedia.org/T388927] * L'habillage Minerva (web mobile) combine les notifications d'avis et d'alertes dans l'icône de cloche ([[File:OOjs UI icon bell.svg|16px|link=|class=skin-invert]]). Il existait depuis longtemps un bogue qui faisait qu'une indication de nouvelles notifications n'était affichée que si vous aviez des alertes que vous n'avez pas vues. Ce problème est désormais résolu. À l'avenir, les utilisateurs de Minerva remarqueront un compteur au-dessus de l'icône de la cloche lorsque vous avez un ou plusieurs notifications et/ou alertes non vues. [https://phabricator.wikimedia.org/T344029] * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:23|la tâche soumise|les {{formatnum:23}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:23||s}} la semaine dernière]]. '''Actualités pour la contribution technique''' * VisualEditor a introduit un [[mw:VisualEditor/Hooks|nouveau hook côté client]] pour les développeurs à utiliser lors de l'intégration avec le cycle de vie de la cible VisualEditor. Ce hook devrait remplacer les hooks existants liés au cycle de vie et être plus cohérent entre les différentes plateformes. De plus, le nouveau hook s'appliquera aux utilisations de VisualEditor en dehors de l'édition complète d'articles, permettant aux gadgets d'interagir avec l'éditeur dans DiscussionTools également. L'équipe d'édition a l'intention de déprécier et éventuellement de supprimer les hooks de l'ancien cycle de vie, donc tous les cas d'utilisation que ce nouveau hook ne couvre pas seraient intéressants pour l'équipe et peuvent être [[phab:T355555|partagés dans la tâche]]. * Les développeurs qui utilisent la bibliothèque JavaScript <code dir=ltr>mw.Api</code> peuvent désormais identifier l'outil qui l'utilise avec le paramètre <code dir=ltr>userAgent</code> : <code dir=ltr>var api = new mw.Api( { userAgent: 'GadgetNameHere/1.0.1' } );</code>. Si vous gérez un gadget ou un script utilisateur, veuillez définir un agent utilisateur, car cela facilite la maintenance de la bibliothèque et du serveur et permet de différencier le trafic légitime du trafic illégitime. [https://phabricator.wikimedia.org/T373874][https://foundation.wikimedia.org/wiki/Policy:Wikimedia_Foundation_User-Agent_Policy] * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.44/wmf.22|MediaWiki]] '''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2025/13|Traduire]]&nbsp;• [[m:Tech|Obtenir de l’aide]]&nbsp;• [[m:Talk:Tech/News|Donner son avis]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].'' </div><section end="technews-2025-W13"/> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 24 mars 2025 à 23:42 (CET) <!-- Message envoyé par User:Quiddity (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=28443127 --> == Actualités techniques n° 2025-14 == <section begin="technews-2025-W14"/><div class="plainlinks"> Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2025/14|D’autres traductions]] sont disponibles. '''Actualités pour la contribution''' * L'équipe Contribution travaille sur une nouvelle [[mw:Special:MyLanguage/Edit Check|vérification des modifications]] : le [[mw:Special:MyLanguage/Edit check#26 March 2025|contrôle des éloges]]. L'objectif de cette vérification est d’identifier les termes non neutres saisis lors de la modification d’une page Wikipédia, afin d’informer l’auteur ou autrice que son texte devrait peut-être être modifié avant publication. Ce projet n’en est qu’à ses débuts ; l’équipe a besoin de l’avis des communautés. Dans [[phab:T389445|cette tâche Phabricator]], l’équipe rassemble les recommendations internes des wikis, les modèles utilisés pour étiqueter les articles non neutres et les termes (jargon et mots-clés) utilisés dans les résumés de modification pour les langues étudiées actuellement. Vous pouvez participer en modifiant le tableau sur Phabricator, en commentant la tâche ou en envoyant directement un message à [[m:user:Trizek (WMF)|Trizek (WMF)]]. * La [[mw:Special:MyLanguage/MediaWiki Platform Team/SUL3|connexion utilisateur unique]] (SUL) a été mise à jour sur tous les wikis afin de déplacer la connexion et la création de compte vers un domaine central. Cela rend la connexion des contributeurs compatible avec les restrictions des navigateurs sur les cookies inter-domaines, qui ont empêché les utilisateurs de certains navigateurs de rester connectés. * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:35|la tâche soumise|les {{formatnum:35}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:35||s}} la semaine dernière]]. '''Actualités pour la contribution technique''' * À partir du 31 mars, l'équipe MediaWiki Interfaces va lancer une version limitée des spécifications OpenAPI générées et une expérience de bac à sable basée sur SwaggerUI pour [[mw:Special:MyLanguage/API:REST API|MediaWiki REST APIs]]. L'équipe invite les développeurs d'un groupe limité de communautés Wikipédia non anglophones (arabe, allemand, français, hébreu, interlingua, néerlandais, chinois) à consulter la documentation et à expérimenter le bac à sable dans leur langue de choix. En plus de ces projets Wikipédia spécifiques, le bac à sable et la spécification OpenAPI seront disponibles sur la [[testwiki:Special:RestSandbox|page spéciale test wiki REST Sandbox]] pour les développeurs dont l'anglais est la langue préférée. Pendant la période de prévisualisation, l'équipe MediaWiki Interfaces invite également les développeurs à [[mw:MediaWiki Interfaces Team/Feature Feedback/REST Sandbox|partager leur retour d'expérience]]. L'aperçu durera environ 2 semaines, après quoi le bac à sable et les spécifications OpenAPI seront mis à la disposition de tous les projets wiki. * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.44/wmf.23|MediaWiki]] '''En détails''' * Parfois, un petit changement de code d'une ligne peut avoir une grande importance : dans ce cas, cela signifie que pour la première fois depuis des années, nous sommes en mesure de faire fonctionner toute la pile qui sert <bdi lang="en" dir="ltr">[http://maps.wikimedia.org/ maps.wikimedia.org]</bdi> - un hôte dédié à servir nos wikis et leurs besoins en cartes multilingues - à partir d'un seul centre de données, ce que nous testons à chaque fois que nous effectuons un [[m:Special:MyLanguage/Tech/Server switch|basculement de centre de données]]. C'est important car cela signifie que si l'un de nos centres de données est affecté par une catastrophe, nous serons toujours en mesure de servir le site. Ce changement est le résultat d'un [[phab:T216826|travail intensif]] de deux développeurs sur le portage du dernier composant de la pile de cartes sur [[w:fr:Kubernetes|kubernetes]], où nous pouvons allouer des ressources plus efficacement qu'auparavant, ce qui nous permet de supporter plus de trafic dans un seul centre de données. Ce travail a nécessité beaucoup d'étapes compliquées car ce logiciel et les bibliothèques logicielles qu'il utilise nécessitaient de nombreuses mises à jour attendues depuis longtemps. Ce type de travail rend l'infrastructure de Wikimedia plus durable. '''Rencontres et évènements''' * La [[mw:Special:MyLanguage/MediaWiki Users and Developers Workshop Spring 2025|Conférence des utilisateurs et développeurs de MediaWiki printemps 2025]] se déroulera à Sandusky, aux États-Unis, et en ligne, du 14 au 16 mai 2025. La conférence proposera des discussions autour de l'utilisation du logiciel MediaWiki par et au sein d'entreprises de différents secteurs, et inspirera et embarquera de nouveaux utilisateurs. L'inscription et l'enregistrement des présentations sont maintenant disponibles sur le site web de la conférence. '''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2025/14|Traduire]]&nbsp;• [[m:Tech|Obtenir de l’aide]]&nbsp;• [[m:Talk:Tech/News|Donner son avis]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].'' </div><section end="technews-2025-W14"/> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 1 avril 2025 à 02:05 (CEST) <!-- Message envoyé par User:Quiddity (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=28473566 --> == Final proposed modifications to the Universal Code of Conduct Enforcement Guidelines and U4C Charter now posted == <div lang="en" dir="ltr" class="mw-content-ltr"> The proposed modifications to the [[foundation:Special:MyLanguage/Policy:Universal_Code_of_Conduct/Enforcement_guidelines|Universal Code of Conduct Enforcement Guidelines]] and the U4C Charter [[m:Universal_Code_of_Conduct/Annual_review/2025/Proposed_Changes|are now on Meta-wiki for community notice]] in advance of the voting period. This final draft was developed from the previous two rounds of community review. Community members will be able to vote on these modifications starting on 17 April 2025. The vote will close on 1 May 2025, and results will be announced no later than 12 May 2025. The U4C election period, starting with a call for candidates, will open immediately following the announcement of the review results. More information will be posted on [[m:Special:MyLanguage//Universal_Code_of_Conduct/Coordinating_Committee/Election|the wiki page for the election]] soon. Please be advised that this process will require more messages to be sent here over the next two months. The [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee|Universal Code of Conduct Coordinating Committee (U4C)]] is a global group dedicated to providing an equitable and consistent implementation of the UCoC. This annual review was planned and implemented by the U4C. For more information and the responsibilities of the U4C, you may [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Charter|review the U4C Charter]]. Please share this message with members of your community so they can participate as well. -- In cooperation with the U4C, [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User_talk:Keegan (WMF)|talk]]) 4 avril 2025 à 04:04 (CEST) </div> <!-- Message envoyé par User:Keegan (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=28469465 --> == Actualités techniques n° 2025-15 == <section begin="technews-2025-W15"/><div class="plainlinks"> Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2025/15|D’autres traductions]] sont disponibles. '''Actualités pour la contribution''' * Désormais, les [[m:Special:MyLanguage/Interface administrators|admins d’interface]] et [[m:Special:MyLanguage/Central notice administrators|admins des annonces centrales]] sont contraint techniquement d’activer l’[[m:Special:MyLanguage/Help:Two-factor authentication|authentification à deux facteurs]] avant de pouvoir utiliser leurs privilèges. À l’avenir, cela pourrait être étendu à d’autres groupes ayant des droits avancés. [https://phabricator.wikimedia.org/T150898] * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:20|la tâche soumise|les {{formatnum:20}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:20||s}} la semaine dernière]]. '''Actualités pour la contribution technique''' * L’équipe Système design prépare la sortie de la nouvelle version majeur de Codex (v2.0.0) pour le 29 avril. Les contributeurices et développeurs et développeuses qui utilisent du CSS de Codex devraient consulter la [[mw:Codex/Release Timeline/2.0|documentation sur l’arrivée de la v2]], elle inclut un guidage pour les ruptures introduites dans cette version, par exemple pour <code dir=ltr style="white-space: nowrap;">font-size</code>, <code dir=ltr style="white-space: nowrap;">line-height</code> et <code dir=ltr style="white-space: nowrap;">size-icon</code>. * Les résultats de [[mw:Developer Satisfaction Survey/2025|l’enquête 2025 sur la satisfaction des développeurs et développeuses]] est désormais disponible. Merci à tous les participants ! Ces résultats aident Wikimedia à décider ce sur quoi orienter le travail et à évaluer le travail récent. * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.44/wmf.24|MediaWiki]] '''Rencontres et évènements''' * Le [[mw:Special:MyLanguage/Wikimedia Hackathon 2025|Hackathon Wikimedia 2025]] aura lieu à Istanbul en Turquie, du 2 au 4 mai. Les inscriptions pour participer en présentiel ont lieu jusqu’au 13 avril. Avant de vous inscrire, sachez qu’il vous faudra peut-être un [https://www.mfa.gov.tr/turkish-representations.en.mfa visa] ou un [https://www.mfa.gov.tr/visa-information-for-foreigners.en.mfa e-visa] pour entrer dans le pays. '''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2025/15|Traduire]]&nbsp;• [[m:Tech|Obtenir de l’aide]]&nbsp;• [[m:Talk:Tech/News|Donner son avis]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].'' </div><section end="technews-2025-W15"/> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 7 avril 2025 à 20:52 (CEST) <!-- Message envoyé par User:UOzurumba (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=28507470 --> == Wikidata and Sister Projects: An online community event == ''(Apologies for posting in English)'' Hello everyone, I am excited to share news of an upcoming online event called '''[[d:Event:Wikidata_and_Sister_Projects|Wikidata and Sister Projects]]''' celebrating the different ways Wikidata can be used to support or enhance with another Wikimedia project. The event takes place over 4 days between '''May 29 - June 1st, 2025'''. We would like to invite speakers to present at this community event, to hear success stories, challenges, showcase tools or projects you may be working on, where Wikidata has been involved in Wikipedia, Commons, WikiSource and all other WM projects. If you are interested in attending, please [[d:Special:RegisterForEvent/1291|register here]]. If you would like to speak at the event, please fill out this Session Proposal template on the [[d:Event_talk:Wikidata_and_Sister_Projects|event talk page]], where you can also ask any questions you may have. I hope to see you at the event, in the audience or as a speaker, - [[Utilisateur:MediaWiki message delivery|MediaWiki message delivery]] ([[Discussion utilisateur:MediaWiki message delivery|discussion]]) 11 avril 2025 à 11:18 (CEST) <!-- Message envoyé par User:Danny Benjafield (WMDE)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=User:Danny_Benjafield_(WMDE)/MassMessage_Send_List&oldid=28525705 --> == <span lang="en" dir="ltr">Tech News: 2025-16</span> == <div lang="en" dir="ltr"> <section begin="technews-2025-W16"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2025/16|Translations]] are available. '''Weekly highlight''' * Later this week, the default thumbnail size will be increased from 220px to 250px. This changes how pages are shown in all wikis and has been requested by some communities for many years, but wasn't previously possible due to technical limitations. [https://phabricator.wikimedia.org/T355914] * File thumbnails are now stored in discrete sizes. If a page specifies a thumbnail size that's not among the standard sizes (20, 40, 60, 120, 250, 330, 500, 960), then MediaWiki will pick the closest larger thumbnail size but will tell the browser to downscale it to the requested size. In these cases, nothing will change visually but users might load slightly larger images. If it doesn't matter which thumbnail size is used in a page, please pick one of the standard sizes to avoid the extra in-browser down-scaling step. [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Images#Thumbnail_sizes][https://phabricator.wikimedia.org/T355914] '''Updates for editors''' * The Wikimedia Foundation are working on a system called [[m:Edge Uniques|Edge Uniques]] which will enable [[:w:en:A/B testing|A/B testing]], help protect against [[:w:en:Denial-of-service attack|Distributed denial-of-service attacks]] (DDoS attacks), and make it easier to understand how many visitors the Wikimedia sites have. This is so that they can more efficiently build tools which help readers, and make it easier for readers to find what they are looking for. * To improve security for users, a small percentage of logins will now require that the account owner input a one-time password [[mw:Special:MyLanguage/Help:Extension:EmailAuth|emailed to their account]]. It is recommended that you [[Special:Preferences#mw-prefsection-personal-email|check]] that the email address on your account is set correctly, and that it has been confirmed, and that you have an email set for this purpose. [https://phabricator.wikimedia.org/T390662] * "Are you interested in taking a short survey to improve tools used for reviewing or reverting edits on your Wiki?" This question will be [[phab:T389401|asked at 7 wikis starting next week]], on Recent Changes and Watchlist pages. The [[mw:Special:MyLanguage/Moderator Tools|Moderator Tools team]] wants to know more about activities that involve looking at new edits made to your Wikimedia project, and determining whether they adhere to your project's policies. * On April 15, the full Wikidata graph will no longer be supported on <bdi lang="zxx" dir="ltr">[https://query.wikidata.org/ query.wikidata.org]</bdi>. After this date, scholarly articles will be available through <bdi lang="zxx" dir="ltr" style="white-space:nowrap;">[https://query-scholarly.wikidata.org/ query-scholarly.wikidata.org]</bdi>, while the rest of the data hosted on Wikidata will be available through the <bdi lang="zxx" dir="ltr">[https://query.wikidata.org/ query.wikidata.org]</bdi> endpoint. This is part of the scheduled split of the Wikidata Graph, which was [[d:Special:MyLanguage/Wikidata:SPARQL query service/WDQS backend update/September 2024 scaling update|announced in September 2024]]. More information is [[d:Wikidata:SPARQL query service/WDQS graph split|available on Wikidata]]. * The latest quarterly [[m:Special:MyLanguage/Wikimedia Apps/Newsletter/First quarter of 2025|Wikimedia Apps Newsletter]] is now available. It covers updates, experiments, and improvements made to the Wikipedia mobile apps. * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:30}} community-submitted {{PLURAL:30|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. '''Updates for technical contributors''' * The latest quarterly [[mw:Technical Community Newsletter/2025/April|Technical Community Newsletter]] is now available. This edition includes: an invitation for tool maintainers to attend the Toolforge UI Community Feedback Session on April 15th; recent community metrics; and recent technical blog posts. * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.44/wmf.25|MediaWiki]] '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2025/16|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2025-W16"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 15 avril 2025 à 02:24 (CEST) <!-- Message envoyé par User:Quiddity (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=28540654 --> == Vote now on the revised UCoC Enforcement Guidelines and U4C Charter == <div lang="en" dir="ltr" class="mw-content-ltr"> The voting period for the revisions to the Universal Code of Conduct Enforcement Guidelines ("UCoC EG") and the UCoC's Coordinating Committee Charter is open now through the end of 1 May (UTC) ([https://zonestamp.toolforge.org/1746162000 find in your time zone]). [[m:Special:MyLanguage/Universal_Code_of_Conduct/Annual_review/2025/Voter_information|Read the information on how to participate and read over the proposal before voting]] on the UCoC page on Meta-wiki. The [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee|Universal Code of Conduct Coordinating Committee (U4C)]] is a global group dedicated to providing an equitable and consistent implementation of the UCoC. This annual review of the EG and Charter was planned and implemented by the U4C. Further information will be provided in the coming months about the review of the UCoC itself. For more information and the responsibilities of the U4C, you may [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Charter|review the U4C Charter]]. Please share this message with members of your community so they can participate as well. In cooperation with the U4C -- [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User_talk:Keegan (WMF)|talk]]) 17 avril 2025 à 02:34 (CEST) </div> <!-- Message envoyé par User:Keegan (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=28469465 --> == Actualités techniques n° 2025-17 == <section begin="technews-2025-W17"/><div class="plainlinks"> Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2025/17|D’autres traductions]] sont disponibles. '''Actualités pour la contribution''' * [[f:Special:MyLanguage/Wikifunctions:Main Page|Wikifunctions]] est désormais intégré à la [[w:dag:Solɔɣu|Wikipédia en dagbani]] depuis le 15 avril. C'est le premier projet qui pourra appeler des [[f:Special:MyLanguage/Wikifunctions:Introduction|fonctions de Wikifonctions]] et les intégrer dans des articles. Une fonction est quelque chose qui prend une ou plusieurs entrées et les transforme en un résultat souhaité, comme l'addition de deux nombres, la conversion de miles en mètres, le calcul du temps écoulé depuis un événement, ou la déclinaison d'un mot en une casse. Les Wikifonctions permettront aux utilisateurs de faire cela par un simple appel d'[[f:Special:MyLanguage/Wikifunctions:Catalogue|une fonction stable et globale]], plutôt que par l'intermédiaire d'un modèle local. [https://www.wikifunctions.org/wiki/Special:MyLanguage/Wikifunctions:Status_updates/2025-04-16] * Un nouveau type d'erreur ''lint'' a été créé : [[Special:LintErrors/empty-heading|{{int:linter-category-empty-heading}}]] ([[mw:Special:MyLanguage/Help:Lint errors/empty-heading|documentation]]). L'objectif de l'extension [[mw:Special:MyLanguage/Help:Extension:Linter|Linter]] est d'identifier les éléments de wikitexte qui doivent ou peuvent être corrigés dans les pages et de fournir des conseils sur les problèmes posés par ces éléments et sur la manière de les corriger. [https://phabricator.wikimedia.org/T368722] * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:37|la tâche soumise|les {{formatnum:37}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:37||s}} la semaine dernière]]. '''Actualités pour la contribution technique''' * À la suite de sa publication sur ''HuggingFace'', l'ensemble de données « ''Structured Contents'' », développé par Wikimedia Enterprise, est [https://enterprise.wikimedia.com/blog/kaggle-dataset/ maintenant également disponible sur Kaggle]. Cette initiative bêta vise à rendre les données de Wikimedia plus lisibles par les machines pour les réutilisateurs de gros volumes. Cette version bêta est publiée à un emplacement déjà utilisé par les communautés de données ouvertes, afin de recueillir des commentaires qui permettront d'améliorer le produit en vue d'une future diffusion à plus grande échelle. Vous pouvez en savoir plus sur le projet ''[https://enterprise.wikimedia.com/blog/structured-contents-snapshot-api/#open-datasets Structured Contents]'', et sur la [https://enterprise.wikimedia.com/blog/structured-contents-wikipedia-infobox/ première version librement utilisable]. * Il n'y a pas de nouvelle version de MediaWiki cette semaine. '''Rencontres et évènements''' * Les équipes de rédaction et d'apprentissage automatique (''Editing and Machine Learning Teams'') invitent les bénévoles intéressés à une visioconférence pour discuter de la [[mw:Special:MyLanguage/Edit check/Peacock check|vérification « ''peacock'' »]] <small>(NdT : litt. « paon » mais également une expression idiomatique pour le langage vaniteux, prétentieux)</small>, qui est la dernière [[mw:Special:MyLanguage/Edit check|vérification de modification]] qui détectera le langage « trop promotionnel » ou « non neutre » pendant qu'un rédacteur est en train de taper. Les rédacteurs qui travaillent avec les nouveaux arrivants, ou qui aident à corriger ce type d'écriture, ou qui sont intéressés par la manière dont nous utilisons l'intelligence artificielle dans nos projets, sont invités à participer à cette réunion. La [[mw:Special:MyLanguage/Editing team/Community Conversations#Next Conversation|réunion aura lieu le 28 avril 2025]] à [https://zonestamp.toolforge.org/1745863200 18:00-19:00 UTC] et sera hébergée sur Zoom. '''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2025/17|Traduire]]&nbsp;• [[m:Tech|Obtenir de l’aide]]&nbsp;• [[m:Talk:Tech/News|Donner son avis]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].'' </div><section end="technews-2025-W17"/> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 21 avril 2025 à 23:00 (CEST) <!-- Message envoyé par User:Quiddity (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=28578245 --> == Actualités techniques n° 2025-18 == <section begin="technews-2025-W18"/><div class="plainlinks"> Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2025/18|D’autres traductions]] sont disponibles. '''Actualités pour la contribution''' * <span lang="en" dir="ltr" class="mw-content-ltr">Event organizers who host collaborative activities on [[m:Special:MyLanguage/CampaignEvents/Deployment status#Global Deployment Plan|multiple wikis]], including Bengali, Japanese, and Korean Wikipedias, will have access to the [[mw:Special:MyLanguage/Extension:CampaignEvents|CampaignEvents extension]] this week. Also, admins in the Wikipedia where the extension is enabled will automatically be granted the event organizer right soon. They won't have to manually grant themselves the right before they can manage events as [[phab:T386861|requested by a community]].</span> * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:19|la tâche soumise|les {{formatnum:19}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:19||s}} la semaine dernière]]. '''Actualités pour la contribution technique''' * <span lang="en" dir="ltr" class="mw-content-ltr">The release of the next major version of [[mw:Special:MyLanguage/Codex|Codex]], the design system for Wikimedia, is scheduled for 29 April 2025. Technical editors will have access to the release by the week of 5 May 2025. This update will include a number of [[mw:Special:MyLanguage/Codex/Release_Timeline/2.0#Breaking_changes|breaking changes]] and minor [[mw:Special:MyLanguage/Codex/Release_Timeline/2.0#Visual_changes|visual changes]]. Instructions on handling the breaking and visual changes are documented on [[mw:Special:MyLanguage/Codex/Release Timeline/2.0#|this page]]. Pre-release testing is reported in [[phab:T386298|T386298]], with post-release issues tracked in [[phab:T392379|T392379]] and [[phab:T392390|T392390]].</span> * <span lang="en" dir="ltr" class="mw-content-ltr">Users of [[wikitech:Special:MyLanguage/Help:Wiki_Replicas|Wiki Replicas]] will notice that the database views of <code dir="ltr">ipblocks</code>, <code dir="ltr">ipblocks_ipindex</code>, and <code dir="ltr">ipblocks_compat</code> are [[phab:T390767|now deprecated]]. Users can query the <code dir="ltr">[[mw:Special:MyLanguage/Manual:Block_table|block]]</code> and <code dir="ltr">[[mw:Special:MyLanguage/Manual:Block_target_table|block_target]]</code> new views that mirror the new tables in the production database instead. The deprecated views will be removed entirely from Wiki Replicas in June, 2025.</span> * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.44/wmf.27|MediaWiki]] '''En détails''' * <span lang="en" dir="ltr" class="mw-content-ltr">The latest quarterly [[mw:Special:MyLanguage/Wikimedia Language and Product Localization/Newsletter/2025/April|Language and Internationalization Newsletter]] is now available.</span> <span lang="en" dir="ltr" class="mw-content-ltr">This edition includes an overview of the improved [https://test.wikipedia.org/w/index.php?title=Special:ContentTranslation&campaign=contributionsmenu&to=es&filter-type=automatic&filter-id=previous-edits&active-list=suggestions&from=en#/ Content Translation Dashboard Tool], [[mw:Special:MyLanguage/Wikimedia Language and Product Localization/Newsletter/2025/April#Language Support for New and Existing Languages|support for new languages]], [[mw:Special:MyLanguage/Wikimedia Language and Product Localization/Newsletter/2025/April#Wiki Loves Ramadan Articles Made In Content Translation Mobile Workflow|highlights from the Wiki Loves Ramadan campaign]], [[m:Special:MyLanguage/Research:Languages Onboarding Experiment 2024 - Executive Summary|results from the Language Onboarding Experiment]], an analysis of topic diversity in articles, and information on upcoming community meetings and events.</span> '''Rencontres et évènements''' * <span lang="en" dir="ltr" class="mw-content-ltr">The [[Special:MyLanguage/Grants:Knowledge_Sharing/Connect/Calendar|Let's Connect Learning Clinic]] will take place on [https://zonestamp.toolforge.org/1745937000 April 29 at 14:30 UTC]. This edition will focus on "Understanding and Navigating Conflict in Wikimedia Projects". You can [[m:Special:MyLanguage/Event:Learning Clinic %E2%80%93 Understanding and Navigating Conflict in Wikimedia Projects (Part_1)|register now]] to attend.</span> * <span lang="en" dir="ltr" class="mw-content-ltr">The [[mw:Special:MyLanguage/Wikimedia Hackathon 2025|2025 Wikimedia Hackathon]], which brings the global technical community together to connect, brainstorm, and hack existing projects, will take place from May 2 to 4th, 2025, at Istanbul, Turkey.</span> '''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2025/18|Traduire]]&nbsp;• [[m:Tech|Obtenir de l’aide]]&nbsp;• [[m:Talk:Tech/News|Donner son avis]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].'' </div><section end="technews-2025-W18"/> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 28 avril 2025 à 21:31 (CEST) <!-- Message envoyé par User:UOzurumba (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=28585685 --> == Vote sur les modifications proposées aux lignes directrices de l'UCoC et à la charte de l'U4C == <section begin="announcement-content" /> La période de vote pour les révisions des directives d'application du Code de conduite universel et de la Charte U4C se termine le 1er mai 2025 à 23:59 UTC ([https://zonestamp.toolforge.org/1746162000 trouver dans votre fuseau horaire]). [[m:Special:MyLanguage/Universal Code of Conduct/Annual review/2025/Voter information|Lisez les informations sur la façon de participer et lisez la proposition avant de voter]] sur la page UCoC de Méta-wiki. Le [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee|Comité de coordination du code de conduite universel (U4C)]] est un groupe mondial qui se consacre à la mise en œuvre équitable et cohérente de l'UCoC. Cet examen annuel a été planifié et mis en œuvre par l'U4C. Pour plus d'informations et pour connaître les responsabilités de l'U4C, vous pouvez [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Charter|réviser la charte U4C]]. Veuillez partager ce message avec les membres de votre communauté dans votre langue, le cas échéant, afin qu'ils puissent également y participer. En coopération avec l'U4C -- <section end="announcement-content" /> <div lang="en" dir="ltr" class="mw-content-ltr"> [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) 29 avril 2025 à 05:40 (CEST)</div> <!-- Message envoyé par User:Keegan (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=28618011 --> == Actualités techniques n° 2025-19 == <section begin="technews-2025-W19"/><div class="plainlinks"> Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2025/19|D’autres traductions]] sont disponibles. '''En lumière cette semaine''' * La Wikimedia Foundation a partagé le dernier projet de mise à jour de son [[m:Special:MyLanguage/Wikimedia Foundation Annual Plan/2025-2026|plan annuel]] pour l'année prochaine (juillet 2025-juin 2026). Cela comprend un [[m:Special:MyLanguage/Wikimedia Foundation Annual Plan/2025-2026|résumé exécutif]] (également sur [[diffblog:2025/04/25/sharing-the-wikimedia-foundations-2025-2026-draft-annual-plan/|Diff]]), des détails sur les trois principaux [[m:Special:MyLanguage/Wikimedia Foundation Annual Plan/2025-2026/Goals|objectifs]] ([[m:Special:MyLanguage/Wikimedia Foundation Annual Plan/2025-2026/Product & Technology OKRs|Infrastructure]], [[m:Special:MyLanguage/Wikimedia Foundation Annual Plan/2025-2026/Goals/Volunteer Support|Soutien aux bénévoles]] et [[m:Special:MyLanguage/Wikimedia Foundation Annual Plan/2025-2026/Goals/Effectiveness|Efficacité]]), [[m:Special:MyLanguage/Wikimedia Foundation Annual Plan/2025-2026/Global Trends|tendances mondiales]], ainsi que le [[m:Special:MyLanguage/Wikimedia Foundation Annual Plan/2025-2026/Budget Overview|budget]] et le [[m:Special:MyLanguage/Wikimedia Foundation Annual Plan/2025-2026/Financial Model|modèle financier]]. Les réactions et les questions sont les bienvenues sur la [[m:Talk:Wikimedia Foundation Annual Plan/2025-2026|page de discussion]] jusqu'à la fin du mois de mai. '''Actualités pour la contribution''' * Pour les wikis qui ont l'extension [[m:Special:MyLanguage/CampaignEvents/Deployment status|CampaignEvents]] activée, deux nouvelles améliorations de fonctionnalités ont été publiées : ** Les administrateurs peuvent désormais choisir les espaces de noms autorisés pour [[m:Special:MyLanguage/Event Center/Registration|Inscription à un événement]] via [[mw:Special:MyLanguage/Community Configuration|Configuration de la communauté]] ([[mw:Special:MyLanguage/Help:Extension:CampaignEvents/Registration/Permitted namespaces|documentation]]). Par défaut, l'enregistrement d'un événement est autorisé dans l'espace de noms Event, mais d'autres espaces de noms (tels que l'espace de noms du projet ou l'espace de noms WikiProject) peuvent désormais être ajoutés. Grâce à cette modification, les communautés telles que les WikiProjets peuvent désormais utiliser plus facilement l'enregistrement d'événements pour leurs activités collaboratives. ** Les éditeurs peuvent désormais [[mw:Special:MyLanguage/Transclusion|transclure]] la liste de collaboration sur une page wiki ([[mw:Special:MyLanguage/Help:Extension:CampaignEvents/Collaboration list/Transclusion|documentation]]). La liste de collaboration est une liste automatisée d'événements et de wikiprojets sur les wikis, accessible via {{#special:AllEvents}} ([[w:en:Special:AllEvents|exemple]]). Désormais, la liste de collaboration peut être ajoutée à toutes sortes de pages wiki, telles que : une page principale wiki, une page WikiProjet, une page d'affiliation, une page d'événement, ou même une page d'utilisateur. * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:27|la tâche soumise|les {{formatnum:27}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:27||s}} la semaine dernière]]. '''Actualités pour la contribution technique''' * Les développeurs qui utilisent la bibliothèque <code dir=ltr>moment</code> dans les gadgets et les scripts utilisateur doivent réviser leur code pour utiliser des alternatives comme la bibliothèque <code dir=ltr>Intl</code> ou la nouvelle bibliothèque <code dir=ltr>mediawiki.DateFormatter</code>. La bibliothèque <code dir=ltr>moment</code> a été dépréciée et commencera à enregistrer des messages dans la console du développeur. Vous pouvez voir une recherche globale pour les utilisations actuelles, et [[phab:T392532|posez des questions connexes dans cette tâche Phabricator]]. * Les développeurs qui maintiennent un outil qui interroge les tables de stockage de termes de Wikidata (<code dir=ltr style="white-space: nowrap;">wbt_*</code>) doivent mettre à jour leur code pour se connecter à une grappe de base de données séparée. Ces tables sont réparties dans une grappe de base de données distincte. Les outils qui interrogent ces tables via les répliques du wiki doivent être adaptés pour se connecter à la nouvelle grappe. [[wikitech:News/2025 Wikidata term store database split|La documentation et des liens connexes sont à votre disposition]]. [https://phabricator.wikimedia.org/T390954] * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.44/wmf.28|MediaWiki]] '''En détails''' * La dernière [[mw:Special:MyLanguage/Extension:Chart/Project/Updates|lettre d’information du projet Chart]] est disponible. Il comprend des mises à jour sur la préparation de l'extension du déploiement à d'autres wikis dès cette semaine (à partir du 6 mai) et sur la mise à l'échelle au cours des semaines suivantes, ainsi que sur l'exploration du filtrage et de la transformation des données sources. '''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2025/19|Traduire]]&nbsp;• [[m:Tech|Obtenir de l’aide]]&nbsp;• [[m:Talk:Tech/News|Donner son avis]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].'' </div><section end="technews-2025-W19"/> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 6 mai 2025 à 02:14 (CEST) <!-- Message envoyé par User:Quiddity (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=28665011 --> == We will be enabling the new Charts extension on your wiki soon! == ''(Apologies for posting in English)'' Hi all! We have good news to share regarding the ongoing problem with graphs and charts affecting all wikis that use them. As you probably know, the [[:mw:Special:MyLanguage/Extension:Graph|old Graph extension]] was disabled in 2023 [[listarchive:list/wikitech-l@lists.wikimedia.org/thread/EWL4AGBEZEDMNNFTM4FRD4MHOU3CVESO/|due to security reasons]]. We’ve worked in these two years to find a solution that could replace the old extension, and provide a safer and better solution to users who wanted to showcase graphs and charts in their articles. We therefore developed the [[:mw:Special:MyLanguage/Extension:Chart|Charts extension]], which will be replacing the old Graph extension and potentially also the [[:mw:Extension:EasyTimeline|EasyTimeline extension]]. After successfully deploying the extension on Italian, Swedish, and Hebrew Wikipedia, as well as on MediaWiki.org, as part of a pilot phase, we are now happy to announce that we are moving forward with the next phase of deployment, which will also include your wiki. The deployment will happen in batches, and will start from '''May 6'''. Please, consult [[:mw:Special:MyLanguage/Extension:Chart/Project#Deployment Timeline|our page on MediaWiki.org]] to discover when the new Charts extension will be deployed on your wiki. You can also [[:mw:Special:MyLanguage/Extension:Chart|consult the documentation]] about the extension on MediaWiki.org. If you have questions, need clarifications, or just want to express your opinion about it, please refer to the [[:mw:Special:MyLanguage/Extension_talk:Chart/Project|project’s talk page on Mediawiki.org]], or ping me directly under this thread. If you encounter issues using Charts once it gets enabled on your wiki, please report it on the [[:mw:Extension_talk:Chart/Project|talk page]] or at [[phab:tag/charts|Phabricator]]. Thank you in advance! -- [[User:Sannita (WMF)|User:Sannita (WMF)]] ([[User talk:Sannita (WMF)|talk]]) 6 mai 2025 à 17:07 (CEST) <!-- Message envoyé par User:Sannita (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=User:Sannita_(WMF)/Mass_sending_test&oldid=28663781 --> == Actualités techniques n° 2025-20 == <section begin="technews-2025-W20"/><div class="plainlinks"> Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2025/20|D’autres traductions]] sont disponibles. '''En lumière cette semaine''' * Le lien [[m:Special:MyLanguage/Wikimedia URL Shortener|« Obtenir une URL raccourcie »]] dans la barre latérale inclut désormais un [[phab:T393309|code QR]]. Les utilisateurs des sites Wikimedia peuvent maintenant l’utiliser en le scannant ou en le téléchargeant pour partager et accéder rapidement au contenu partagé des sites Wikimedia, de manière pratique. '''Actualités pour la contribution''' * La Wikimedia Foundation travaille sur un système appelé [[m:Edge Uniques|« ''Edge Uniques'' »]], qui permettra de réaliser des [[w:en:A/B testing|tests A/B]], d’aider à se protéger contre les [[w:en:Denial-of-service attack|attaques par déni de service distribué]] (attaques DDoS), et de mieux comprendre combien de visiteurs les sites Wikimedia reçoivent. Cela vise à construire plus efficacement des outils utiles aux lecteurs, et de les aider à trouver ce qu'ils cherchent. Les Actualités techniques en ont [[m:Special:MyLanguage/Tech/News/2025/16|déjà parlé]]. Le déploiement sera progressif. Certains pourraient voir le cookie « ''Edge Uniques'' » à partir de la semaine du 19 mai. Vous pouvez en discuter sur la [[m:Talk:Edge Uniques|page de discussion]]. * À partir du 19 mai 2025, les organisateurs d’événements sur les wikis disposant de l’[[mw:Special:MyLanguage/Help:Extension:CampaignEvents|extension « CampaignEvents »]] pourront utiliser l’[[m:Special:MyLanguage/Event Center/Registration|inscription aux événements]] dans l’espace de noms du projet (par exemple, l’espace Wikipédia, l’espace Wikidata). Avec ce changement, les communautés n’ont plus besoin d’administrateurs pour utiliser cette fonctionnalité. Toutefois, les wikis qui ne souhaitent pas ce changement peuvent retirer et ajouter les espaces de noms autorisés sur [[Special:CommunityConfiguration/CampaignEvents]]. * Le projet Wikipédia dispose désormais d’un {{int:project-localized-name-group-wikipedia/fr}} en [[d:Q36720|nupe]] ([[w:nup:|<code>w:nup:</code>]]). Il s’agit d’une langue principalement parlée dans la région du centre-nord du Nigeria. Les locuteurs de cette langue sont invités à contribuer à la [[w:nup:Tatacin feregi|nouvelle Wikipédia]]. * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:27|la tâche soumise|les {{formatnum:27}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:27||s}} la semaine dernière]]. '''Actualités pour la contribution technique''' * Les développeurs peuvent désormais accéder à la Wikipédia néerlandaise pré-analysée, parmi d’autres (anglais, allemand, français, espagnol, italien et portugais), via les [https://enterprise.wikimedia.com/docs/snapshot/#structured-contents-snapshot-bundle-info-beta instantanés « ''Structured Contents'' » (bêta)]. Le contenu comprend des résumés Wikipédia analysés, des descriptions, des images principales, des infoboxes, des sections d’articles et des références. * Le point de terminaison de l’API REST <code dir="ltr">/page/data-parsoid</code> n’est plus utilisé et sera obsolète. Il est [[phab:T393557|prévu qu’il soit désactivé]] le 7 juin 2025. * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.45/wmf.1|MediaWiki]] '''En détails''' * Le [https://wikitech.wikimedia.org/wiki/News/2025_Cloud_VPS_VXLAN_IPv6_migration support IPv6] est un nouveau réseau virtuel Cloud qui améliore considérablement l’évolutivité, la sécurité et la préparation des plateformes Wikimedia pour l’avenir. Si vous êtes un contributeur technique curieux d’en savoir plus, consultez [https://techblog.wikimedia.org/2025/05/06/wikimedia-cloud-vps-ipv6-support/ ce billet de blogue] pour un aperçu détaillé de la transition vers l’IPv6. '''Rencontres et évènements''' * La deuxième édition de 2025 de [[m:Special:MyLanguage/Afrika Baraza|« Afrika Baraza »]], une plateforme virtuelle permettant aux Wikimédiens africains de se connecter, aura lieu le [https://zonestamp.toolforge.org/1747328400 15 mai à 17 h UTC]. Cette édition sera axée sur des discussions concernant la [[m:Special:MyLanguage/Wikimedia Foundation Annual Plan/2025-2026|planification annuelle et les avancées de Wikimedia]]. * La [[m:Special:MyLanguage/MENA Connect Community Call|« ''MENA Connect Community Call'' »]], une réunion virtuelle permettant aux Wikimédiens de la [[w:fr:MENA|région Moyen-Orient et Afrique du Nord]] (MENA) de se rencontrer, aura lieu le [https://zonestamp.toolforge.org/1747501200 17 mai à 17 h UTC]. Vous pouvez [[m:Event:MENA Connect (Wiki_Diwan) APP Call|vous inscrire dès maintenant]] pour y assister. '''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2025/20|Traduire]]&nbsp;• [[m:Tech|Obtenir de l’aide]]&nbsp;• [[m:Talk:Tech/News|Donner son avis]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].'' </div><section end="technews-2025-W20"/> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 13 mai 2025 à 00:37 (CEST) <!-- Message envoyé par User:UOzurumba (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=28714188 --> == Appel aux candidatures pour le Comité de Coordination du Code de Conduite Universel (U4C). == <section begin="announcement-content" /> Les résultats du vote sur les directives d'application et la charte du Comité de Coordination du Code de Conduite Universel (U4C) sont disponibles [[m:Special:MyLanguage/Universal Code of Conduct/Annual review/2025#Results|sur Méta-wiki]]. Vous pouvez désormais [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Election/2025/Candidates|soumettre votre candidature pour siéger à l'U4C]] <s>à partir du 29 mai 2025 à 12:00 UTC</s>. Des informations sur [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Election/2025|l'éligibilité, le processus, et la chronologie sont disponibles sur Méta-wiki]]. Le vote sur les candidats sera ouvert le 1<sup>er</sup> juin 2025 et durera deux semaines, se finissant donc le 15 juin 2025 à 12:00 UTC. Si vous avez des questions, vous pouvez les poser sur [[m:Talk:Universal Code of Conduct/Coordinating Committee/Election/2025|la page de discussion pour l'élection]]. -- en coopération avec l'U4C, </div><section end="announcement-content" /> <bdi lang="en" dir="ltr">[[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User_talk:Keegan (WMF)|discussion]])</bdi> 16 mai 2025 à 00:06 (CEST) <!-- Message envoyé par User:Keegan (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=28618011 --> :Rectification : Vous pouvez désormais [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Election/2025/Candidates|soumettre votre candidature pour siéger à l'U4C]] du 14 mai au 28 mai. :{{BlocCitation|You can submit your candidacy from May 14 until May 28, 2025}} :--&nbsp;◄&nbsp;[[Utilisateur:DavidL|'''D'''avid&nbsp;'''L''']]&nbsp;•&nbsp;[[Discussion Utilisateur:DavidL|discuter]]&nbsp;► 16 mai 2025 à 16:36 (CEST) == <span lang="en" dir="ltr">Tech News: 2025-21</span> == <div lang="en" dir="ltr"> <section begin="technews-2025-W21"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2025/21|Translations]] are available. '''Weekly highlight''' * The Editing Team and the Machine Learning Team are working on a new check for newcomers: [[mw:Edit check/Peacock check|Peacock check]]. Using a prediction model, this check will encourage editors to improve the tone of their edits, using artificial intelligence. We invite volunteers to review the first version of the Peacock language model for the following languages: Arabic, Spanish, Portuguese, English, and Japanese. Users from these wikis interested in reviewing this model are [[mw:Edit check/Peacock check/model test|invited to sign up at MediaWiki.org]]. The deadline to sign up is on May 23, which will be the start date of the test. '''Updates for editors''' * From May 20, 2025, [[m:Special:MyLanguage/Oversight policy|oversighters]] and [[m:Special:MyLanguage/Meta:CheckUsers|checkusers]] will need to have their accounts secured with two-factor authentication (2FA) to be able to use their advanced rights. All users who belong to these two groups and do not have 2FA enabled have been informed. In the future, this requirement may be extended to other users with advanced rights. [[m:Special:MyLanguage/Mandatory two-factor authentication for users with some extended rights|Learn more]]. * [[File:Octicons-gift.svg|12px|link=|class=skin-invert|Wishlist item]] [[m:Special:MyLanguage/Community Wishlist Survey 2023/Multiblocks|Multiblocks]] will begin mass deployment by the end of the month: all non-Wikipedia projects plus Catalan Wikipedia will adopt Multiblocks in the week of May 26, while all other Wikipedias will adopt it in the week of June 2. Please [[m:Talk:Community Wishlist Survey 2023/Multiblocks|contact the team]] if you have concerns. Administrators can test the new user interface now on your own wiki by browsing to [{{fullurl:Special:Block|usecodex=1}} {{#special:Block}}?usecodex=1], and can test the full multiblocks functionality [[testwiki:Special:Block|on testwiki]]. Multiblocks is the feature that makes it possible for administrators to impose different types of blocks on the same user at the same time. See the [[mw:Special:MyLanguage/Help:Manage blocks|help page]] for more information. [https://phabricator.wikimedia.org/T377121] * Later this week, the [[{{#special:SpecialPages}}]] listing of almost all special pages will be updated with a new design. This page has been [[phab:T219543|redesigned]] to improve the user experience in a few ways, including: The ability to search for names and aliases of the special pages, sorting, more visible marking of restricted special pages, and a more mobile-friendly look. The new version can be [https://meta.wikimedia.beta.wmflabs.org/wiki/Special:SpecialPages previewed] at Beta Cluster now, and feedback shared in the task. [https://phabricator.wikimedia.org/T219543] * The [[mw:Special:MyLanguage/Extension:Chart|Chart extension]] is being enabled on more wikis. For a detailed list of when the extension will be enabled on your wiki, please read the [[mw:Special:MyLanguage/Extension:Chart/Project#Deployment Timeline|deployment timeline]]. * [[f:Special:MyLanguage/Wikifunctions:Main Page|Wikifunctions]] will be deployed on May 27 on five Wiktionaries: [[wikt:ha:|Hausa]], [[wikt:ig:|Igbo]], [[wikt:bn:|Bengali]], [[wikt:ml:|Malayalam]], and [[wikt:dv:|Dhivehi/Maldivian]]. This is the second batch of deployment planned for the project. After deployment, the projects will be able to call [[f:Special:MyLanguage/Wikifunctions:Introduction|functions from Wikifunctions]] and integrate them in their pages. A function is something that takes one or more inputs and transforms them into a desired output, such as adding up two numbers, converting miles into metres, calculating how much time has passed since an event, or declining a word into a case. Wikifunctions will allow users to do that through a simple call of [[f:Special:MyLanguage/Wikifunctions:Catalogue|a stable and global function]], rather than via a local template. * Later this week, the Wikimedia Foundation will publish a hub for [[diffblog:2024/07/09/on-the-value-of-experimentation/|experiments]]. This is to showcase and get user feedback on product experiments. The experiments help the Wikimedia movement [[diffblog:2023/07/13/exploring-paths-for-the-future-of-free-knowledge-new-wikipedia-chatgpt-plugin-leveraging-rich-media-social-apps-and-other-experiments/|understand new users]], how they interact with the internet and how it could affect the Wikimedia movement. Some examples are [[m:Special:MyLanguage/Future Audiences/Generated Video|generated video]], the [[m:Special:MyLanguage/Future Audiences/Roblox game|Wikipedia Roblox speedrun game]] and [[m:Special:MyLanguage/Future Audiences/Discord bot|the Discord bot]]. * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:29}} community-submitted {{PLURAL:29|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, there was a bug with creating an account using the API, which has now been fixed. [https://phabricator.wikimedia.org/T390751] '''Updates for technical contributors''' * Gadgets and user scripts that interact with [[{{#special:Block}}]] may need to be updated to work with the new [[mw:Special:MyLanguage/Help:Manage blocks|manage blocks interface]]. Please review the [[mw:Help:Manage blocks/Developers|developer guide]] for more information. If you need help or are unable to adapt your script to the new interface, please let the team know on the [[mw:Help talk:Manage blocks/Developers|talk page]]. [https://phabricator.wikimedia.org/T377121] * The <code dir=ltr>mw.title</code> object allows you to get information about a specific wiki page in the [[w:en:Wikipedia:Lua|Lua]] programming language. Starting this week, a new property will be added to the object, named <code dir=ltr>isDisambiguationPage</code>. This property allows you to check if a page is a disambiguation page, without the need to write a custom function. [https://phabricator.wikimedia.org/T71441] * [[File:Octicons-tools.svg|15px|link=|class=skin-invert|Advanced item]] User script developers can use a [[toolforge:gitlab-content|new reverse proxy tool]] to load javascript and css from [[gitlab:|gitlab.wikimedia.org]] with <code dir=ltr>mw.loader.load</code>. The tool's author hopes this will enable collaborative development workflows for user scripts including linting, unit tests, code generation, and code review on <bdi lang="zxx" dir="ltr">gitlab.wikimedia.org</bdi> without a separate copy-and-paste step to publish scripts to a Wikimedia wiki for integration and acceptance testing. See [[wikitech:Tool:Gitlab-content|Tool:Gitlab-content on Wikitech]] for more information. * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.45/wmf.2|MediaWiki]] '''Meetings and events''' * The 12th edition of [[m:Special:MyLanguage/Wiki Workshop 2025|Wiki Workshop 2025]], a forum that brings together researchers that explore all aspects of Wikimedia projects, will be held virtually on 21-22 May. Researchers can [https://pretix.eu/wikimedia/wikiworkshop2025/ register now]. '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2025/21|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2025-W21"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 20 mai 2025 à 01:12 (CEST) <!-- Message envoyé par User:Quiddity (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=28724712 --> == RfC ongoing regarding Abstract Wikipedia (and your project) == <div lang="en" dir="ltr" class="mw-content-ltr"> ''(Apologies for posting in English, if this is not your first language)'' Hello all! We opened a discussion on Meta about a very delicate issue for the development of [[:m:Special:MyLanguage/Abstract Wikipedia|Abstract Wikipedia]]: where to store the abstract content that will be developed through functions from Wikifunctions and data from Wikidata. Since some of the hypothesis involve your project, we wanted to hear your thoughts too. We want to make the decision process clear: we do not yet know which option we want to use, which is why we are consulting here. We will take the arguments from the Wikimedia communities into account, and we want to consult with the different communities and hear arguments that will help us with the decision. The decision will be made and communicated after the consultation period by the Foundation. You can read the various hypothesis and have your say at [[:m:Abstract Wikipedia/Location of Abstract Content|Abstract Wikipedia/Location of Abstract Content]]. Thank you in advance! -- [[User:Sannita (WMF)|Sannita (WMF)]] ([[User talk:Sannita (WMF)|<span class="signature-talk">{{int:Talkpagelinktext}}</span>]]) 22 mai 2025 à 17:26 (CEST) </div> <!-- Message envoyé par User:Sannita (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=User:Sannita_(WMF)/Mass_sending_test&oldid=28768453 --> == Actualités techniques n° 2025-22 == <section begin="technews-2025-W22"/><div class="plainlinks"> Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2025/22|D’autres traductions]] sont disponibles. '''En lumière cette semaine''' * Une discussion communautaire à l’échelle du mouvement est désormais ouverte sur Meta au sujet d’un point très délicat pour le développement de [[m:Special:MyLanguage/Abstract Wikipedia|« Abstract Wikipedia »]] : où stocker le contenu abstrait qui sera développé à partir des fonctions de Wikifunctions et des données de Wikidata. La discussion est ouverte jusqu’au 12 juin sur [[m:Special:MyLanguage/Abstract Wikipedia/Location of Abstract Content|Abstract Wikipedia/Location of Abstract Content]], et tous les avis sont les bienvenus. La décision sera prise et communiquée par la Fondation à l’issue de la période de consultation. '''Actualités pour la contribution''' * Depuis la semaine dernière, sur tous les wikis excepté [[phab:T388604|les vingt plus grands]], les utilisateurs de l’éditeur visuel mobile disposent de [[phab:T385851|nouveaux outils dans la barre de menu]], accessibles via le nouveau bouton de la barre d’outils <code>+</code>. Pour commencer, le nouveau menu proposera des options pour ajouter : des références, des hiéroglyphes et des blocs de code. Le déploiement sur les autres wikis est [[phab:T388605|prévu]] pour le mois de juin. * [[File:Octicons-tools.svg|12px|link=|class=skin-invert|Sujet technique]] La fonction d’analyse <code dir=ltr>[[mw:Special:MyLanguage/Help:Extension:ParserFunctions##ifexist|#ifexist]]</code> ne créera plus de lien vers sa page cible. Cela améliorera l’utilité de [[{{#special:WantedPages}}]], qui ne listera à terme que les pages réellement ciblées par un lien rouge. Ce changement se fera progressivement à mesure que les pages sources seront mises à jour. [https://phabricator.wikimedia.org/T14019] * Cette semaine, l’équipe des outils de modération va lancer [[mw:Special:MyLanguage/2025 RecentChanges Language Agnostic Revert Risk Filtering|un nouveau filtre dans les modifications récentes]], en commençant par la Wikipédia en indonésien. Ce nouveau filtre met en évidence les modifications susceptibles d’être annulées. L’objectif est d’aider les patrouilleurs des modifications récentes à repérer les contributions potentiellement problématiques. D’autres wikis bénéficieront de ce filtre à l’avenir. * Lorsqu’ils cliquent sur une barre de recherche vide, les utilisateurs non connectés verront des suggestions d’articles à lire. Cette fonctionnalité sera disponible à la fois sur ordinateur et sur mobile. Les lecteurs des Wikipédias en catalan, hébreu et italien ainsi que de certains projets frères recevront ce changement entre le 21 mai et la mi-juin. Les lecteurs des autres wikis le recevront plus tard. L’objectif est d’encourager les utilisateurs à lire davantage les wikis. [[mw:Special:MyLanguage/Reading/Web/Content Discovery Experiments/Search Suggestions|En savoir plus]]. * Certains utilisateurs de l’application Wikipédia sur Android peuvent utiliser une nouvelle fonctionnalité destinée aux lecteurs : [[mw:Special:MyLanguage/Wikimedia Apps/Team/Android/TrivaGame|« WikiGames »]], un jeu quotidien de quiz basé sur des événements historiques réels. Le déploiement a commencé sous forme de test A/B, disponible pour 50 % des utilisateurs dans les langues suivantes : anglais, français, portugais, russe, espagnol, arabe, chinois et turc. * L’[[mw:Special:MyLanguage/Extension:Newsletter|extension « Newsletter »]] disponible sur MediaWiki.org permet la création de [[mw:Special:Newsletters|divers bulletins d’information]] à destination des utilisateurs de tous les wikis. L’extension peut désormais publier de nouveaux numéros sous forme de liens vers des sections sur une page existante, au lieu de nécessiter une nouvelle page pour chaque numéro. [https://phabricator.wikimedia.org/T393844] * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:32|la tâche soumise|les {{formatnum:32}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:32||s}} la semaine dernière]]. '''Actualités pour la contribution technique''' * Les champs <code dir=ltr>[[mw:Special:MyLanguage/Manual:Ipblocks table|ipblocks]]</code>, précédemment déclarés obsolètes, seront supprimés début juin dans les [[wikitech:Help:Wiki Replicas|Wiki Replicas]]. Il est recommandé aux utilisateurs d’interroger les nouveaux champs <code dir=ltr>[[mw:Special:MyLanguage/Manual:Block table|block]]</code> et <code dir=ltr>[[mw:Special:MyLanguage/Manual:Block target table|block_target]]</code> à la place. * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.45/wmf.3|MediaWiki]] '''Rencontres et évènements''' * [[d:Special:MyLanguage/Event:Wikidata and Sister Projects|« Wikidata et les projets frères »]] est un événement en ligne de plusieurs jours qui portera sur l’intégration de Wikidata à Wikipédia et aux autres projets Wikimedia. L’événement se déroulera du 29 mai au 1<sup>er</sup> juin. Vous pouvez [[d:Special:MyLanguage/Event:Wikidata and Sister Projects#Sessions|consulter le programme]] et [[d:Special:RegisterForEvent/1291|vous inscrire]]. '''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2025/22|Traduire]]&nbsp;• [[m:Tech|Obtenir de l’aide]]&nbsp;• [[m:Talk:Tech/News|Donner son avis]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].'' </div><section end="technews-2025-W22"/> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 26 mai 2025 à 22:04 (CEST) <!-- Message envoyé par User:UOzurumba (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=28788673 --> == Sélection 2025 du conseil d'administration de la fondation Wikimédia et appel à questions == <section begin="announcement-content" /> :''[[m:Special:MyLanguage/Wikimedia Foundation elections/2025/Announcement/Selection announcement|{{int:interlanguage-link-mul}}]] • [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:Wikimedia Foundation elections/2025/Announcement/Selection announcement}}&language=&action=page&filter= {{int:please-translate}}]'' Chers tous et toutes, Cette année, le mandat de deux administrateurs sélectionnés par la communauté et les affiliés au conseil d'administration de la Fondation Wikimédia prendra fin [1]. Le conseil invite l'ensemble du mouvement à participer au processus de sélection de cette année et à voter pour pourvoir ces sièges. Le Comité des élections supervisera ce processus avec le soutien du personnel de la Fondation [2]. Le Comité de gouvernance, composé de membres du Conseil d'administration non-candidats au processus de sélection des membres du Conseil d'administration 2025 sélectionnés par la communauté et les affiliés (Raju Narisetti, Shani Evenstein Sigalov, Lorenzo Losa, Kathy Collins, Victoria Doronina et Esra'a Al Shafei) [3], est chargé de superviser le processus de sélection des membres du Conseil d'administration 2025 et de tenir le Conseil d'administration au courant de la situation. Pour plus de détails sur les rôles de la commission des élections, du conseil d'administration et du personnel, cliquez ici [4]. En voici les dates clés : * 22 mai - 5 juin : Annonce ( la présente communication) et période d'appel à questions. [6] * 17 juin - 1er juillet 2025 : Appel à candidatures * Juillet 2025 : Si nécessaire, les affiliés votent pour présélectionner les candidats si 10 d'entre eux ou plus se présentent [5]. * Août 2025 : Période de la campagne * Août - septembre 2025 : Période de vote communautaire de deux semaines * Octobre - novembre 2025 : Vérification des antécédents des candidats sélectionnés * Réunion du conseil d'administration en décembre 2025 : Installation des nouveaux membres du conseil d'administration Pour en savoir plus sur le processus de sélection de 2025 - y compris le calendrier détaillé, le processus de candidature, les règles de la campagne et les critères d'éligibilité des électeurs -, veuillez consulter cette page Meta-wiki. [[m:Special:MyLanguage/Wikimedia_Foundation_elections/2025|[link]]]. '''Appel à questions''' Lors de chaque processus de sélection, la communauté a la possibilité de soumettre des questions auxquelles les candidats au conseil d'administration devront répondre. Le comité électoral sélectionne les questions à partir de la liste établie par la communauté pour que les candidats y répondent. Les candidats doivent répondre à toutes les questions posées dans le dossier de candidature pour être éligibles, faute de quoi leur candidature sera rejetée. Cette année, le comité électoral sélectionnera 5 questions auxquelles les candidats devront répondre. Les questions sélectionnées peuvent être une combinaison de celles qui ont été soumises par la communauté, si elles sont similaires ou liées. [[m:Special:MyLanguage/Wikimedia_Foundation_elections/2025/Questions_for_candidates|[link]]] '''Bénévoles des élections''' Une autre façon de participer au processus de sélection de 2025 est de devenir bénévole des élections. Les bénévoles électoraux constituent un pont entre le comité électoral et leur communauté respective. Ils veillent à ce que leur communauté soit représentée et les incitent à voter. Pour en savoir plus sur le programme et les modalités d'adhésion, consultez cette page Meta-wiki. [[m:Wikimedia_Foundation_elections/2025/Election_volunteers|[link]]]. Je vous remercie ! [1] https://meta.wikimedia.org/wiki/Wikimedia_Foundation_elections/2022/Results [2] https://foundation.wikimedia.org/wiki/Committee:Elections_Committee_Charter [3] https://foundation.wikimedia.org/wiki/Resolution:Committee_Membership,_December_2024 [4] https://meta.wikimedia.org/wiki/Wikimedia_Foundation_elections_committee/Roles [5] https://meta.wikimedia.org/wiki/Wikimedia_Foundation_elections/2025/FAQ [6] https://meta.wikimedia.org/wiki/Wikimedia_Foundation_elections/2025/Questions_for_candidates Bien à vous, Victoria Doronina Liaison du conseil d'administration avec le comité des élections Comité de gouvernance<section end="announcement-content" /> [[Utilisateur:MediaWiki message delivery|MediaWiki message delivery]] ([[Discussion utilisateur:MediaWiki message delivery|discussion]]) 28 mai 2025 à 05:07 (CEST) <!-- Message envoyé par User:RamzyM (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=28618011 --> == Actualités techniques n° 2025-23 == <section begin="technews-2025-W23"/><div class="plainlinks"> Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2025/23|D’autres traductions]] sont disponibles. '''En lumière cette semaine''' * L'[[mw:Special:MyLanguage/Extension:Chart|extension Chart]] est maintenant disponible sur tous les wikis Wikimedia. Les éditeurs peuvent utiliser cette nouvelle extension pour créer des visualisations de données interactives comme des diagrammes à barres, à lignes, avec des zones, et circulaires. Chart a été créée pour remplacer la plupart des utilisations de l'ancienne [[mw:Special:MyLanguage/Extension:Graph|extension Graph]]. '''Actualités pour la contribution''' * Il est maintenant plus simple de configurer les citations automatiques pour votre wiki dans le [[mw:Special:MyLanguage/Citoid/Enabling Citoid on your wiki|générateur de citations]] de l'éditeur visuel. Les administrateurs peuvent maintenant définir un modèle par défaut en utilisant la clé <code dir=ltr>_default</code> dans la page locale <bdi lang="en" dir="ltr">[[MediaWiki:Citoid-template-type-map.json]]</bdi> ([[mw:Special:Diff/6969653/7646386|exemple de modification]]). Définir ce réglage par défaut permettra aussi de pérenniser vos configurations existantes lorsque de [[phab:T347823|nouveaux types d'objets]] seront ajoutés à l'avenir. Vous pouvez toujours définir des modèles pour des types d'objets individuels et ils seront prioritaires par rapport au modèle par défaut. [https://phabricator.wikimedia.org/T384709] * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:20|la tâche soumise|les {{formatnum:20}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:20||s}} la semaine dernière]]. '''Actualités pour la contribution technique''' * À partir de la semaine du 2 juin, les robots qui utilisent <code dir=ltr>action=login</code> ou <code dir=ltr>action=clientlogin</code> pour s'authentifier auront un taux d'échec plus fréquent. Cela est dû à des protections plus fortes contre les connexions suspectes. Les robots qui utilisent des [[mw:Special:MyLanguage/Manual:Bot passwords|mots de passe de robots]] ou une authentification sans connexion telle que [[mw:Special:MyLanguage/OAuth/Owner-only consumers|OAuth]] ne seront pas affectés. Si votre bot n'utilise aucun des deux, vous devriez le mettre à jour ; utiliser <code dir=ltr>action=login</code> sans un mot de passe de robot a été rendu désuet [[listarchive:list/wikitech-l@lists.wikimedia.org/message/3EEMN7VQX5G7WMQI5K2GP5JC2336DPTD/|en 2016]]. Pour la plupart des robots, cela nécessite seulement de changer quel mot de passe ce dernier utilise. [https://phabricator.wikimedia.org/T395205] * À partir de cette semaine, les wikis Wikimedia permettront des fonctionnalités ES2017 dans le code JavaScript pour le code officiel, les gadgets et les scripts utilisateurs. La fonctionnalité la plus visible d'ES2017 est la syntaxe <bdi lang="zxx" dir="ltr"><code>async</code>/<code>await</code></bdi>, ce qui permet un code plus facile à lire. Jusqu'à cette semaine, la plateforme ne permettait que jusqu'à ES2016, et quelques mois plus tôt, jusqu'à ES2015. [https://phabricator.wikimedia.org/T381537] * [[File:Octicons-sync.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.45/wmf.4|MediaWiki]] '''Rencontres et évènements''' * Les demandes de bourse d'études pour participer à la [[m:Special:MyLanguage/GLAM Wiki 2025|conférence GLAM 2025]] sont maintenant ouvertes. La conférence aura lieu du 30 octobre au 1er novembre, à Lisbonne, au Portugal. Les contributeurs GLAM qui n'ont pas les moyens de financer leur participation peuvent [[m:Special:MyLanguage/GLAM Wiki 2025/Scholarships|faire une demande ici]]. La date limite de candidature est le 7 juin. '''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2025/23|Traduire]]&nbsp;• [[m:Tech|Obtenir de l’aide]]&nbsp;• [[m:Talk:Tech/News|Donner son avis]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].'' </div><section end="technews-2025-W23"/> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 3 juin 2025 à 01:54 (CEST) <!-- Message envoyé par User:Quiddity (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=28819186 --> qgex8flrsb47gflskeqyjz3562vdqeh Wikilivres:Requêtes aux administrateurs/2025 4 82066 744185 742838 2025-06-05T23:24:39Z Samuele2002 53231 /* Vandalism user:Sophiedecaen140 */ nouvelle section 744185 wikitext text/x-wiki {{Wikilivres:Groupes}} {{Wikilivres:Requêtes aux administrateurs/En-tête}} == Transfert WIKIPEDIA --> WIKILIVRES == Bonjour j'ai écris une page récemment dans WIKIPEDIA sur le mini-shogi. On m'a demandé de faire un transfert dans WIKILIVRES; car cet article n'est pas de nature encyclopédique. J'ai modifié l’Entêté de la page avec {{Pour Wikibooks}}. Je dois ensuite demander un transfert de la page vers WIKILIVRES à un administrateur mais je n'ai pas trouvé comment faire. Je voudrais donc connaitre la procédure à suivre. Merci [[Utilisateur:Didier1963|Didier1963]] ([[Discussion utilisateur:Didier1963|discussion]]) 16 janvier 2025 à 13:02 (CET) :Bonjour Didier1963, :Il suffit juste de faire une demande ici. :Le transfert est en cours. :--&nbsp;◄&nbsp;[[Utilisateur:DavidL|'''D'''avid&nbsp;'''L''']]&nbsp;•&nbsp;[[Discussion Utilisateur:DavidL|discuter]]&nbsp;► 18 janvier 2025 à 11:42 (CET) ::La page a été importée ici : [[Utilisateur:Didier1963/Brouillon]] ::Pour en faire un livre, il faut diviser le contenu en plusieurs pages wiki (chapitres) liées à la page principale de présentation du livre. ::* Voir [[Wikilivres:Conventions sur les titres]] et [[Wikilivres/Organisation d'un wikilivre]] ::* Exemple de livres similaires : [[Jeu de Go]], [[Jeu de rôle sur table — Jouer, créer]] ::--&nbsp;◄&nbsp;[[Utilisateur:DavidL|'''D'''avid&nbsp;'''L''']]&nbsp;•&nbsp;[[Discussion Utilisateur:DavidL|discuter]]&nbsp;► 18 janvier 2025 à 11:52 (CET) :::Bonjour, on m'a pingué sur Wikipédia en parallèle et j'avais importé cette page ici en parallèle : [[Mini-shōgi]]. Du coup j'ai supprimé le brouillon. [[Utilisateur:JackPotte|JackPotte]] ([[Discussion utilisateur:JackPotte|<span style="color:#FF6600">$</span>♠]]) 19 janvier 2025 à 11:36 (CET) ::::Bonjour ::::je n'arrive pas a comprendre le fonctionnement de ma demande de transfert de ma page WKIPEDIA dans Didier1963/Brouillon "mini-shogi" ::::En premier lieu, j'a été "signalé" (par vous apparent) à cause d'un brouillon "gâteau aux excréments" apparu dans mes sessions .Que signifie exactement cette notion de "signalement" ? ::::Cette 'fausse" page est bien sur ridicule,.... Je ne suis n"y absolument pour rien, c'est-ce un vandalisme délibéré (par qu)i ?; mais je 'ai pas su tout traiter cette brutale intrusion, sinon de reprendre la rédaction de mon brouillon.... ::::Comment se fait-il qu'il soit possible de vandaliser un brouillon qui par nature n'est pas public ? ::::En second lieu, suite a un avis reçu de WKIPEDIA j'ai demandé de transfert de mon article dans WIKILIVRE ::::il me semble avoir compris que le transfert avait été fait mais la page aussitôt supprimée (par vous apparent) ? ::::Si c'est bien ça , il est assez inadmissible (et incompréhensible) de procéder ainsi sans explications et sans aide. ::::s'il y a un problème de rédaction ou de forme, il suffit de l’écrire et éventuellement d'indiquer comment faire, surtout pour les débutants comme moi ::::cordialement [[Utilisateur:Didier1963|Didier1963]] ([[Discussion utilisateur:Didier1963|discussion]]) 22 janvier 2025 à 23:05 (CET) :::::je me répond à moi même... :::::j'ai finalement trouvé la page transférée de WIKIPEDIA vers WIKILIVRE en passant par le moteur de recherche. :::::je remercie les intervenants car j'en déduit que, finalement, tout s'est bien passé. :::::cordialement [[Utilisateur:Didier1963|Didier1963]] ([[Discussion utilisateur:Didier1963|discussion]]) 24 janvier 2025 à 22:31 (CET) {{État de la requête|état=traitée}} == Import du modèle:mesure de WP == '''Auteur :''' [[Utilisateur:Cdang|Cdang]] ([[Discussion utilisateur:Cdang|discussion]]) '''Date :''' 22 janvier 2025 à 09:40 (CET) '''Modèle :''' [[:modèle:chiffrage mesure]] '''Requête :''' Bonjour, serait-il possible d'importer le ''[[w:modèle:mesure]]'' pour remplacer l'actuel ''[[:modèle:chiffrage mesure]]'', bien moins complet ? Je préconise de garder le nom ''chiffrage mesure'', moins ambigu. Le ''modèle:chiffrage mesure'' est actuellement utilisé dans les wikilivres ''[[Introduction à LilyPond]]'', ''[[Formation musicale]]'' et ''[[LaTeX/Écrire de la musique]]''. {{État de la requête|état=traitée}} '''Discussions :''' :{{fait}} [[Utilisateur:JackPotte|JackPotte]] ([[Discussion utilisateur:JackPotte|<span style="color:#FF6600">$</span>♠]]) 26 janvier 2025 à 22:33 (CET) == Page Conjuguer au conditionnel présent == Bonjour, Je me présente, je m'appelle Nathalie BALON. Je suis logopède, psychopédagogue et formatrice en langage écrit (à savoir : orthographe, rédaction d'ouvrages, écriture thérapeutique et écrits professionnels). Par hasard, je suis "tombée" sur la page concernant la conjugaison au conditionnel présent, car je conseille parfois des blogs, sites, voire wikilivre ou wikipédia. Je n'ai pu m'empêcher de voir d'une part deux grosses erreurs qui font que la conjugaison sur cette page est fausse (cf. les deux premières personnes du pluriel). Quant aux exemples, ils sont également erronés, l'auteur n'ayant apparemment pas compris les modifications de la nouvelle grammaire qui permettent d'envisager, selon le sens de la phrase, le conditionnel soit comme un temps de l'indicatif, soit comme un mode à part entière. Dès lors, j'ai effectivement modifié la page de manière importante. La mention expliquant la raison de la non publication de ma mise à jour fait mention d'une modification d'un bloc trop important ; ce qui est exact, mais selon moi, nécessaire. Si vous le souhaitez, je peux recommencer les modifications afin que la page soit correcte, ou une autre personne peut s'en charger. Évidemment, en qualité d'administrateur, vous êtes juge pour décider de la suite. De mon côté, sans les modifications indispensables, je déconseillerai aux jeunes de consulter, en guise d'aide pour leur cours de français, les pages de wikilivre, car vous comprendrez aisément que ce ne serait pas une aide. En vous souhaitant une très belle fin de journée, veuillez agréer mes sentiments les meilleurs, Nathalie BALON nat.balon@skynet.be :Bonjour Nathalie, :Les paramètres du filtre ont été corrigés. :Désormais, les modifications devraient passer à condition d'utiliser des titres de sections avec la syntaxe standard (titre entre deux séries de égal de même quantité, comme pour cette page de discussion). :--&nbsp;◄&nbsp;[[Utilisateur:DavidL|'''D'''avid&nbsp;'''L''']]&nbsp;•&nbsp;[[Discussion Utilisateur:DavidL|discuter]]&nbsp;► 7 mai 2025 à 00:22 (CEST) == Vandalism [[user:Sophiedecaen140]] == '''Auteur :''' [[Utilisateur:Samuele2002|Samuele2002]] ([[Discussion utilisateur:Samuele2002|discussion]]) '''Date :''' 6 juin 2025 à 01:24 (CEST) '''utilisateur:''' [[user:Sophiedecaen140]] <!-- Ne gardez que la/les option(s) qui vous sont utiles. --> '''Requête :''' Sorry for english. Please block and delete page created by [[User:Sophiedecaen140]], cross-wiki Vandalism. Thanks. <!-- Remplacez cette ligne par votre requête. --> {{État de la requête|état=en attente}} '''Discussions :''' httnhf0mdo166je7kckwmcbijyfq4xj 744188 744185 2025-06-06T05:34:20Z JackPotte 5426 /* Vandalism user:Sophiedecaen140 */ 744188 wikitext text/x-wiki {{Wikilivres:Groupes}} {{Wikilivres:Requêtes aux administrateurs/En-tête}} == Transfert WIKIPEDIA --> WIKILIVRES == Bonjour j'ai écris une page récemment dans WIKIPEDIA sur le mini-shogi. On m'a demandé de faire un transfert dans WIKILIVRES; car cet article n'est pas de nature encyclopédique. J'ai modifié l’Entêté de la page avec {{Pour Wikibooks}}. Je dois ensuite demander un transfert de la page vers WIKILIVRES à un administrateur mais je n'ai pas trouvé comment faire. Je voudrais donc connaitre la procédure à suivre. Merci [[Utilisateur:Didier1963|Didier1963]] ([[Discussion utilisateur:Didier1963|discussion]]) 16 janvier 2025 à 13:02 (CET) :Bonjour Didier1963, :Il suffit juste de faire une demande ici. :Le transfert est en cours. :--&nbsp;◄&nbsp;[[Utilisateur:DavidL|'''D'''avid&nbsp;'''L''']]&nbsp;•&nbsp;[[Discussion Utilisateur:DavidL|discuter]]&nbsp;► 18 janvier 2025 à 11:42 (CET) ::La page a été importée ici : [[Utilisateur:Didier1963/Brouillon]] ::Pour en faire un livre, il faut diviser le contenu en plusieurs pages wiki (chapitres) liées à la page principale de présentation du livre. ::* Voir [[Wikilivres:Conventions sur les titres]] et [[Wikilivres/Organisation d'un wikilivre]] ::* Exemple de livres similaires : [[Jeu de Go]], [[Jeu de rôle sur table — Jouer, créer]] ::--&nbsp;◄&nbsp;[[Utilisateur:DavidL|'''D'''avid&nbsp;'''L''']]&nbsp;•&nbsp;[[Discussion Utilisateur:DavidL|discuter]]&nbsp;► 18 janvier 2025 à 11:52 (CET) :::Bonjour, on m'a pingué sur Wikipédia en parallèle et j'avais importé cette page ici en parallèle : [[Mini-shōgi]]. Du coup j'ai supprimé le brouillon. [[Utilisateur:JackPotte|JackPotte]] ([[Discussion utilisateur:JackPotte|<span style="color:#FF6600">$</span>♠]]) 19 janvier 2025 à 11:36 (CET) ::::Bonjour ::::je n'arrive pas a comprendre le fonctionnement de ma demande de transfert de ma page WKIPEDIA dans Didier1963/Brouillon "mini-shogi" ::::En premier lieu, j'a été "signalé" (par vous apparent) à cause d'un brouillon "gâteau aux excréments" apparu dans mes sessions .Que signifie exactement cette notion de "signalement" ? ::::Cette 'fausse" page est bien sur ridicule,.... Je ne suis n"y absolument pour rien, c'est-ce un vandalisme délibéré (par qu)i ?; mais je 'ai pas su tout traiter cette brutale intrusion, sinon de reprendre la rédaction de mon brouillon.... ::::Comment se fait-il qu'il soit possible de vandaliser un brouillon qui par nature n'est pas public ? ::::En second lieu, suite a un avis reçu de WKIPEDIA j'ai demandé de transfert de mon article dans WIKILIVRE ::::il me semble avoir compris que le transfert avait été fait mais la page aussitôt supprimée (par vous apparent) ? ::::Si c'est bien ça , il est assez inadmissible (et incompréhensible) de procéder ainsi sans explications et sans aide. ::::s'il y a un problème de rédaction ou de forme, il suffit de l’écrire et éventuellement d'indiquer comment faire, surtout pour les débutants comme moi ::::cordialement [[Utilisateur:Didier1963|Didier1963]] ([[Discussion utilisateur:Didier1963|discussion]]) 22 janvier 2025 à 23:05 (CET) :::::je me répond à moi même... :::::j'ai finalement trouvé la page transférée de WIKIPEDIA vers WIKILIVRE en passant par le moteur de recherche. :::::je remercie les intervenants car j'en déduit que, finalement, tout s'est bien passé. :::::cordialement [[Utilisateur:Didier1963|Didier1963]] ([[Discussion utilisateur:Didier1963|discussion]]) 24 janvier 2025 à 22:31 (CET) {{État de la requête|état=traitée}} == Import du modèle:mesure de WP == '''Auteur :''' [[Utilisateur:Cdang|Cdang]] ([[Discussion utilisateur:Cdang|discussion]]) '''Date :''' 22 janvier 2025 à 09:40 (CET) '''Modèle :''' [[:modèle:chiffrage mesure]] '''Requête :''' Bonjour, serait-il possible d'importer le ''[[w:modèle:mesure]]'' pour remplacer l'actuel ''[[:modèle:chiffrage mesure]]'', bien moins complet ? Je préconise de garder le nom ''chiffrage mesure'', moins ambigu. Le ''modèle:chiffrage mesure'' est actuellement utilisé dans les wikilivres ''[[Introduction à LilyPond]]'', ''[[Formation musicale]]'' et ''[[LaTeX/Écrire de la musique]]''. {{État de la requête|état=traitée}} '''Discussions :''' :{{fait}} [[Utilisateur:JackPotte|JackPotte]] ([[Discussion utilisateur:JackPotte|<span style="color:#FF6600">$</span>♠]]) 26 janvier 2025 à 22:33 (CET) == Page Conjuguer au conditionnel présent == Bonjour, Je me présente, je m'appelle Nathalie BALON. Je suis logopède, psychopédagogue et formatrice en langage écrit (à savoir : orthographe, rédaction d'ouvrages, écriture thérapeutique et écrits professionnels). Par hasard, je suis "tombée" sur la page concernant la conjugaison au conditionnel présent, car je conseille parfois des blogs, sites, voire wikilivre ou wikipédia. Je n'ai pu m'empêcher de voir d'une part deux grosses erreurs qui font que la conjugaison sur cette page est fausse (cf. les deux premières personnes du pluriel). Quant aux exemples, ils sont également erronés, l'auteur n'ayant apparemment pas compris les modifications de la nouvelle grammaire qui permettent d'envisager, selon le sens de la phrase, le conditionnel soit comme un temps de l'indicatif, soit comme un mode à part entière. Dès lors, j'ai effectivement modifié la page de manière importante. La mention expliquant la raison de la non publication de ma mise à jour fait mention d'une modification d'un bloc trop important ; ce qui est exact, mais selon moi, nécessaire. Si vous le souhaitez, je peux recommencer les modifications afin que la page soit correcte, ou une autre personne peut s'en charger. Évidemment, en qualité d'administrateur, vous êtes juge pour décider de la suite. De mon côté, sans les modifications indispensables, je déconseillerai aux jeunes de consulter, en guise d'aide pour leur cours de français, les pages de wikilivre, car vous comprendrez aisément que ce ne serait pas une aide. En vous souhaitant une très belle fin de journée, veuillez agréer mes sentiments les meilleurs, Nathalie BALON nat.balon@skynet.be :Bonjour Nathalie, :Les paramètres du filtre ont été corrigés. :Désormais, les modifications devraient passer à condition d'utiliser des titres de sections avec la syntaxe standard (titre entre deux séries de égal de même quantité, comme pour cette page de discussion). :--&nbsp;◄&nbsp;[[Utilisateur:DavidL|'''D'''avid&nbsp;'''L''']]&nbsp;•&nbsp;[[Discussion Utilisateur:DavidL|discuter]]&nbsp;► 7 mai 2025 à 00:22 (CEST) == Vandalism [[user:Sophiedecaen140]] == '''Auteur :''' [[Utilisateur:Samuele2002|Samuele2002]] ([[Discussion utilisateur:Samuele2002|discussion]]) '''Date :''' 6 juin 2025 à 01:24 (CEST) '''utilisateur:''' [[user:Sophiedecaen140]] <!-- Ne gardez que la/les option(s) qui vous sont utiles. --> '''Requête :''' Sorry for english. Please block and delete page created by [[User:Sophiedecaen140]], cross-wiki Vandalism. Thanks. <!-- Remplacez cette ligne par votre requête. --> {{État de la requête|état=traitée}} '''Discussions :''' :Bonjour, [//fr.wikibooks.org/w/index.php?title=Sp%C3%A9cial:Journal&type=delete&page=Sophie+des+mjc+de+caen la page a été supprimée en global sysop]. [[Utilisateur:JackPotte|JackPotte]] ([[Discussion utilisateur:JackPotte|<span style="color:#FF6600">$</span>♠]]) 6 juin 2025 à 07:34 (CEST) pbzlxunzxz3t9cpds923whe84twz7kh Jeu de rôle sur table — Jouer, créer/Créer un jeu de rôle 0 82237 744047 742095 2025-06-03T15:30:26Z Cdang 1202 testez ! 744047 wikitext text/x-wiki <noinclude>{{NavTitre|book={{BASEPAGENAME}}|prev=Créer un univers|next=Abréviations}}</noinclude> Nous avons vu : * [[../Créer une nouvelle règle|comment créer des règles]] ; * [[../Créer un univers|comment créer un univers]] ; il est donc temps d'aborder la question de la création d'un jeu de rôle complet. == Processus global == Donc vous avez un groupe de joueurs et joueuses régulières. Vous avez joué des parties régulières, soit en développant une campagne, soit par des parties indépendantes mais avec une logique récurrente : type de parties, univers… Au fur et à mesure, vous avez développé un univers et créé des règles spécifiques pour avoir des moments de jeux intéressants. Vous avez donc… déjà créé votre jeu de rôle. Vous voulez alors peut-être le partager, le diffuser, voire le vendre. Ou alors : vous avez une idée de partie type et vous voulez créer un jeu pour concrétiser ce que vous avez en tête. Là, tout est à créer… == L'hygiène de l'écrivain == Pour tenir sur le long terme, vous pouvez prendre des bonnes habitudes d'écriture<ref>{{lien web |url=https://blog.lulu.com/6-writing-habits/ |titre=6 Writing Habits to Write More |auteur=paul |site=Lulu blog |date=2020-09-18 |consulté le2025-04-19 |lang=en}}.</ref> : # Écrivez chaque jour — chisissez un moment et respectez-le ! # Définissez des objectifs d'écriture — imposez-vous un nombre de mot à écrire chaque jour. # Dédiez du temps à l'écriture — réservez du temps, que ce soit 10 minutes ou une heure. # Un lieu, un lieu, un lieu — dédiez un lieu qui soit votre « espace d'écriture ». # Faite de l'édition plus tard — les fautes d'orthographe n'ont pas d'importance pour un premier jet. # Créez et surveillez des éléments mesurables — suivez votre progression et ajustez vos buts. {{...}} == Testez, testez, testez… == {{citation bloc |1=''À propos du ''Butin des Gobelins'' pour le jeu de rôle ''Coureurs d’orage.'' : C'est qui est intéressant (et nouveau en ce qui me concerne) c'est que je me retrouve dans une position « à la @Johan Scipion » (toutes proportions gardées) avec ce micro-scénar. : Cinquième fois que tu fais jouer la même proposition (règles + scénario), tu commences à repérer des trucs, des axes d'amélioration qui ne sautent pas forcément aux yeux sur seulement deux itérations (quand je playtestais mes modules ''CdO'', je les faisais jouer deux fois). : Bref tu augmentes encore sensiblement ton niveau d'affinage parce que tu commences a avoir en tête un catalogue de réactions possibles basé sur du concret, du vu-et-joué, pas de la supputation. : : C'est une expérience que je recommande aux MJ un peu exigeants et qui veulent bosser leur « métier ». — Islayre d'Argolh » mar. juin 03, 2025 1:45 pm : Complètement d'accord. Le replay : : :+ Est un super outil de ''game design''. :+ Bonifie la maîtrise donc l'expérience ludique de toute la table. :+ Est supra fun. : : Ce sont les raisons pour lesquelles je lui ai récemment consacré un numéro de ''Sombre'' : https://www.terresetranges.net/forums/viewtopic.php?pid=21690#p21690 — Johan Scipion » mar. juin 03, 2025 4:09 pm |3={{lien web |url=https://www.casusno.fr/viewtopic.php?p=2273179#p2273179 |titre=Re: Retours de partie : Il était une fois [Sondage en page 1]/Re: Sombre, la peur comme au cinéma |site=Casus Non Officiel |date=3 juin 2025 |consulté le=2025-06-03}} }} == Références == {{références}} ---- ''[[../Créer un univers/]]'' &lt; [[Jeu de rôle sur table — Jouer, créer|↑]] &gt; ''[[../Abréviations/]]'' {{DEFAULTSORT:Creer un jeu de role}} [[Catégorie:Jeu de rôle sur table — Jouer, créer (livre)]] jecfeuk4lzvjpudfostnh4ww1tkaep6 Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Les programmes wikipédien(ne) en residence 0 82274 744013 743917 2025-06-02T22:20:41Z LodestarChariot2 120009 /* Ouvrages citées */ 744013 wikitext text/x-wiki ''Cette observation a été rédigée par Caroline Winter et Talya Jesperson, pour le Electronic Textual Cultures Laboratory et le partenariat Implementing New Knowledge Environments.'' En règle générale, un wikipédien(ne)s en résidence sont des éditeurs de [https://fr.wikipedia.org/wiki/Wikip%C3%A9dia:Accueil_principal Wikipédia] qui agissent en tant que des liaisons entre la communauté Wikipédia et une institution, par exemple une université, un organisme de recherche, ou un galerie, bibliothèque, archive ou musée. Ces postes sont parfois connus sous le nom de wikimédien(ne) en résidence - faisant référence à l'organisation mère de Wikipédia, la [https://wikimediafoundation.org/ Wikimedia Foundation] - ou wikipédien(ne) résidents honoraires. Le premier wikipédien en résidence, Liam Wyatt, s'est porté volontaire avec le [https://www.britishmuseum.org/ British Museum] pour fournir des informations sur ses collections sur Wikipédia dans le but de rendre ses collections plus accessibles à la communauté élargie («&#8239;Wikipedians&#8239;» 2010; Cohen 2010). Depuis lors, [https://w.wiki/Cx6 plus de 200] d’entre eux sont en liaison avec un large éventail d'institutions à travers le monde, y compris des bibliothèques nationales, universitaires et locales; sociétés savantes; instituts et organisations de recherche; organisations intergouvernementales et à but non lucratif; organisations de médias; musées nationaux et locaux; archives nationales et spécialisées; et jardins botaniques («&#8239;Wikimedians&#8239;» 2020). Les postes peuvent prendre de nombreuses formes, allant des postes de bénévole à temps partiel à court terme à un emploi permanent à temps plein («&#8239;Wikimedians&#8239;» 2020; «&#8239;Wikipedians&#8239;» 2020). Les tâches d'un wikipédien(ne) en résidence comprennent souvent une combinaison des éléments suivants&nbsp;: * Formation, comme l’enseignement le personnel des établissements et les membres de la communauté comment contribuer à Wikipédia ou sur des questions pertinentes telles que les droits d'auteur et les licences ou la numérisation * Diriger des événements de sensibilisation tels que des edit-a-thons, au cours desquels les participants éditent et contribuent ensemble à Wikipédia ou à d'autres projets de la Fondation Wikimedia * Numérisation des collections ou des fonds, ajout des images à Wikimedia Commons et des métadonnées à Wikidata * Planification stratégique pour la sensibilisation et le partage des connaissances * Contribution d'informations à Wikipédia («&#8239;Wikimedia&#8239;» 2020; «&#8239;Wikipédia&#8239;» 2020) ==Programmes de Wikipédien(ne)s en résidence et la communauté INKE== En 2014, les bibliothèques de l’University of Victoria (UVic), l'Electronic Textual Cultures Lab (ETCL) et la Fédération des sciences humaines –– tous partenaires d'INKE –– ont annoncé le lancement d'un programme [https://etcl.uvic.ca/hrw/ wikipédien(ne) résident honoraire] à l'UVic. [https://www.ideas-idees.ca/media/media-releases/honorary-resident-wikipedian-professor-christian-vandendorpe Christian Vandendorpe] a été nommé premier Wikipédien résident honoraire de 2014 à 2016, suivi par membre du Partenariat INKE [https://www.uvic.ca/library/home/home/news/archive/Wikipedia-A-Thon.php Constance Crompton] de 2017 à 2018, [https://etcl.uvic.ca/2019/04/09/2019-20-honorary-resident-wikipedian-dr-erin-glass/ Erin Glass] de 2019 à 2020 et [https://etcl.uvic.ca/2020/10/08/2020-2021-honorary-resident-wikipedian-silvia-gutierrez-de-la-torre/ Silvia Gutiérrez De la Torre] de 2020 à 2021. Le projet Cultural Data / Data for Culture de Crompton, basé au Humanities + Data Lab de l’Université d’Ottawa, examine les projets Wikimedia en tant que plates-formes de connaissances ouvertes. Le projet appelle également la communauté universitaire à apporter ses connaissances aux projets Wikimedia, la source de données culturelles et humaines structurées plus grande au monde, et lisible par des humains et par des machines. Il note que Wikipédia et les autres projects de Wikimedia a besoin des spécialistes du sectueur universitaire également des éditeurs non spécialisés. La communauté universitaire peut aider a démocratiser ces connaissances et contribuer à ce que les utilisations basées sur les données de Wikimedia (The Humanities Data Lab s.d.). Crompton plaide en faveur de la valeur de la recherche Wikidata pour les sciences humaines dans «&#8239;[https://popjournal.ca/issue02/crompton Familiar Wikidata: The Case for Building a Data Source We Can Trust]&#8239;», sur la base d'une recherche partagée lors du rassemblement INKE 2020: [https://mcri.inke.ca/index.html%3Fp=2937.html Open scholarship for the 2020s] (2020). Un [https://www.lib.sfu.ca/help/publish/scholarly-publishing/radical-access-blog article] sur le blog de la bibliothèque de l'Université Simon Fraser (SFU), soutient de la même manière que la participation sur Wikipédia par les contributeurs appartenant à la communauté universitaire parce qu’ils ont accès à des informations savantes de haute qualité et l'expertise du domaine nécessaire pour rendre des sujets plus complexes accessibles à un large public (Robinson-Clogg 2020). Le [https://www.lib.sfu.ca/help/publish/dh/dhil/digital-pedagogy-network SFU-UVIC Digital Pedagogy Network], basé dans le [https://www.lib.sfu.ca/help/publish/dh/dhil Digital Humanities Innovation Lab] à la bibliothèque de SFU et en partenariat [https://etcl.uvic.ca/ avec l’Electronic Textual Cultures Lab (ETCL)] et [https://www.uvic.ca/library/ les bibliothèques d’UVi]c, entre autres, a inclus une [https://www.lib.sfu.ca/help/publish/dh/dhil/digital-pedagogy-network Indigenous Wikipedia Edit-a-thon] dans ses événements en 2016; les détails de l'événement peuvent être trouvés [https://en.wikipedia.org/wiki/Wikipedia:Meetup/IndigenousFilmandMedia en ligne]. ==Wikipédien(ne)s en résidence dans la presse== Plusieurs programmes wikipédien(ne)s en résidence ont été couverts dans les médias. La nomination inaugurale de Vandendorpe à l’UVic, par exemple, a été couverte par [http://www.cbc.ca/news/canada/british-columbia/university-of-victoria-announces-new-honorary-resident-wikipedian-1.2894838 CBC News] et le Victoria [http://www.timescolonist.com/business/on-the-street-insurance-brokerage-sold-1.1725881 ''Times Colonist''], ainsi que par [https://etcl.uvic.ca/hrw/ d’autres médias locaux]. La nomination d'Alex Jung par l'Université de Toronto en tant que premier wikipédien en résidence en 2018 a été couverte par le [https://www.thestar.com/news/gta/2018/11/01/u-of-t-libraries-hires-first-wikipedian-in-residence.html?rf ''Toronto Star''], et la nomination par l'Université Concordia d'Amber Berson en 2019 a été couverte par [https://www.cbc.ca/news/canada/montreal/wikipedia-in-residence-concordia-montreal-1.5200247 CBC News], [https://montreal.ctvnews.ca/concordia-university-s-wikipedian-in-residence-teaching-people-how-to-access-and-assess-information-1.4537133?cache=%3FclipId%3D89680 CTV News], [https://montreal.citynews.ca/video/2019/07/10/canadas-newest-wikipedian-in-residence/ City News] et le [https://montrealgazette.com/opinion/columnists/brownstein-concordias-wikipedian-in-residence-has-a-lot-on-her-plate ''Montreal Gazette'']. Les wikipédien(ne)s ont également attiré l'attention de la presse académique. En plus de la première location d'un par une université - par [https://www.timeshighereducation.com/news/berkeleys-wikipedian-helps-unlock-scholarly-silos/2012696.article l'Université de Californie à Berkeley] en 2014 - la presse académique a également couvert le programme de manière plus générale, abordant la question de [https://www.timeshighereducation.com/news/wikipedia-should-be-better-integrated-into-teaching/2018486.article Wikipédia en classe universitaire] et [https://www.timeshighereducation.com/news/wikipedian-residence-improves-public-access-science le succès des programmes pour améliorer la qualité des articles Wikipédia], par exemple. En 2015, [https://www.timeshighereducation.com/news/university-hopes-wikipedian-residence-will-tackle-gender-gap ''Times Higher Education''] (''THE'') a couvert la création par le West Virginia University d'un poste de wikipédien(ne) en résidence chargé de combler l'écart entre les sexes de Wikipédia&nbsp;: des enquêtes en 2011 et 2018 suggèrent qu'environ 90% des rédacteurs bénévoles de Wikipédia s'identifient comme des hommes («&#8239;Gender Bias on Wikipedia&#8239;» 2020 ; Straumsheim 2015). De nombreux ces rôles sont basés dans des bibliothèques universitaires et, comme le souligne un article de 2019 dans [https://www.affairesuniversitaires.ca/actualites/actualites-article/wikipedia-au-service-du-milieu-universitaire/?_ga=2.61844268.1060067117.1611275827-1855156954.1605314527 ''University Affairs''], les bibliothèques universitaires et d'autres bibliothèques s'engagent également avec Wikipédia par d'autres moyens (Aschaiek 2019). S'adressant à la communauté des bibliothèques, la publication de l'American Libraries Association ''Leveraging Wikipedia, Connecting Communities of Knowledge'' (2018) met l'accent sur les objectifs communs des communautés de bibliothèques et de Wikipédia et offre des conseils sur la manière d'accroître l'engagement dans l'édition de Wikipédia dans les communautés de bibliothèques - les bibliothèques publiques également comme recherche - ce qui comprend l'embauche des wikipédien(ne)s en résidence (Proffitt 2018). Ces programmes intéressent également la communauté au sens large. Un article de 2014 dans ''The Atlantic'' sur le programme de [https://www.theatlantic.com/technology/archive/2014/03/harvards-looking-for-a-wikipedian-in-residence/284373/ la bibliothèque de Houghton] relie le programme au mandat de la bibliothèque, en particulier son objectif de rendre ses informations et ses ressources accessibles à la communauté (Garber). Un article publié en 2015 dans ''USA Today'' sur le programme wikipédien(ne) en résidence de West Virginia University note qu'il a été créé spécifiquement pour lutter contre [https://en.wikipedia.org/wiki/Gender_bias_on_Wikipedia les préjugés sexistes de Wikipédia], ce que d'autres postes ont également abordé depuis, notamment au Canada, la bibliothèque de l'Université Concordia wikipédienne en résidence [https://library.concordia.ca/about/wikipedian-in-residence/ Amber Berson] et l'Université de l'Alberta wikipédienne en residence [https://www.ualberta.ca/giving/giving-news/2020/august/ualbertas-first-wikipedian-in-residence.html Erin O'Neil]. De même, un article dans [https://www.macleans.ca/education/why-universities-are-hiring-wikipedeans-in-residence/ ''Macleans''] en 2019 souligne la nécessité pour les étudiants et autres utilisateurs et contributeurs de Wikipédia de réfléchir de manière critique à la plate-forme, notamment en demandant qui fournit des informations et en modérant les contributions, et quels sont les préjugés de la communauté (Hutchins). Dans une interview publiée en 2019 dans [https://theconversation.com/on-the-job-with-a-wikipedian-in-residence-118494 ''The Conversation''], la wikipédienne en résidence pour le [https://www.sciencehistory.org/ Philadelphia’s Science History Institute], Mary Mark Ockerbloom, souligne que les positions peuvent être controversées au sein de la communauté Wikipédia, en particulier lorsqu'il s'agit de postes rémunérés, par souci de conflits d'intérêts. Ockerbloom note que ces conflits sont une préoccupation importante pour tous les éditeurs de Wikipédia, mais qu'être payé pour éditer du contenu n'est pas nécessairement un conflit, en particulier parce que Wikipédia, les institutions culturelles et les wikipédien(ne)s qu'ils utilisent partagent des objectifs communs (Hocquet 2019). ==Les reactions de la communauté universitaire== L'émergence des programmes wikipédien(ne)s en résidence est le signe d'un changement d'attitude envers Wikipédia au sein de la communauté universitaire. Dans les années qui ont suivi le lancement de Wikipédia, de nombreux membres de la communauté académique l'ont rejeté comme inexact et peu fiable. Maintenant, sachant que c'est là que de nombreux étudiants, membres de la communauté et chercheurs recherchent des informations, de nombreux membres de la communauté académique, y compris [https://etcl.uvic.ca/event/making-a-better-web-free-public-talk-lunch-wikipedia-edit-a-thon-with-dr-constance-crompton-university-of-ottawa/ Constance Crompton], ancienne résidente honoraire de l'Université de Victoria, demandent à la communauté d'améliorer la qualité et la fiabilité de ses informations et l'utiliser comme une plateforme pour partager la richesse des connaissances que possède la communauté (Hutchins). ==Les programmes wikipédien(ne) en résidence et la science ouverte== En tant que ressource ouverte, collaborative, à but non lucratif et dirigée par la communauté qui vise à rendre les informations disponibles et accessibles en ligne, la mission et les objectifs de Wikipédia s'alignent étroitement avec ceux de la mouvement science ouverte. Les programmes wikipédien(ne)s en résidence comblent souvent les lacunes de la base de connaissances de Wikipédia, en abordant et en sensibilisant aux problèmes liés aux inégalités d’accès aux connaissances et au partage des connaissances des communautés marginalisées. De plus, Wikipédia et d'autres projets Wikimedia sont des composants importants de l'infrastructure mondiale des connaissances ouverte. Par exemple, Wikidata est un hub important pour les données ouvertes liées. Andy Mabbett, le wikipédien en résidence avec [https://orcid.org/ ORCID], note que les identifiants ORCID peuvent être utilisés comme identifiants persistants dans Wikipédia pour les universitaires, qui peuvent ne pas avoir d'identifiants [http://viaf.org/ VIAF (Virtual International Authority File]) ou d'autres identifiants persistants (voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/ORCID : Connecter la recherche et les chercheurs|ORCID: Connecter la recherche et les chercheurs]]&#8239;», «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Mise à jour ORCID : Intégration des identifiants ORCID dans les workflows de financement de la recherche|Mise à jour ORCID : Intégration des identifiants ORCID dans les workflows de financement de la recherche]]&#8239;», «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Le Persistent Identifier (PID) Consortium de Royaume-Uni|Le «&#8239;Persistent Identifier (PID) Consortium&#8239;» de Royaume-Uni]]&#8239;», et «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Wikidata dans les bibliothèques de recherche|Wikidata dans les bibliothèques de recherche]]&#8239;»). De cette manière, Wikidata et Wikipédia peuvent être intégrés dans l'infrastructure de recherche numérique plus large. ==Ouvrages citées== *Aschaiek, Sharon. 2019. «&#8239;Wikipédia au service du milieu universitaire&#8239;». ''Affaires Universitaires''. 26 février 2019. https://www.affairesuniversitaires.ca/actualites/actualites-article/wikipedia-au-service-du-milieu-universitaire/. *Cohen, Noam. 2010. «&#8239;Venerable British Museum Enlists in the Wikipedia Revolution&#8239;». ''New York Times''. 4 juin 2010. [https://www.nytimes.com/2010/06/05/arts/design/05wiki.html https://www.nytimes.com/2010/06/05/arts/design/05wiki.html]. *Crabtree, Trent. 2015. «&#8239;West Virginia University to Hire ‘Wikipedian in Residence’&#8239;». ''USA Today''. 24 juillet 2015. [https://www.usatoday.com/story/college/2015/07/24/west-virginia-university-to-hire-wikipedian-in-residence/37404995/ https://www.usatoday.com/story/college/2015/07/24/west-virginia-university-to-hire-wikipedian-in-residence/37404995/]. *Crompton, Constance. 2020. «&#8239;Familiar Wikidata: The Case for Building a Data Source we can Trust&#8239;». 31 octobre 2020. [https://popjournal.ca/issue02/crompton https://popjournal.ca/issue02/crompton]. *Garber, Megan. 2014. «&#8239;Harvard’s Looking for a ‘Wikipedian in Residence’&#8239;». ''The Atlantic''. 12 mars 2014. [https://www.theatlantic.com/technology/archive/2014/03/harvards-looking-for-a-wikipedian-in-residence/284373/ https://www.theatlantic.com/technology/archive/2014/03/harvards-looking-for-a-wikipedian-in-residence/284373/]. *«&#8239;Gender Bias on Wikipedia&#8239;». 2020. Wikipedia. 11 decembre 2020. [https://en.wikipedia.org/wiki/Gender_bias_on_Wikipedia https://en.wikipedia.org/wiki/Gender_bias_on_Wikipedia]. *Hocquet, Alexandre. 2019. «&#8239;On the Job with a ‘Wikipedian in Residence’&#8239;». ''The Conversation''. 10 juillet 2019. [https://theconversation.com/on-the-job-with-a-wikipedian-in-residence-118494 https://theconversation.com/on-the-job-with-a-wikipedian-in-residence-118494]. *The Humanities Data Lab. n.d. ''Cultural Data/Data for Culture''. http://humanitiesdata.ca/projects/cultural-data/. *Hutchins, Aaron. 2019. «&#8239;Why Universities are Hiring ‘Wikipedeans-in-Residence’&#8239;». ''Macleans''. 3 octobre 2019. https://www.macleans.ca/education/why-universities-are-hiring-wikipedeans-in-residence/. *Meadows, Alice. 2016. «&#8239;Meet our Wikipedian-in-Residence, Andy Mabbett!&#8239;» ORCiD. 15 janvier 2016. [https://info.orcid.org/meet-our-wikipedian-in-residence-andy-mabbett/ https://info.orcid.org/meet-our-wikipedian-in-residence-andy-mabbett/]. *Proffitt, Merrilee. 2018. ''Leveraging Wikipedia: Connecting Communities of Knowledge. ''ALA Editions. *Robinson-Clogg, Graeme. 2020. «&#8239;Getting Started with Wikipedia&#8239;». Radical Access: Scholarly Publishing + Open Access. Simon Fraser University Library. 7 octobre 2020. [https://www.lib.sfu.ca/help/publish/scholarly-publishing/radical-access/wikipedia-editing https://www.lib.sfu.ca/help/publish/scholarly-publishing/radical-access/wikipedia-editing]. *Straumsheim, Carl. 2015. «&#8239;University Hopes ‘Wikipedian in Residence’ will Tackle Gender Gap&#8239;». ''Times Higher Education''. 20 juillet 2015. https://www.timeshighereducation.com/news/university-hopes-wikipedian-residence-will-tackle-gender-gap. *«&#8239;Wikimedian in Residence&#8239;». 2020. Wikimedia. 10 decembre 2020. https://meta.wikimedia.org/wiki/Wikimedian_in_residence. *«&#8239;Wikipedian in Residence&#8239;». 2020. Wikipedia. 15 decembre 2020. https://en.wikipedia.org/wiki/Wikipedian_in_residence. [[Catégorie:Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024 (livre)]] a91045inf263uransnvjrr2x9wk3q4e Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Les Fonds de recherche du Québec rejoignent la cOAlition S 0 82354 744014 742397 2025-06-02T22:23:36Z LodestarChariot2 120009 /* Ouvrages citées */ 744014 wikitext text/x-wiki ''Cette observation a été écrit par Caroline Winter (avec remerciements à Tanja Niemann et Simon Van Bellen pour ses commentaires et contributions), pour le Electronic Textual Cultures Laboratory et le partenariat Implementing New Knowledge Environments.'' En juin 2021, [https://frq.gouv.qc.ca/ les Fonds de recherche du Québec (FRQ)] ont annoncé qu’ils se joignent a la [https://www.coalition-s.org/about/ cOAlition S] et mettaient en oeuvre les principes du [https://www.coalition-s.org/why-plan-s/ Plan S], y compris libre accès complets et immédiat à tous la recherche qu’ils financent. Les FRQ sont le premier organisme de financement canadien et le premier organisme de financement public en Amérique du Nord à se joindre à cOAlition S, qui a été fondée en 2018 en tant que groupe de 11 organismes de financement européens engagés à faire progresser libre accès, soutenu par le Conseil européen de la recherche et la Commission européenne (voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Plan S et cOAlition S|Plan S et cOAlition S]]&#8239;»). Il s'est depuis élargi pour inclure des membres d'Afrique, du Moyen-Orient et des États-Unis (voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Mise à jour ORCID : Intégration des identifiants ORCID dans les workflows de financement de la recherche|Mise à jour du Plan S : l'élargissement de l'adhésion de la cOAlition S]]&#8239;»). Les FRQ comprendre les trois organismes subventionnaires de la recherche au Québec : [https://frq.gouv.qc.ca/nature-et-technologies/ Nature et technologies (FRQNT)], [https://frq.gouv.qc.ca/sante/ Santé (FRQS)] et [https://frq.gouv.qc.ca/societe-et-culture/ Société et culture (FRQSC)]. Représentant près du quart de la communauté de recherche au Canada, les FRQ ont administré 253 millions de dollars en financement de recherche en 2019-2020 à des chercheurs basés au Québec (Fondation européenne de la science, 2021). Les FRQ offrent également un Programme de soutien aux revues scientifiques, qui soutient la publication de recherches savantes en français, avec une priorité à la publication numérique et en libre accès (FRQ 2021). Leur [https://frq.gouv.qc.ca/app/uploads/2021/04/politique-libre-acces_avril19.pdf politique de libre accès existante], en place depuis 2019, exige que les publications soient en libre accès dans les 12 mois suivant la publication ; afin d'aligner cette politique sur le Plan S, à compter de mars 2023, cette période d'embargo sera supprimée (Gouvernement du Québec, 2021). ==Réponse de la communauté INKE== Plan S et cOAlition S intéressent la communauté INKE depuis leur lancement, en reconnaissance de la nature mondiale de la science ouverte. Dans son rapport de 2020 ''Advancing Open: points de vue des spécialistes de la communication savante'', le groupe de travail sur les dépôts ouverts de l'Association des bibliothèques de recherche du Canada (ABRC), un partenaire d'INKE, exprime ses inquiétudes quant à la volonté du Canada d'adopter un «&#8239;modèle transformateur de science ouverte&#8239;» tel que le Plan S (MacCallum et al. 8). Le délai prolongé des FRQ pour lever leur période d'embargo – près de deux ans plutôt que la période habituelle – semble toutefois répondre à cette préoccupation. Comme le note le communiqué des FRQ, «&#8239;Conscients des impacts que ce changement pourrait engendrer dans la communauté scientifique et étudiante, les FRQ déploieront graduellement les dix principes du Plan S et planifieront des mesures pour les accompagner&#8239;» (Fondation européenne de la science 2021 ; Gouvernement du Québec 2021). [https://www.erudit.org/fr/ Érudit], un partenaire d'INKE, collabore avec le FRQSC depuis 2006. Conformément à la politique du FRQ en libre accès, toutes les revues financées par le FRQSC sont en libre accès via Érudit (Érudit 2021). ==Les FRQ, la cOAlition S et la science ouverte== En tant que premier organisme de financement canadien à se joindre à la cOAlition S, les FRQ ouvrent la voie à d'autres bailleurs de fonds publics canadiens et nord-américains pour se joindre au Plan S, qui est devenu une initiative mondiale. Bien que la recherche financée par les FRQ ne soit pas nécessairement publiée en français, son adhésion au Plan S s'inscrit dans le cadre d'autres initiatives menées par le scientifique en chef du Québec, dont le lancement d'un [https://www.scientifique-en-chef.gouv.qc.ca/dossiers/conseil-scientifique-aux-gouvernements/reseau-francophone-en-conseil-scientifique/ réseau francophone] sur les avis scientifiques pour les politiques publiques, annoncé en septembre 2021. Le rapport accompagnant le lancement de ce réseau note que la recherche en langue française doit être accessible en libre accès à tous les chercheurs francophones (Scientifique en chef 2021, 48).[https://frq.gouv.qc.ca/app/uploads/2021/04/politique-libre-acces_avril19.pdf La politique libre accès des FRQ] soutient également la recherche en français comme l'un de ses principes fondamentaux (FRQ 2019). La nouvelle des FRQ rejoignant la cOAlition a été [https://quebec.consulfrance.org/Engagement-du-Quebec-en-faveur-de-la-science-ouverte partagée sur le site Web du Consulat général de France à Québec], soulignant le fait que la politique française de libre accès est un autre contexte important pour la décision des FRQ. Lui-même adopté dans le contexte de cadres européens plus larges, dont Horizon Europe, [https://www.ouvrirlascience.fr/deuxieme-plan-national-pour-la-science-ouverte/ ''le Deuxième Plan national pour la science ouverte : généraliser la science ouverte en France 2021-2024''] étend le premier plan de 2018 pour inclure le code ouvert, l'infrastructure pour soutenir le partage de données, et un accent mis sur la généralisation plus large du libre accès, notamment par la traduction de publications françaises pour améliorer leur accessibilité. Comme indiqué dans un article du [https://www.timeshighereducation.com/news/france-back-not-profit-diamond-journals ''Times Higher Ed''], cet Deuxième Plan est l'une des nouvelles politiques nationales visant à mettre l'accent sur le soutien à libre accès diamant, dans laquelle les revues ne facturent pas de frais de traitement d'article ni de frais d'abonnement (Matthews 2021). [https://anr.fr/fr/ L'Agence nationale de la recherche (ANR)], l'organisme national de financement de la recherche en France, est membre de la cOAlition S depuis sa création, et de nombreux chercheurs français publient probablement dans les revues francophones du Québec. ==Ouvrages citées== *Érudit. 2021. ''Annual Report 2020–2021: Érudit Consortium''. [https://www.erudit.org/public/documents/AnnualReport_20-21.pdf https://www.erudit.org/public/documents/AnnualReport_20-21.pdf]. *Fondation européenne de la science. 2021. «&#8239;cOAlition S Expands its Global Footprint as the Québec Research Funds adopt Plan S&#8239;». ''Plan S: Making Full & Immediate Open Access a Reality''. [https://www.coalition-s.org/coalition-s-expands-its-global-footprint-as-the-quebec-research-funds-adopt-plan-s/ https://www.coalition-s.org/coalition-s-expands-its-global-footprint-as-the-quebec-research-funds-adopt-plan-s/]. *FRQ (Fonds de recherche du Québec). 2019. ''Politique de diffusion en libre accès des Fonds de recherche du Québec''. Gouvernement du Québec, 15 avril 2019. [https://frq.gouv.qc.ca/app/uploads/2021/05/politique-libre-acces_en_avril19.pdf https://frq.gouv.qc.ca/app/uploads/2021/04/politique-libre-acces_avril19.pdf]. *FRQ (Fonds de recherche du Québec). 2021. ''Scientific Journal Support Program''. Gouvernement du Québec, mai 2021. [https://frq.gouv.qc.ca/app/uploads/2021/07/scientific-journal-support-program-frqsc.pdf https://frq.gouv.qc.ca/app/uploads/2021/07/scientific-journal-support-program-frqsc.pdf]. *Gouvernement du Québec. 2021. «&#8239;Les Fonds de recherche du Québec appuient la science ouverte en joignant la cOAlition S&#8239;». ''Québec'', 21 juin 2021. [https://www.scientifique-en-chef.gouv.qc.ca/nouvelles/les-fonds-de-recherche-du-quebec-appuient-la-science-ouverte-en-joignant-la-coalition-s/ https://www.scientifique-en-chef.gouv.qc.ca/nouvelles/les-fonds-de-recherche-du-quebec-appuient-la-science-ouverte-en-joignant-la-coalition-s/]. *MacCallum, Lindsey, Ann Barrett, Leah Vanderjagt et Amy Buckland. 2020. ''Advancing Open: points de vue de spécialistes de la communication savante''. Association des bibliothèques de recherche du Canada (ABRC), avril 2020, [https://www.carl-abrc.ca/wp-content/uploads/2020/04/GTDO_rapport3_Advancing_open_FR.pdf https://www.carl-abrc.ca/wp-content/uploads/2020/04/GTDO_rapport3_Advancing_open_FR.pdf]. *Matthews, David. 2021. «&#8239;France to Back Not-for Profit Diamond Journals&#8239;». ''Times Higher Ed'', 13 juillet 2021. [https://www.timeshighereducation.com/news/france-back-not-profit-diamond-journals https://www.timeshighereducation.com/news/france-back-not-profit-diamond-journals]. *Scientifique en chef du Québec. 2021. ''Vers un résearu francophone pour l’utilisation des science en soutien aux politiques publiques: Document pour consultation''. Gouvernement du Québec, septembre 2021. [https://www.scientifique-en-chef.gouv.qc.ca/wp-content/uploads/ConseilSci_Francophonie_version_Sept2021.pdf https://www.scientifique-en-chef.gouv.qc.ca/wp-content/uploads/ConseilSci_Francophonie_version_Sept2021.pdf]. [[Catégorie:Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024 (livre)]] 8wq2sno25eajbhqfj4wlmvvic8k3zn5 Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Renforcement des capacités de GDR au Canada et la série de rapports Insights de Portage 0 82355 744015 742403 2025-06-02T22:24:06Z LodestarChariot2 120009 /* Ouvrages citées */ 744015 wikitext text/x-wiki ''Cette observation a été écrit par Caroline Winter (avec remerciements à Shahira Khair pour ses commentaires et contributions), pour le Electronic Textual Cultures Laboratory et le partenariat Implementing New Knowledge Environments.'' En mai 2018, les trois organismes du Canada ont publié une ébauche d’un Politique de gestion des données de recherche (GDR) aux fins de consultation, l'une des nombreuses politiques liées à la gestion des données, y compris la [https://www.science.gc.ca/eic/site/063.nsf/fra/h_F6765465.html Politique des trois organismes sur le libre accès aux publications] (2015) et la [https://www.science.gc.ca/eic/site/063.nsf/fra/h_83F7624E.html Déclaration de principes des trois organismes sur la gestion des données numériques] (2016) (voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Le politique des trois organismes sur la gestion des données de recherche|Le Politique des trois organismes sur la gestion des données de recherche]]&#8239;»). La version finale de la [https://www.science.gc.ca/eic/site/063.nsf/fra/h_97610.html Politique des trois organismes sur la GDR] a été publiée en mars 2021 (voir «&#8239;[[Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Mise à jour : Gestion des données de recherche au Canada|Mise à jour : Gestion des données de recherche au Canada]]&#8239;»). En vertu de la politique, les établissements de recherche qui administrent les fonds des trois organismes sont tenus d'élaborer des stratégies de GDR d'ici le 1er mars 2023 (Gouvernement du Canada 2021). Alors que les établissements commençaient à élaborer leurs politiques de GDR en réponse à l'ébauche de politique des trois organismes, le Groupe d'experts sur la recherche et l’intelligence (GERI) du réseau Portage a mené deux sondages pour déterminer dans quelle mesure les établissements étaient prêts à mettre en œuvre la Politique de GDR et quels services Portage et d'autres intervenants pourraient offrir en soutien. ==Sondage sur la stratégie institutionnelle de GDR== Le [https://doi.org/10.5281/zenodo.3962885 sondage sur la stratégie institutionnelle de GDR de Portage] (Portage 2019) a été mené en juin 2019 et a reçu 88 réponses de 63 établissements. Il a révélé que la plupart des établissements répondants avaient entamé le processus d'élaboration d'une stratégie institutionnelle de GDR, même si bon nombre d'entre eux en étaient au stade de la planification. Parmi ceux-ci, beaucoup ont noté que le développement a l’arrêt, en attendant la publication de la politique finale de GDR des trois organismes. Sur la base des réponses à l'enquête, le GERI a suggéré des mesures à prendre pour aider les établissements à développer leurs stratégies, notamment en partageant les stratégies finales pour servir d'exemples, en facilitant les communautés de pratique pour aider les groupes de travail institutionnels à apprendre les uns des autres et en fournissant des conseils explicites sur la manière dont stratégies peuvent répondre aux exigences de la politique des trois organismes. ==L'enquête sur la capacité des services GDR institutionnels et les rapports d'analyse== À l'automne 2019, le GERI a mené le ''Sondage sur la capacité des services institutionnels de gestion des données'' afin d'établir une référence pour la capacité des établissements de recherche au Canada à soutenir les activités de GDR décrites dans l'ébauche de la politique de GDR des trois organismes (Cooper et al. 2020). Il a reçu 85 réponses de 77 établissements, dont des universités, des collèges, des CEGEPs, des centres et établissements de recherche et des organismes gouvernementaux (2). Un résumé analytique a été publié en janvier 2020 (Cooper et al. 2020). [https://doi.org/10.5281/zenodo.3906470 Le premier rapport Insights], publié en juin 2020, s'est concentré sur la capacité au sein des organisations, avec des conclusions clés liées à la politique, aux structures organisationnelles, aux budgets et aux collaborations internes et externes (Abel et al., 3). S'appuyant sur les résultats discutés dans le rapport initial, il a noté que les bibliothèques et les unités administratives de la recherche dirigeaient le plus souvent l'élaboration de stratégies et de politiques de GDR dans les universités et les collèges (4). En ce qui concerne les structures de travail, environ la moitié des établissements (principalement des universités) avaient des groupes de travail institutionnels formels sur la GDR, la plupart dirigés par des bibliothèques ou des groupes d'administration de la recherche (8). En termes de structure de personnel, environ le tiers (33,8 %) des établissements, principalement des universités, avaient créé de nouveaux postes pour assumer des responsabilités de GDR et un peu moins du tiers (28,6 %) avaient réaffecté du personnel existant pour les assumer, mais un peu plus du tiers (37,7 %) n'avaient pas de personnel responsable de la GDR (9). Bien que le financement soit crucial pour le développement des capacités, une seule institution a fait état d'un budget institutionnel dédié à la GDR ; la forme de financement la plus courante consistait à utiliser les budgets opérationnels (27,3 %) et de nombreux établissements (37,7 %) ont déclaré ne pas avoir de budget dédié à la GDR (15–16). La plupart des établissements ont participé à des initiatives collaboratives nationales (65,6 %) ou régionales (72,1 %) de GDR (13). [https://doi.org/10.5281/zenodo.4559991 Le deuxième rapport Insights], publié en février 2021, se concentre sur le personnel hautement qualifié (PHQ), l'infrastructure et les services (Cooper et al. 2021a). Il a examiné l'expertise en GDR dans 12 catégories de compétences (par exemple, la connaissance des politiques nationales, le développement de logiciels, la gestion des données, la création de métadonnées), organisées en étapes du cycle de vie des données, comme décrit dans [https://doi.org/10.5281/zenodo.4015589 ''L'introduction à gestion des données de recherche de Portage'']. Il a constaté que les universités avaient tendance à faire état d'une plus grande capacité que les collèges dans plusieurs catégories et que les établissements exprimaient le besoin d'un soutien plus qualifié dans toutes les catégories, avec un besoin particulier «&#8239;en gestion des données sensibles, en curation de données, en développement de logiciels de recherche, en préservation des données, en gestion des données par les chercheurs et au regard des aspects techniques des infrastructures électroniques&#8239;» (4). En termes d'infrastructure GDR, par rapport aux collèges, les universités ont signalé une plus grande connaissance et un soutien institutionnel pour le transfert de données (50 % ; 19 %), les données sensibles (40,4 % ; 33,3 %), le calcul haute performance (50 % ; 14,3 %) , logiciels commerciaux qualitatifs (55,8 % ; 28,6 %), logiciels quantitatifs (75 % ; 38,1 %) et outils de collaboration (26,9 % ; 9,5 %) (12–14). Dans de nombreux cas, cependant, les répondants ne savaient pas quels soutiens étaient disponibles. En ce qui concerne les services de GDR, alors que plus de la moitié des répondants offrent une gamme complète de soutiens de GDR, l'étendue et le niveau de développement de ces services varient considérablement (16). Ces services sont généralement proposés au niveau institutionnel et dirigés par des bibliothèques, des départements informatiques ou des efforts conjoints (17–19). Les institutions avec des postes dédiés à la GDR et un soutien budgétaire dédié ont tendance à offrir davantage de soutiens institutionnels, tandis que celles dans lesquelles le soutien à la GDR est affecté à des postes existants ont tendance à faire appel à des ressources externes (20–21). [https://doi.org/10.5281/zenodo.4892718 Le troisième rapport Insights], publié en février 2021 (Cooper et al. 2021b), examine quelles ressources GDR sont disponibles, comment elles sont allouées et comment elles pourraient mieux servir la communauté. Lorsqu'on leur a demandé de classer les ressources à privilégier pour soutenir la GDR, les répondants ont cité le plus souvent les ressources humaines (37,7 %), suivies des conseils sue les questions de politiques (22,1 %) et des ressources financières (16,9 %) et techniques (14,3 %) (5). En termes d'investissement, près de la moitié (46,8 %) des établissements n'avaient pas l'intention ou ne connaissaient pas de l'intention d'investir davantage dans les supports technologiques de GDR, et seulement 7,8 % prévoyaient de créer de nouveaux postes de GDR (6). Environ le quart des universités ont déclaré offrir du perfectionnement professionnel en GDR aux chercheurs (19,6 %) et au personnel (23,5 %), comparativement à seulement 5,3 % des collèges, qui ont déclaré offrir une formation aux chercheurs seulement (9). Interrogés sur les obstacles au soutien de la GDR, les répondants ont le plus souvent cité le manque de sensibilisation ou la résistance au partage des données, le manque de temps et le manque de financement et d’incitatifs (11). Lorsqu'on leur a demandé quels facteurs accéléreraient le plus efficacement le développement de la GDR, les répondants ont mentionné le plus souvent le financement, suivi des politiques, de la formation et de la collaboration (15). Le troisième rapport Insights se termine par une liste de recommandations, certaines nouvelles et d'autres déjà mises en œuvre. De façon générale, cela comprend le développement de ressources pour soutenir la capacité de GDR, comme celles que Portage a créées pour soutenir le développement de [https://portagenetwork.ca/fr/outils-et-ressources/strategies-institutionnelles/ stratégies institutionnelles de GDR]. Ils comprennent également une collaboration accrue entre les organisations existantes, en particulier par l'intermédiaire de [https://alliancecan.ca/fr/ l'Alliance de recherche numérique du Canada] (l'Alliance, anciennement NOIRN), et la mise en relation des chercheurs avec les ressources existantes. Le rapport note également que l'Alliance continuera de fournir un soutien à la GDR au niveau national, permettant aux établissements de concentrer leur financement et d'autres ressources sur les besoins locaux (Cooper et al. 2021b, 21). Pris ensemble, ces trois rapports montrent que les services et soutiens de GDR –– y compris la stratégie institutionnelle et, dans une moindre mesure, la politique ––sont en développement dans de nombreuses institutions canadiennes, souvent dirigées par des bibliothèques. Les établissements s'engagent dans des réseaux et des collaborations régionaux et nationaux, mais les soutiens à la GDR sont disponibles de manière inégale, les universités déclarant plus de ressources que les collèges. Certaines des priorités pour le renforcement des capacités de GDR comprennent le PHQ et les ressources humaines, le financement, l'infrastructure technologique et la connaissance des politiques (Cooper et al 2021b, 19). ==Renforcement des capacités de GDR et le Partenariat INKE== La GDR est une question d'intérêt pour de nombreux membres du Partenariat INKE, dont beaucoup sont depuis longtemps impliqués dans le développement des capacités de GDR. Avant de se joindre à l'Alliance, Portage était à l'origine une initiative de [https://www.carl-abrc.ca/fr/ l'Association des bibliothèques de recherche du Canada (ABRC)] et, sous le nom de l'ABRC Portage, elle a développé [https://assistant.portagenetwork.ca/ l'Assistant PGD (plans de gestion des données)], un outil bilingue en ligne pour la planification de la gestion des données hébergé par l'Université d’Alberta. Il a également travaillé avec [https://www.canarie.ca/fr/ CANARIE] pour soutenir une extension nationale du service [https://dataverse.scholarsportal.info/fr/ Scholars Portal Dataverse], un dépôt de données de recherche soutenu par [https://ocul.on.ca/ l’Ontario Council of University Libraries (OCUL)] et hébergé par [https://onesearch.library.utoronto.ca/ les bibliothèques de l'Université de Toronto]. L'ABRC Portage et [https://www.computecanada.ca/?lang=fr Calcul Canada] se sont également associés à l'Alliance pour développer le [https://www.frdr-dfdr.ca/repo/?locale=fr Dépôt fédéré de données de recherche (DFDR)], un dépôt pour les grands ensembles de données (> 1 To) et une plateforme de découverte qui fédère les données entre les dépôts canadiens. Portage et un autre partenaire INKE, [https://www.crkn-rcdr.ca/fr le Réseau canadien de documentation pour la recherche (RCDR)], gèrent également [https://www.crkn-rcdr.ca/fr/consortium-datacite-canada le Consortium DataCite Canada], qui permet aux institutions canadiennes de créer et d'intégrer des DOI pour soutenir la GDR et améliorer la découvrabilité, l'accessibilité et la citabilité de la recherche. En juin 2021, les bibliothèques de l'UVic ont organisé un événement virtuel intitulé [https://osf.io/6vepj/wiki/home/ Research Data Management for Digitally-Curious Humanists] qui a exploré le concept de données de recherche dans les sciences humaines et les stratégies de renforcement des capacités en GDR. [https://ospolicyobservatory.uvic.ca/draft-report-rdm/ Un projet de rapport basé sur les discussions lors de l'événement] a été partagé sur l'Open Scholarship Policy Observatory pour commentaires en novembre 2021. ==Renforcement des capacités de GDR et communauté universitaire élargie== La série de rapports de la coopérative internationale de bibliothèques [https://www.oclc.org/fr/home.html OCLC], intitulée [https://www.oclc.org/research/publications/2017/oclcresearch-rdm-part-one-service-space-tour.html ''The Realities of Research Data Management''], présente des études de cas d'universités du Royaume-Uni, des États-Unis, d'Australie et des Pays-Bas. Les auteurs notent que l'augmentation exponentielle de l'échelle des données de recherche est un facteur important qui motive le besoin d'une plus grande capacité de GDR. L'avènement du Big Data et les techniques de recherche computationnelle dans les sciences humaines et sociales a changé le visage des données dans la recherche d’aujourd’hui, et les processus d'assemblage, de gestion et la conservation des données également (Bryant et al. 2017). Les données de recherche, en plus des publications qui en découlent, sont devenues une partie importante du dossier scientifique et un atout précieux, en particulier lorsqu'elles sont optimisées pour être réutilisées. Au Canada, la politique de GDR des trois organismes à laquelle répondent le sondage et les rapports Insights de Portage fait partie des développements continus dans les écosystèmes nationaux de politiques et d'infrastructures qui visent à renforcer la capacité de GDR. Un article paru dans [https://www.affairesuniversitaires.ca/actualites/actualites-article/des-organismes-subventionnaires-priorisent-la-gestion-des-donnees-de-recherche/?_ga=2.122700619.1789151288.1643143466-1326693258.1641858361 ''Affaires universitaires''] note que bien que la GDR soit de plus en plus importante dans toutes les disciplines à mesure que la recherche devient plus intensive en données, ce n'est pas toujours une priorité pour les chercheurs, de sorte que le changement culturel est un facteur important pour faire progresser la capacité de GDR. Comme le note Jeff Moon, directeur de Portage, «&#8239;Nous devons changer cette culture afin que des données, métadonnées et codes bien documentés soient jugés aussi précieux qu'un bon article publié dans une revue scientifique&#8239;» (Voinigescu 2021). L'article pointe vers [https://portagenetwork.ca/fr/outils-et-ressources/ les ressources offertes par Portage] comme supports utiles pour les individus et les institutions. Les efforts du Canada pour renforcer la capacité de GDR font partie de sa stratégie globale d'infrastructure de recherche numérique (IRN). L'Alliance a été créée dans le cadre de cette stratégie : une organisation nationale à but non lucratif pour soutenir le calcul informatique de recherche avancée et les logiciels de recherche en plus de la GDR et les intégrer dans un système national d'IRN (voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/NOIRN et la stratégie canadienne d’infrastructure de recherche numérique|NOIRN et la stratégie canadienne d'infrastructure de recherche numérique]]&#8239;»). L'Alliance a publié [https://alliancecan.ca/assets/uploads/documents/NDRIO_GDR_E%CC%81xpose%CC%81deprincipe-1.pdf un rapport connexe] en septembre 2021, sondant l'environnement de la GDR au Canada (Khair et al. 2020; voir «&#8239;[[Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/État actuel de la gestion des données de recherche au Canada : un rapport par l’Alliance de recherche numérique du Canada|État actuel de la gestion des données de recherche au Canada : un rapport par l’Alliance de recherche numérique du Canada]]&#8239;»). En décembre 2021, [https://alliancecan.ca/fr/dernier/new-research-data-management-resources-institutional-rdm-strategies-and-data-management-plans l'Alliance a annoncé de nouvelles ressources GDR] pour soutenir les établissements : * [https://zenodo.org/record/5745923#.YfQtt_XMLm8 Modèle pour l’élaboration de stratégie institutionnelle de GDR] * [https://zenodo.org/record/5745894#.YfQt0fXMLm8 Modèle d'évaluation de la maturité de la GDR au Canada (MAMIC)] * [https://www.youtube.com/watch?v=epsYxaNlS40 Vidéo d'introduction] aux plans de gestion des données (PGD) et l’Assistant PGD ==Renforcement des capacités GDR et la science ouverte== Bien que la politique de GDR des trois organismes indique explicitement qu'il «&#8239;n’est pas une politique sur les données ouvertes&#8239;» (Gouvernement du Canada 2021), et que toutes les données de recherche ne peuvent ou ne doivent pas être ouvertes, les pratiques et la capacité de GDR sont fondamentales pour les données ouvertes et la science ouverte. Les chercheurs peuvent utiliser des infrastructures GDR telles que DFDR, par exemple, pour améliorer la découvrabilité et la réutilisation de leurs données de recherche, par exemple (Voinigescu 2021). S'appuyer sur les soutiens GDR existants identifiés dans les rapports Insights de Portage améliorera également la capacité de l'écosystème de recherche canadien en matière de la science ouverte. ==Ouvrages citées== *Abel, Jennifer, Alexandra Cooper, Dylanne Dearborn, Carol Perry, Andrea Szwajcer, et Minglu Wang. 2020. ''Sondage sur la capacité des services institutionnels de gestion des données de recherche, rapport INSIGHTS #1 Soutien à la GDR au sein des organisations: budget, structure et stratégies''. Juin 2020, Réseau Portage, Association des bibliothèques de recherche du Canada. [https://doi.org/10.5281/zenodo.3906470 https://doi.org/10.5281/zenodo.3906470]. *Bryant, Rebecca, Brian Lavoie, et Constance Malpas. 2017. ''The Realities of Research Data Management, Part One: A Tour of the Research Data Management (RDM) Service Space''. OCLC. [https://doi.org/10.25333/C3PG8J https://doi.org/10.25333/C3PG8J]. *Cooper, Alexandra, Carol Perry, Andrea Szwajecer, Minglu Wang, et Shahira Khair. 2020. ''Sondage sur la capacité des services institutionnels de gestion des données de recherche: Sommaire. ''Réseau Portage, Association des bibliothèque de recherche du Canada. [https://dx.doi.org/10.14288/1.0388723 https://dx.doi.org/10.14288/1.0388723]. *Cooper, Alexandra, Lucia Costanzo, Dylanne Dearborn, Shahira Khair, Carol Perry, Andrea Szwajcer, et Minglu Wang. 2021a. ''Sondage sur la capacité des services institutionnels de gestion des données de recherche, rapport INSIGHTS no2 '': ''Capacité des établissements au chapiter du personnel hautement qualifié, de l’infrastructure et des services''. [https://doi.org/10.5281/zenodo.4559991 https://doi.org/10.5281/zenodo.4559991]. *Cooper, Alexandra, Lucia Costanzo, Dylanne Dearborn, Shahira Khair, Carol Perry, Andrea Szwajcer, et Minglu Wang. 2021b. ''Sondage sur la capacité des services institutionnels de gestion de données de recherche, rapports INSIGHTS no3 : Avenir de soutien à la GDR pour les établissements : ressources priorisées, investissements, défis et accélérateurs''. [https://doi.org/10.5281/zenodo.4892718 https://doi.org/10.5281/zenodo.4892718]. *Gouvernement du Canada. 2021. ''Politique des trois organismes sur la gestion des données de recherche''. [https://www.science.gc.ca/eic/site/063.nsf/fra/h_97610.html https://www.science.gc.ca/eic/site/063.nsf/fra/h_97610.html]. *Groupe d’experts sur la recherche et l’intelligence du reseau Portage. 2019.'' Sondage sur la stratégie institutionelle de gestion des données de recherche (GDR) – Sommaire des résultats''. Novembre 2019. [https://doi.org/10.5281/zenodo.3962885 https://doi.org/10.5281/zenodo.3962885]. *Khair, Shahira, Rozita Dara, Susan Haigh, Mark Leggott, Ian Milligan, Jeff Moon, Karen Payne, Elodie Portales-Casamar, Ghilaine Roquet, et Lee Wilson. 2020. ''État actual de la gestion des données de recherche au Canada : Mise à jour de l’exposé de principe du CLIRN sur la gestion des données''. Novembre 2020. [https://alliancecan.ca/assets/uploads/documents/NDRIO_GDR_E%CC%81xpose%CC%81deprincipe-1.pdf https://alliancecan.ca/assets/uploads/documents/NDRIO_GDR_E%CC%81xpose%CC%81deprincipe-1.pdf]. *Voinigescu, Eva. 2021. «&#8239;Des organismes subventionnaires priorisent la gestion des données de recherche&#8239;». ''Affairs universitaires'', 15 juin 2021, [https://www.affairesuniversitaires.ca/actualites/actualites-article/des-organismes-subventionnaires-priorisent-la-gestion-des-donnees-de-recherche/ https://www.affairesuniversitaires.ca/actualites/actualites-article/des-organismes-subventionnaires-priorisent-la-gestion-des-donnees-de-recherche/]. [[Catégorie:Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024 (livre)]] kohycmi76ieo0y7nxtwaamm415adf3g Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/La Stratégie canadienne de numérisation du patrimoine documentaire 0 82356 744016 743670 2025-06-02T22:30:43Z LodestarChariot2 120009 /* Ouvrages Citées */ 744016 wikitext text/x-wiki ''Cette observation a été écrit par Caroline Winter et JT Kern (avec remerciements à Jonathan Bengtson pour ses commentaires et contributions), pour le Electronic Textual Cultures Laboratory et le partenariat Implementing New Knowledge Environments.'' [https://snpd.ca/ La Stratégie canadienne de numérisation du patrimoine documentaire (SNPD)] fait partie d'une longue histoire de numérisation des matériaux du patrimoine culturel qui est en cours dans les communautés savantes et patrimoniales canadiennes depuis au moins les années 1960, évoluant au rythme des développements des technologies numériques, y compris le World Wide Web. Cette histoire comprend les stratégies de numérisation élaborées par l'Institut canadien de microreproductions historiques (ICMH) et [https://www.carl-abrc.ca/fr/ l'Association des bibliothèques de recherche du Canada (ABRC)] à partir des années 1970, l'initiative des bibliothèques numériques des années 1990, [https://www.crkn-rcdr.ca/fr le Réseau canadien de documentation pour la recherche (RCDR)] et [https://www.canadiana.ca/?usrlang=fr Canadiana] dans les années 2000. [https://archive.org/details/toronto Internet Archive Canada] donne accès libre au matériel numérisé des institutions canadiennes depuis 2004, lorsqu'un centre de numérisation a été établi dans le cadre d'un projet pilote à l'Université de Toronto (Calamai 2007). Le centre a été agrandi en 2006 et a numérisé près de 350 000 textes en quelques années seulement, avec le soutien financier de l'Université de Toronto, d'Internet Archive, de Microsoft et du CRKN (Casey 2011). Le centre de numérisation a été considérablement réduit en 2011, mais à ce jour, Internet Archive Canada a collaboré avec plus de 250 institutions (Internet Archive s.d.). En 2014, [https://rsc-src.ca/fr/node/3439 la Société royale du Canada (SRC)] a appelé à un programme national de numérisation pour faire entrer le patrimoine culturel et scientifique du Canada dans nouveau l'ère numérique (Beaudry 2014, p. 12). Un [https://www.rapports-cac.ca/reports/a-la-fine-pointe-du-monde-numerique-possibilites-pour-les-institutions-de-la-memoire-collective-au-canada/ rapport de 2015 du Conseil des académies canadiennes (CAC)] sur l'avenir numérique auquel sont confrontées les institutions de mémoire du Canada a noté que «&#8239;le Canada prend du retard, et d’énormes quantités d'information produites sous forme numérique risquent d'être perdues parce que bien des outils traditionnels ne sont plus adéquats&#8239;» (CCA 2015). ==Le SNPD== En 2016, Guy Berthiaume, alors bibliothécaire et archiviste du Canada, a annoncé le lancement d'une Stratégie de numérisation du patrimoine documentaire (SNPD), éclairée par les rapports de la SRC et du CAC ainsi que par des consultations avec [http://www.cdncouncilarchives.ca/f-intro.html le Conseil canadien des archives] (BAC 2016b). La SNPD a établi ses objectifs pour ses 10 premières années, notamment la numérisation de * la quasi-totalité (90 %) des documents patrimoniaux publiés avant 1917 * la moitié de toutes les monographies publiées avant 1940 * toutes les revues savantes publiées par les universités canadiennes avant 2000 * toutes les thèses des universités canadiennes avant 2000 * tous les microfilms et microfiches des institutions de mémoire canadiennes * une sélection de documents audio et audiovisuels de grande valeur * toutes les cartes historiques disponibles * toutes les ressources généalogiques d'archives (BAC 2016a). La SNPD était initialement dirigée par un comité directeur et un secrétariat à [https://www.bac-lac.gc.ca/fra/Pages/accueil.aspx Bibliothèque et Archives Canada (BAC)]. En novembre 2020, il a été annoncé que le secrétariat de la SNPD avait été transféré au [https://www.crkn-rcdr.ca/fr Réseau canadien de documentation pour la recherche (RCDR)] (SNPD 2020). À cette époque, le comité directeur de la SNPD a également été repensé en tant que [https://snpd.ca/le-comite-consultatif-de-la-snpd/ Comité consultatif] relevant d'un nouveau [https://snpd.ca/le-comite-de-direction-de-la-snpd/ Comité de direction] (SNPD 2021b). ==Les activités de la SNPD== En 2017, la SNPD a mené un projet pilote appelé Digitizing Newspapers, avec le financement de la Salamander Foundation (SNPD s.d.-b). Avec le soutien des éditeurs et des rédacteurs en chef des journaux, les numéros de trois journaux autochtones datant de 1976 à 2017 ont été numérisés et mis en ligne. En 2018, la SNPD a partagé sa [https://scnpd.files.wordpress.com/2018/03/snpd-strategie-de-contenu-ebauche.pdf Stratégie relative au contenu] et a lancé l'appel de financement pour [https://snpd.ca/2018/04/17/demande-de-financement-dans-le-cadre-de-la-snpd-pour-numeriser-vos-collections/ Numérisation des collections canadiennes], qui offrait jusqu'à 100 000 $ aux des archives, bibliothèques, musées, universités et collèges et autres des organismes du patrimoine culturel pour soutenir leurs projets de numérisation (SNPD 2018a). Il a reçu plus de 200 demandes de financement, totalisant 10 millions de dollars, une réponse qui «&#8239;ont démontré qu’il y a un intérêt pour le programme de numérisation national&#8239;» et a financé 21 projets (SNPD 2018b; 2018c). Aussi en octobre 2018, la SNPD a co-organisé [https://www.crkn-rcdr.ca/fr/atelier-conjoint-sur-le-patrimoine-documentaire-de-la-snpd-et-du-rcdr l'Atelier conjoint sur le patrimoine documentaire de la SNPD et du RCDR]. Lors de [https://www.crkn-rcdr.ca/fr/2019-conference-du-rcdr-sur-lacces-au-savoir la Conférence du RCDR sur l'accès au savoir en 2019], le RCDR et le SNPD ont tenu des sessions conjointes sur [https://vimeo.com/373462141?embedded=true&source=video_title&owner=91739283 les stratégies de numérisation au Canada], le droit d'auteur, le droit d'auteur et [https://vimeo.com/375434364?embedded=true&source=video_title&owner=91739283 les déclarations des droits]. Des sessions de mise à jour de la stratégie du SNPD ont été offertes lors des conférences virtuelles [https://vimeo.com/485986493 2020] et [https://vimeo.com/648768588 2021] du RCDR. La SNPD a également développé plusieurs [https://snpd.ca/ressources/ ressources], dont beaucoup en collaboration avec ses membres, notamment [https://scnpd.files.wordpress.com/2020/07/nhds-rightsstatements-report-2020.pdf un rapport sur le groupe de travail sur les déclarations des droits internationaux], [https://www.canada.ca/fr/reseau-information-patrimoine/services/preservation-numerique/recommandations-formats-fichier-preservation-numerique.html des recommandations sur les formats de fichiers pour la préservation numérique] de divers supports et [https://scnpd.files.wordpress.com/2019/05/snpd-pratiques-exemplaires-et-recommandations-2019.pdf un ensemble de meilleures pratiques pour la numérisation]. Le comité exécutif de la SNPD mène actuellement [https://snpd.ca/processus-de-planification-strategique-de-la-snpd/ un processus de planification stratégique] en cinq étapes. L'étape 1 impliquait une consultation, y compris un sondage communautaire et une série d'appels avec communautaires et des parties prenantes. À l'étape 2, actuellement en cours, le Comité de direction et le Comité consultatif et un groupe de travail technique s'appuieront sur le rapport des consultations pour identifier les objectifs, les priorités, les activités et les initiatives à inclure dans le nouveau plan stratégique. À l'étape 3, le Comité de direction élaborera un ébauche de plan stratégique qui, à l'étape 4, sera partagé avec la communauté pour consultation, rétroaction et révision. À l'étape 5, prévue pour 2022, le plan finalisé sera partagé (SNPD s.d.-c.). ==La SNPD dans la presse== De nombreuses activités de la SNPD ont été couvertes dans la presse académique et populaire. Par exemple, [https://winnipeg.ctvnews.ca/province-digitizing-centuries-old-trading-post-records-to-mark-manitoba-150-1.4317365 un article de CTV News] met en lumière la numérisation [https://www.gov.mb.ca/chc/archives/hbca/index.fr.html des Archives de la Compagnie de la Baie d'Hudson], qui sont maintenant librement accessibles dans le cadre des Archives du Manitoba (Charron 2019). Un article de [https://www.cbc.ca/news/entertainment/digitization-culture-pandemic-1.6015861 CBC News] sur la façon dont la pandémie a conduit à une numérisation accrue des documents du patrimoine culturel mondial note que le gouvernement canadien soutient des initiatives de numérisation depuis des années, y compris la SNPD, et que le budget fédéral du Canada pour 2021 comprend un financement pour la numérisation des documents du patrimoine culturel (Panetta 2021). Plusieurs projets financés par l'appel de financement Numérisation des collections canadiennes de la SNPD ont également été couverts dans la presse. Un article dans [https://www.affairesuniversitaires.ca/articles-de-fond/article/les-archives-a-lere-de-la-numerisation-et-de-la-decolonisation/?_ga=2.99724830.1629680361.1644268837-1326693258.1641858361 ''Affaires universitaires''] souligne des sérieux efforts des institutions canadiennes, y compris BAC et le SNPD, pour numériser les documents du patrimoine culturel, y compris le projet financé par le SNPD Healing and Education Through Digital Access (Thorkelson 2019). Il s'agit d'un partenariat entre [http://shingwauk.org/srsc/ le Shingwauk Residential Schools Centre] et [https://library.algomau.ca/ la bibliothèque de l'Université Algoma] qui a numérisé [http://archives.algomau.ca/main/?q=node%2F30854 les dossiers du Shingwauk Residential School], un bâtiment qui abrite maintenant l'Université Algoma. Soulignant le rôle important que les institutions de mémoire et les professionnels des bibliothèques et des archives doivent jouer dans la décolonisation, l'article note que rendre ce matériel librement disponible nous permet de demander des autres types de questions comme une communauté de professionnels de l’information sur ce que signifie partager ces éléments en contexte de l'histoire de la violence coloniale et l'utilisation abusive et le vol de matériel aux peuples autochtones (Thorkelson 2019). Ce projet a également été couvert dans ''SooToday'', un site Web de nouvelles local de Sault Ste. Marie, et sur le blog de [https://www.feathersofhope.ca/digital-archives-project-results-released-national-heritage-digitization-strategy-provides-funding-to-shingwauk-residential-schools-centre/ Feathers of Hope], une initiative de soutien et d'autonomisation des jeunes des Premières Nations en Ontario, soulignant l'importance de ce projet de numérisation pour les communautés concernées. Un article de [https://www.cbc.ca/news/canada/british-columbia/after-decades-in-boxes-vancouver-s-lgbtq-archive-now-has-a-home-1.5345714 CBC News] traite de la numérisation des [https://searcharchives.vancouver.ca/bc-gay-and-lesbian-archives BC Gay and Lesbian Archives], également financée dans le cadre de l'appel de financement Numérisation des collections canadiennes de la SNPD. Cette collection de milliers de photos, d'œuvres multimédias, d'affiches et d'autres matériaux recueillis par Ron Dutton pendant près de quatre décennies et donnés aux archives de la ville de Vancouver en 2013 (Ghoussoub 2019). [https://www.cbc.ca/news/canada/prince-edward-island/pei-newspaper-archive-1.4874414 CBC News] a également mis en lumière le projet de numérisation des journaux de l'Université de l'Île-du-Prince-Édouard, financé dans le cadre du même appel. Grâce à ce projet, deux journaux du XIXe siècle, dont le premier journal français de l'Île-du-Prince-Édouard, ont été numérisés et ajoutés à [https://islandnewspapers.ca/nhds IslandNewspapers.ca] (Yarr 2019). ==SNPD et le partenariat INKE== Le transfert du secrétariat de la SNPD au RCDR, un partenaire d'INKE, a été l'aboutissement d'un partenariat de longue date entre les deux organisations. Clare Appavoo, directrice générale du RCDR, siège aux comités directeurs de la SNPD depuis sa création, et la numérisation et la préservation du patrimoine documentaire canadien sont au cœur des travaux du RCDR, comme le montre de sa fusion avec Canadiana en 2018 (Bengtson et Shepstone 2020 ; voir également «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Plan Stratégique 2019–2024 du CRKN–RCDR|Plan stratégique 2019-2024 du CRKN–RCDR]]&#8239;» et «&#8239;[https://ospolicyobservatory.uvic.ca/reponse-des-partenaires-au-plan-strategique-2019-2024-du-crkn-rcdr/ Réponse des partenaires au plan stratégique 2019-2024 du CRKN–RCDR]&#8239;»). [https://www.carl-abrc.ca/fr/ L'ABRC] est un autre partenaire INKE qui entretient des liens étroits avec la SNPD. Parmi ses [https://www.carl-abrc.ca/wp-content/uploads/2016/03/CARL_Budget_2018_brief-final_fr.pdf recommandations pour le budget fédéral de 2018], le gouvernement «&#8239;investir 30 M$ au cours des cinq prochaines années (2018-2022) afin d’appuyer une initiative nationale coordonnée de numérisation du riche patrimoine documentaire du Canada, et de concevoir l'infrastructure numérique requise pour rendre ce matériel accessible à tous les Canadiens&#8239;» (ABRC 2017, 1). L'ABRC est actuellement représentée au SNPD par Jonathan Bengtson (Bibliothèques de l'Université de Victoria), qui est président de son comité exécutif (ABRC s.d.). Bengtson a présenté une conférence intitulée «&#8239;Five Years Makes All the Difference: Towards a Canadian National Heritage Digitalization Strategy&#8239;» lors d'un panel présenté lors de [https://inke.ca/putting-open-social-scholarship-into-practice/abstracts/ Putting Open Social Scholarship into Practice], le rassemblement annuel du Partenariat INKE, en décembre 2021. ==Le SNPD et la communauté universitaire élargie== Les stratégies de numérisation du Canada sont également un sujet d'intérêt pour l'ensemble de la communauté universitaire. En 2016, Michael Geist a fait valoir que l'incapacité du Canada à adopter une stratégie nationale de numérisation cohérente a été une source de frustration, donnant l’impression que le pays prend du retard. Il reproche au SNPD de ne pas en faire assez, comparant sa vision à une bibliothèque abandonnée avec des étagères vides de tout sauf de vieux livres. En comparant le SNPD à d'autres stratégies nationales de numérisation, Geist soutient que les obstacles juridiques et financiers qui sont souvent cités ne sont pas aussi insurmontables qu'ils le paraissent, et qu'une initiative dirigée par le gouvernement qui rassemble des ressources publiques et privées c’est le bonne voie à suivre (Geist 2016). [https://allanamayer.tumblr.com/post/149368526957/the-national-heritage-defeatist-strategy Allana Mayer] a répondu aux critiques de Geist en soulignant que les risques financiers pour les bibliothèques et les archives liés à la numérisation et à la distribution d'œuvres potentiellement protégées par le droit d'auteur sont prohibitifs (voir également «&#8239;[https://ospolicyobservatory.uvic.ca/la-prolongation-de-la-periode-de-protection-du-droit-dauteur-en-canada-en-vertu-de-laccord-canada-etats-unis-mexique-aceum/ La prolongation de la période de protection du droit d’auteur en Canada en vertu de l’Accord Canada–États-Unis–Mexique (ACEUM)]&#8239;»), et que le partenariat avec le secteur privé comporte ses propres risques, tels que le «&#8239;paywalling&#8239;» des matériaux du patrimoine culturel public (2016). Mayer note que le budget fédéral de 2016 n'offrait aucune augmentation du financement de BAC, qui a été réduit de 10 millions de dollars de 2012 à 2015 (2016). En effet, les revenus du SNPD ne comprennent que les dons, et son travail est effectué par des membres bénévoles (SNPD s.d.-a). L’article «&#8239;[https://journals.lib.unb.ca/index.php/scl/article/view/26269/1882519038 Survival: Canadian Scholarship in a Digital Age]&#8239;» de Susan Brown appelle également à un soutien national solide pour la numérisation et la préservation des documents du patrimoine canadien. Elle note que, bien que la situation au Québec soit moins désastreuse, en Canada anglais l'ABRC, le RCDR et BAC luttent pour coordonner une programme fédéral sans l'appui du gouvernement. Sans archives nationales dynamiques et bien soutenues, elle argumente, les archives de la culture canadienne seront dispersés et inégales (2018). ==Le SNPD et la science ouverte== Les valeurs directrices du SNPD s'alignent bien sur le mouvement Science ouverte. Sa vision est «&#8239;un avenir dans lequel l'accès Web au riche patrimoine documentaire numérique du Canada est complet et répandu tout en ayant des répercussions importantes sur la culture, l'éducation, la recherche et l'innovation canadiennes&#8239;» et les principes comprennent l'accès, l'ouverture, la collaboration, la durabilité et la liberté intellectuelle (SNPD s.d-a, p. 2–3). Le 15 octobre, lors de la session de mise à jour de la SNPD de la Conférence virtuelle 2021 du RCDR, Bengtson et Carole Urbain ont fait rapport sur les résultats de la consultation entreprise dans le cadre du processus de planification stratégique. Ils ont noté que l'accès était la plus grande priorité identifiée par la communauté et que les plus petites institutions et les sociétés historiques étaient particulièrement intéressées par les infrastructures et les meilleures pratiques (RCDR 2021). Bengtson a noté que d'autres thèmes découlant de la consultation communautaire sont également directement liés à la science ouverte, notamment la préservation, le partage des ressources et la coordination du travail, la création de normes, le financement et le renforcement de la diversité. Dans l'ensemble, Bengtson et Urbain ont mis l'accent sur l'élimination des obstacles à l'engagement avec la communauté au sens large comme un thème important pour guider les activités futures de la SNPD. ==Ouvrages Citées== *ABRC (Association des bibliothèques de recherche du Canada). 2017. ''Budget fédéral de 2018 – Mémoire de l’ABRC au Comité permanent des finances de la Chambre des communes''. 4 août 2017. [https://www.carl-abrc.ca/wp-content/uploads/2016/03/CARL_Budget_2018_brief-final_fr.pdf https://www.carl-abrc.ca/wp-content/uploads/2016/03/CARL_Budget_2018_brief-final_fr.pdf]. *ABRC (Association des bibliothèques de recherche du Canada). n.d. «&#8239;Partenaires et relations&#8239;». [https://www.carl-abrc.ca/fr/a-propos-de-labrc/partenaires-et-relations/ https://www.carl-abrc.ca/fr/a-propos-de-labrc/partenaires-et-relations/]. *BAC (Bibliothèque et Archives Canada). 2016a. «&#8239;Stratégie canadienne de numérisation du patrimoine documentaire&#8239;». [https://www.bac-lac.gc.ca/fra/a-notre-sujet/Pages/strategie-canadienne-numerisation.aspx https://www.bac-lac.gc.ca/fra/a-notre-sujet/Pages/strategie-canadienne-numerisation.aspx]. *BAC (Bibliothèque et Archives Canada). 2016b. «&#8239;Le bibliothècaire et archiviste du Canada annonce la création de la Stratégie nationale de numérisation du patrimoine documentaire&#8239;». 4 juin 2016. ''Internet Archive''. [https://web.archive.org/web/20170224195940/http:/nouvelles.gc.ca/web/article-fr.do?nid=1079789 https://web.archive.org/web/20170224195940/http://nouvelles.gc.ca/web/article-fr.do?nid=1079789]. *Beaudry, Guylaine, et al. 2014. ''The Future Now: Canada’s Libraries, Archives, and Public Memory''. La Société royale du Canada. [https://rsc-src.ca/sites/default/files/L%26A_Report_EN_FINAL_Web.pdf https://rsc-src.ca/sites/default/files/L%26A_Report_EN_FINAL_Web.pdf]. *Bengtson, Jonathan, et Carol Shepstone. 2020. «&#8239;‘Tourner en commun’: La fusion de Canadiana.org avec le Réseau canadien de documentation pour la recherche/Canadian Research Knowledge Network&#8239;». ''Partnership'' 15, no. 1. [https://doi.org/10.21083/partnership.v15i1.6110 https://doi.org/10.21083/partnership.v15i1.6110]. *Brown, Susan. 2018. «&#8239;Survival: Canadian Cultural Scholarship in a Digital Age&#8239;». ''Studies in Canadian Literature / Études en littérature canadienne''. [https://journals.lib.unb.ca/index.php/SCL/article/view/26269/1882519038 https://journals.lib.unb.ca/index.php/SCL/article/view/26269/1882519038]. *CAC (Conseil des académies canadiennes). 2015. ''À la fine pointe du monde numérique : possibilités pour les institutions de la mémoire collective au Canada''. 4 février 2015. [https://www.rapports-cac.ca/reports/a-la-fine-pointe-du-monde-numerique-possibilites-pour-les-institutions-de-la-memoire-collective-au-canada/ https://www.rapports-cac.ca/reports/a-la-fine-pointe-du-monde-numerique-possibilites-pour-les-institutions-de-la-memoire-collective-au-canada/]. *Calamai, Peter. 2007. «&#8239;Archivists Embrace Digital Page&#8239;». ''Toronto Star'', 16 april 2007, [https://www.thestar.com/news/2007/04/16/archivists_embrace_digital_page.html https://www.thestar.com/news/2007/04/16/archivists_embrace_digital_page.html]. *Casey, Liam. 2011. «&#8239;Toronto Online Book Archive Forced to Fire 75% of Staff&#8239;». ''Toronto Star'', 8 juillet 2011. [https://www.thestar.com/news/gta/2011/07/08/toronto_online_book_archive_forced_to_fire_75_of_staff.html https://www.thestar.com/news/gta/2011/07/08/toronto_online_book_archive_forced_to_fire_75_of_staff.html]. *Charron, Jeremie. 2019. «&#8239;Province Digitizing Centuries-old Trading Post Records to Mark Manitoba 150&#8239;». ''CTV News'', 28 février 2019. [https://winnipeg.ctvnews.ca/province-digitizing-centuries-old-trading-post-records-to-mark-manitoba-150-1.4317365 https://winnipeg.ctvnews.ca/province-digitizing-centuries-old-trading-post-records-to-mark-manitoba-150-1.4317365]. *Geist, Michael. 2016. «&#8239;Why Canada’s E-Library is Barren&#8239;». ''The Tyee'', 26 juillet 2021. [https://thetyee.ca/Mediacheck/2016/07/26/Canadas-E-Library-Is-Barren/ https://thetyee.ca/Mediacheck/2016/07/26/Canadas-E-Library-Is-Barren/]. *Ghoussoub, Michelle. 2012. «&#8239;After Decades in Boxes, Vancouver’s LGBTQ Archive Now has a Home&#8239;». ''CBC News''. 3 novembre 2021. [https://www.cbc.ca/news/canada/british-columbia/after-decades-in-boxes-vancouver-s-lgbtq-archive-now-has-a-home-1.5345714 https://www.cbc.ca/news/canada/british-columbia/after-decades-in-boxes-vancouver-s-lgbtq-archive-now-has-a-home-1.5345714.] *Mayer, Allana. 2016. «&#8239;The National Heritage Defeatist Strategy&#8239;». 23 août 2016. [https://allanamayer.tumblr.com/post/149368526957/the-national-heritage-defeatist-strategy https://allanamayer.tumblr.com/post/149368526957/the-national-heritage-defeatist-strategy]. *Panetta, Alexander. 2021. «&#8239;A World of Art at our Fingertips: How COVID-19 Accelerated the Digitization of Culture&#8239;». ''CBC News''. 8 mai 2021. [https://www.cbc.ca/news/entertainment/digitization-culture-pandemic-1.6015861 https://www.cbc.ca/news/entertainment/digitization-culture-pandemic-1.6015861]. *RCDR (Réseau candien de documentation pour la recherche). 2021. «&#8239;2021 CRKN Virtual Conference – 15 October 2021 – National Heritage Digitization Strategy (NHDS) Update&#8239;». Vidéo, 29:53. 15 octobre 2021. [https://vimeo.com/648768588 https://vimeo.com/648768588]. *SNPD (Stratégie de numérisation du patrimoine documentaire). n.d.-a. ''Plan d’activités 2018–2019''. [https://scnpd.files.wordpress.com/2018/09/snpd-plan-dactivitc3a9s-2018-19.pdf https://scnpd.files.wordpress.com/2018/09/snpd-plan-dactivitc3a9s-2018-19.pdf]. *SNPD (Stratégie de numérisation du patrimoine documentaire). n.d.-b. «&#8239;Numérisation de journaux dans le cadre de la SNPD&#8239;». [https://snpd.ca/plan-daction/numerisation-de-certains-journaux-dans-le-cadre-du-projet-pilote-de-la-snpd/ https://snpd.ca/plan-daction/numerisation-de-certains-journaux-dans-le-cadre-du-projet-pilote-de-la-snpd/]. *SNPD (Stratégie de numérisation du patrimoine documentaire). n.d.-c. «&#8239;Processus de planification stratégique de la SNPD&#8239;». [https://snpd.ca/processus-de-planification-strategique-de-la-snpd/ https://snpd.ca/processus-de-planification-strategique-de-la-snpd/]. *SNPD (Stratégie de numérisation du patrimoine documentaire). 2018a. «&#8239;Demande de financement dans le cadre de la SNPD pour numériser vos collections&#8239;». 17 april 2018. [https://snpd.ca/2018/04/17/demande-de-financement-dans-le-cadre-de-la-snpd-pour-numeriser-vos-collections/ https://snpd.ca/2018/04/17/demande-de-financement-dans-le-cadre-de-la-snpd-pour-numeriser-vos-collections/]. *SNPD (Stratégie de numérisation du patrimoine documentaire). 2018b. «&#8239;Mise à jour d’automne de la Stratégie de numérisation du patrimoine documentaire&#8239;». 21 septembre 2018. [https://snpd.ca/2018/09/21/mise-a-jour-dautomne-de-la-strategie-de-numerisation-du-patrimoine-documentaire/ https://snpd.ca/2018/09/21/mise-a-jour-dautomne-de-la-strategie-de-numerisation-du-patrimoine-documentaire/]. *SNPD (Stratégie de numérisation du patrimoine documentaire). 2018c. «&#8239;Stratégie de numérisation du patrimoine documentaire : 21 demandes de financement approuvées dans l’ensemble du Canada&#8239;». 16 octobre 2018. [https://snpd.ca/2018/10/16/strategie-de-numerisation-du-patrimoine-documentaire-21-demandes-de-financement-approuvees-dans-lensemble-du-canada/ https://snpd.ca/2018/10/16/strategie-de-numerisation-du-patrimoine-documentaire-21-demandes-de-financement-approuvees-dans-lensemble-du-canada/]. *SNPD (Stratégie de numérisation du patrimoine documentaire). 2020. «&#8239;Transfert du secrétariat de la SNPD au RCDR&#8239;». 4 novembre 2020. [https://snpd.ca/2020/11/04/transfert-du-secretariat-de-la-snpd-au-rcdr/ https://snpd.ca/2020/11/04/transfert-du-secretariat-de-la-snpd-au-rcdr/]. *SNPD (Stratégie de numérisation du patrimoine documentaire). 2021b. «&#8239;Prochaines étapes de la SNPD : mise à jour sur la gouvernance et la planification stratégique&#8239;». 7 juin 2021. [https://snpd.ca/2021/06/07/prochaines-etapes-de-la-snpd-mise-a-jour-sur-la-gouvernance-et-la-planification-strategique/ https://snpd.ca/2021/06/07/prochaines-etapes-de-la-snpd-mise-a-jour-sur-la-gouvernance-et-la-planification-strategique/]. *Thorkelson, Erika. 2019. «&#8239;Les archives a l’ère de la numérisation et de la décolonisation&#8239;». ''Affaires universitaires.'' 18 septembre 2019. [https://www.affairesuniversitaires.ca/articles-de-fond/article/les-archives-a-lere-de-la-numerisation-et-de-la-decolonisation/?_ga=2.2862896.1629680361.1644268837-1326693258.1641858361 https://www.affairesuniversitaires.ca/articles-de-fond/article/les-archives-a-lere-de-la-numerisation-et-de-la-decolonisation/?_ga=2.2862896.1629680361.1644268837-1326693258.1641858361]. *Yarr, Kevin. 2018. «&#8239;From Confederation to the Great War: P.E.I. Digital Newspaper Collection Expanding&#8239;». 23 octobre 2018. [https://www.cbc.ca/news/canada/prince-edward-island/pei-newspaper-archive-1.4874414 https://www.cbc.ca/news/canada/prince-edward-island/pei-newspaper-archive-1.4874414]. [[Catégorie:Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024 (livre)]] 41tudw47r3bjms15b1gxxx1w9s55uqn Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/La Collaboration entre l’ABRC et OpenAIRE 0 82357 744017 742409 2025-06-02T22:33:21Z LodestarChariot2 120009 /* Ouvrages citées */ 744017 wikitext text/x-wiki ''Cette observation a été écrit par Caroline Winter (avec remerciements à Kathleen Shearer et Martha Whitehead pour ses commentaires et contribution), pour le Electronic Textual Cultures Laboratory et le partenariat Implementing New Knowledge Environments.'' En janvier 2018, [https://www.carl-abrc.ca/fr/ l'Association des bibliothèques de recherche du Canada (ABRC)] a entamé une [https://www.carl-abrc.ca/fr/faire-avancer-la-recherche/depots-institutionnels/groupe-de-travail-depots-ouverts/collaboration-avec-openaire/ collaboration] avec [https://www.openaire.eu/ OpenAIRE], une organisation européenne d'infrastructure de science ouverte, dans le but d'améliorer la visibilité de la recherche canadienne. L'un des résultats de cette collaboration est [https://canada.explore.openaire.eu/ Canada Explore], un portail de recherche dans les dépôts institutionnels canadiens. Cette collaboration et le portail qui en résulte contribuent aux efforts de l'ABRC pour rendre les résultats de recherche disparates du Canada disponibles via une interface unique, dans le cadre d'une infrastructure de communication savante distribuée et en réseau mondial. La collaboration augmentera la découvrabilité de la recherche canadienne, avec un accent initial sur les travaux financés par les trois organismes du Canada, comprenant [https://cihr-irsc.gc.ca/f/193.html les Instituts de recherche en santé du Canada (IRSC)], [https://www.nserc-crsng.gc.ca/index_fra.asp le Conseil de recherches en sciences naturelles et en génie du Canada (CRSNG)] et [https://www.sshrc-crsh.gc.ca/home-accueil-fra.aspx le Conseil de recherche en sciences humaines (CRSH)]. L'un de ses principaux objectifs est de saisir les relations avec les subventionnaires afin de permettre le suivi de la conformité à [https://www.ic.gc.ca/eic/site/063.nsf/fra/h_F6765465.html la Politique des trois organismes sur le libre accès aux publications] (ABRC s.d-b ; voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Politique des trois organismes sur le libre accès aux publications|Politique des trois organismes sur le libre accès aux publications]]&#8239;» et «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Conformité à la politique de libre accès au Canada|Conformité à la politique de libre accès au Canada]]&#8239;»). Cela permettra également d'avoir une vision plus claire du paysage du libre accès au Canada. La collaboration entre ABRC et OpenAIRE, coordonnée par le [https://www.coar-repositories.org/ Confederation of Open Access Repositories (COAR)], a été lancée dans le cadre du projet [https://www.openaire.eu/advance/ Advance] d'OpenAIRE, un projet financé par la Commission européenne qui vise à promouvoir l'érudition ouverte dans un contexte mondial grâce à des collaborations avec des parties prenantes en Afrique, Canada, Japon, Amérique latine et des États-Unis (OpenAIRE 2018). ==OpenAIRE== OpenAIRE (Open Access Infrastructure for Research in Europe) a été fondée en 2008 par la Commission européenne pour promouvoir et soutenir la mise en œuvre des directives du [https://erc.europa.eu/sites/default/files/document/file/ERC_Open_Access_Guidelines-revised_Dec_2021.pdf European Research Council’s Open Access Guidelines] de la recherche pour le libre accès et du [https://ec.europa.eu/commission/presscorner/detail/fr/MEMO_08_548 septième programme-cadre de recherche (FP7)] de la Commission européenne, qui exigeait que tous les résultats de la recherche financée doivent être librement accessibles soit par l'intermédiaire d'une revue, soit par l'intermédiaire d'un dépôt. OpenAIRE, devenue une entité juridique, fournit un certain nombre de services, dont [http://catalogue.openaire.eu/service/openaire.usage_statistics le service de métriques OpenAIRE] et des tableaux de bord institutionnels, communautaires et subventionnaires. Il fournit également [https://www.openaire.eu/noad-activities?highlight=WyJub2FkIl0= des bureaux nationaux de libre accès], qui sont des services d'assistance aux politiques qui offrent une formation et un soutien aux chercheurs et aux institutions pour le partager de leurs travaux dans des dépôts. En outre, il offre une infrastructure de recherche numérique sous la forme de [https://zenodo.org/ Zenodo], un dépôt ouvert pour toutes les disciplines développé avec le [https://home.cern/fr CERN], ainsi que des normes de liaison des données, grâce à l'adoption d'identifiants persistants qui aident à lever l'ambiguïté des organisations de recherche (voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/ORCID : Connecter la recherche et les chercheurs|ORCID : Connecter la recherche et des chercheurs]]&#8239;» et «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Le Persistent Identifier (PID) Consortium de Royaume-Uni|Le «&#8239Persistent Identifier (PID) Consortium&#8239;» de Royaume-Uni]]&#8239;»). [https://graph.openaire.eu/ Le plate-forme OpenAIRE] agrège les métadonnées de milliers de fournisseurs de contenu (par exemple, Zenodo, arXiv, les revues en libre accès) ainsi que des registres d'entités (par exemple, ORCID, CrossRef) pour créer le base de données, au-dessus duquel les services d'OpenAIRE sont construits. Grâce à [https://explore.openaire.eu/ OpenAIRE Explore], les utilisateurs peuvent rechercher et trouver des publications, des projets de recherche, des données de recherche, des organismes de recherche, des dépôts et d'autres fournisseurs de contenu (OpenAIRE s.d.). ==Le portail Explore Canada== [https://canada.explore.openaire.eu/ Canada Explore] est un portail personnalisé pour la recherche canadienne qui affiche un sous-ensemble du base de données d'OpenAIRE (OpenAIRE 2021). Il fournit une vue de tous les enregistrements dans le base de données avec une affiliation avec des auteurs, des institutions ou des subventionnaires au Canada. Le portail utilise les capacités d'exploration de données d'OpenAIRE pour capturer les relations avec les subventionnaires et d'autres points de données à partir du texte intégral des publications qui ne sont pas capturées dans les métadonnées. Par exemple, en octobre 2021, le portail affichait 55 595 résultats financés par l’IRSC, dont 37 671 ont été découverts grâce à l'exploration de texte (ABRC 2021, 24:05). Afin de soutenir l'inclusion des collections de dépôts canadiens dans le base de données d’OpenAIRE, [https://www.carl-abrc.ca/fr/faire-avancer-la-recherche/depots-institutionnels/groupe-de-travail-depots-ouverts/ le Groupe de travail sur les dépôts ouverts] de l'ABRC travaille avec les institutions canadiennes pour s'assurer que leurs dépôts peuvent être récoltés par OpenAIRE. Cela nécessite que les dépôts soient conformes aux [https://guidelines.openaire.eu/en/latest/ directives OpenAIRE 4.0], qui dictent un certain format pour les métadonnées. Les dépôts de littérature qui ne sont pas en mesure de devenir conformes à OpenAIRE peuvent s'assurer que leurs métadonnées sont récoltées indirectement par l'intermédiaire du [https://canadaresearch.mcmaster.ca/handle/123456789/1?locale=fr Canada Research Aggregator], développé par les bibliothèques de l'Université McMaster. Les dépôts de données canadiens sont mis à la disposition d'OpenAIRE par l'intermédiaire du service de découverte du [https://www.frdr-dfdr.ca/repo/?locale=fr Dépôt fédéré de données de recherche (DFDR)] (CARL s.d.-a). Pour soutenir une plus grande participation à OpenAIRE, le Groupe de travail sur les dépôts ouverts développe des documents pour aider les gestionnaires de dépôts, et l'ABRC a proposé une série de webinaires liés à la collaboration ABRC-OpenAIRE : * [https://www.youtube.com/watch?v=i5pmEfn9G4U À la recherche d’une aiguille dans une botte de foin : Accroître la visibilité international de la recherche Canadienne grâce à la collaboration entre l’ABRC et OpenAIRE] (26 octobre 2021) * [https://www.youtube.com/watch?v=8uG13dMzc7A La collaboration ABRC-OpenAIRE : Que faut-il faire dans nos établissements pour y participer?] (26 novembre 2021) * [https://www.youtube.com/watch?v=H-MrsuYU8WE&t=5s Webinaire pour les responables de dépôt : Mise a jour sur la collaboration entre l’ABRC et OpenAIRE] (2 décembre 2020) ==La collaboration CARL–OpenAIRE et la communauté INKE== En plus de l'ABRC, la collaboration implique le CRSH, un partisan de l'INKE et membre des trois organismes. Matthew Lucas, directeur exécutif, Stratégie et rendement organisationnels au CRSH, note que la collaboration CARL-OpenAIRE est essentielle pour rendre la recherche canadienne plus ouverte et plus utilisable et pour améliorer la conformité à la politique des trois organismes sur le libre accès (CARL 2021). En plus de faciliter le suivi de la conformité à la politique, ces données peuvent également aider les trois organismes à déterminer quels obstacles à la conformité existent, comment ils peuvent être surmontés et comment mieux surveiller la conformité. ==La collaboration CARL-OpenAIRE et la communauté universitaire élargie== En plus des avantages qu'elle apporte à la communauté canadienne, la collaboration CARL-OpenAIRE contribue également à la communauté plus large. Par exemple, dans le cadre du projet, le Groupe de travail sur les dépôts ouverts de l'ABRC a lancé le développement d'un plugin pour [https://duraspace.org/dspace/ DSpace] 5 et 6, des plates-formes de dépôt largement utilisées, pour permettre la conformité aux directives OpenAIRE. Cette extension a été dirigée et financée par la bibliothèque de l'Université Queen's avec un financement supplémentaire de l'Université de la Colombie-Britannique, de l'Université Laval, de l'Université de Montréal, de l'Université de la Saskatchewan, de l'Université de l'île de Vancouver et de l'Université York. Ce plugin est disponible pour tous les dépôts DSpace et permettra aux dépôts du monde entier de se conformer plus facilement aux directives OpenAIRE, qui sont également [https://www.coalition-s.org/plan-s-practical-advice/ recommandées pour les dépôts faisant partie du Plan S] (CARL 2019 ; CARL 2020 ; voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Plan S et cOAlition S|Plan S et cOAlition S]]&#8239;»). ==La collaboration CARL-OpenAIRE et la science ouverte== La collaboration entre l'ABRC et OpenAIRE met en évidence le rôle de l'infrastructure dans l'avancement de la science ouverte. Une infrastructure ouverte et dirigée par la communauté telle qu'OpenAIRE offre une plus grande transparence autour de la fourniture de services, ainsi qu'une couche importante de gouvernance communautaire. Vivian Lewis, présidente de l'ABRC, note que l'infrastructure ouverte et dirigée par la communauté est une partie importante de la vision décrite dans [https://www.carl-abrc.ca/wp-content/uploads/2018/03/CARL_ScholComm_Roadmap_FR.pdf ''la Feuille de route de l’ABRC sur la communication savante''] et [https://unesdoc.unesco.org/ark:/48223/pf0000379949.locale=fr ''la Recommendation de l'UNESCO sur une science ouverte''] (ABRC 2021 ; voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Feuille de route sur la communication savante de l'ABRC|Feuille de route sur la communication savante de l'ABRC]]&#8239;» et «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/La Recommandation de l’UNESCO sur la science ouverte|La Recommandation de l'UNESCO sur la science ouverte]]&#8239;»). Le développement et l'optimisation de cette infrastructure nécessitent l'adoption généralisée de normes de métadonnées, de vocabulaires et d'identificateurs persistants, et ceux-ci sont destinés au portail Canada Explore et à l'ouverture de la recherche plus largement. Ce projet met en évidence la nature mondiale de la science ouverte. Comme indiqué dans un article [https://www.affairesuniversitaires.ca/actualites/actualites-article/des-organismes-subventionnaires-priorisent-la-gestion-des-donnees-de-recherche/?_ga=2.135693940.45428248.1645808203-1326693258.1641858361 d’''Affaires universitaires''] sur [https://science.gc.ca/eic/site/063.nsf/fra/h_97610.html ''la Politique des trois organismes sur la gestion des données de recherche''], par exemple, la collecte de [https://portagenetwork.ca/fr/nouvelles/metadonnees-du-dfdr-moissonnees-par-openaire/ métadonnées DFDR] dans le base de données d'OpenAIRE a rendu la recherche canadienne visible et accessible à la communauté internationale (Voinigescu 2021). Natalia Manola, PDG d'OpenAIRE, note que la recherche est mondiale : la recherche qui trouve son origine en Europe ou en Canada n’y reste pas. Ce qu'il faut, c'est une infrastructure mondiale ouverte avec des nœuds décentralisés, avec des responsabilités, ressources et gouvernance partagée (CARL 2021, 19:50). À titre d'exemple, en améliorant la découvrabilité et l'interopérabilité des résultats de la recherche canadienne, le portail accroît sa visibilité dans le paysage mondial de la recherche. ==Ouvrages citées== *ABRC (Association des bibliothèques de recherche du Canada). 2019. «&#8239;Collaboration pour une plus grande visibilité et pour améliorer la découvrabilité de l’érudition ouverte – l’extension de DSpace 5 et 6 permettra bientôt de supporter les nouvelles lignes directrices liées à OpenAIRE&#8239;». 2 décembre 2019. CARL. [https://www.carl-abrc.ca/fr/nouvelles/extension-dspace-5-6-conformite-openaire/ https://www.carl-abrc.ca/fr/nouvelles/extension-dspace-5-6-conformite-openaire/]. *ABRC (Association des bibliothèques de recherche du Canada). 2020. «&#8239;Collaboration pour une plus grande visibilité et pour améliorer la découvrabilité de la science ouverte – l’extension de DSpace 5 et 6 est maintenant disponible pour supporter les nouvelles lignes directrices liées à ORCID et à OpenAIRE&#8239;». 20 mai 2020. [https://www.carl-abrc.ca/fr/nouvelles/sortie-extension-dspace-openaire/ https://www.carl-abrc.ca/fr/nouvelles/sortie-extension-dspace-openaire/]. *ABRC (Association des bibliothèques de recherche du Canada). «&#8239;CARL–OpenAIRE Collaboration Webinar (Oct. 26 2021)&#8239;». YouTube, 1 novembre 2021. [https://www.youtube.com/watch?v=i5pmEfn9G4U https://www.youtube.com/watch?v=i5pmEfn9G4U]. *ABRC (Association des bibliothèques de recherche du Canada). s.d.-a. «&#8239;Comment pouvez-vous participer ?&#8239;» [https://www.carl-abrc.ca/fr/faire-avancer-la-recherche/depots-institutionnels/groupe-de-travail-depots-ouverts/collaboration-avec-openaire/comment-pouvez-vous-participer/ https://www.carl-abrc.ca/fr/faire-avancer-la-recherche/depots-institutionnels/groupe-de-travail-depots-ouverts/collaboration-avec-openaire/comment-pouvez-vous-participer/]. *ABRC (Association des bibliothèques de recherche du Canada). s.d.-b. «&#8239;En quoi ce projet est-il important ?&#8239;» [https://www.carl-abrc.ca/fr/faire-avancer-la-recherche/depots-institutionnels/groupe-de-travail-depots-ouverts/collaboration-avec-openaire/importance/ https://www.carl-abrc.ca/fr/faire-avancer-la-recherche/depots-institutionnels/groupe-de-travail-depots-ouverts/collaboration-avec-openaire/importance/]. *OpenAIRE. 2018. «&#8239;OpenAIRE Advance&#8239;». 20 avril 2018. [https://www.openaire.eu/openaire-advance-project https://www.openaire.eu/openaire-advance-project]. *OpenAIRE. 2021. «&#8239;CANADA.EXPLORE: Discovering Canadian Research Outputs&#8239;». 13 décembre 2021. [https://www.openaire.eu/identifying-canadian-research-outputs https://www.openaire.eu/identifying-canadian-research-outputs]. *OpenAIRE. s.d. «&#8239;About&#8239;». [https://graph.openaire.eu/about https://graph.openaire.eu/about]. *Voinigescu, Eva. 2021. «&#8239;Des organismes subventionnaires priorisent la gestion des données de recherche&#8239;». ''Affaires universitaires''. 15 juin 2021. [https://www.affairesuniversitaires.ca/actualites/actualites-article/des-organismes-subventionnaires-priorisent-la-gestion-des-donnees-de-recherche/?_ga=2.90745823.45428248.1645808203-1326693258.1641858361 https://www.affairesuniversitaires.ca/actualites/actualites-article/des-organismes-subventionnaires-priorisent-la-gestion-des-donnees-de-recherche.] [[Catégorie:Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024 (livre)]] dq9tirrro1gukisv1rzwqq2mah8ppeu Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Le Rapport sur l’infrastructure ouverte du projet Future of Open Scholarship 0 82358 744018 742410 2025-06-02T22:34:58Z LodestarChariot2 120009 /* Ouvrages citées */ 744018 wikitext text/x-wiki ''Cette observation a été écrit par Caroline Winter (avec remerciements à Janneke Adema et Virginia Barbour pour ses commentaires et contribution), pour le Electronic Textual Cultures Laboratory et le partenariat Implementing New Knowledge Environments.'' [https://investinopen.org/ Invest in Open Infrastructure (IOI)] est une organisation internationale qui recherche et défend une infrastructure de recherche ouverte et dirigée par la communauté et travaille à des modèles de financement coordonnés et durables. En août 2021, IOI a publié le rapport final du projet «&#8239;[https://investinopen.org/research/future-of-open-scholarship/ Future of Open Scholarship (FOS)]&#8239;». Ce projet de recherche vise à développer un modèle ouvert et durable pour l'infrastructure de recherche, que IOI définit sur son site Web comme l'ensemble de services, de normes, de protocoles et de logiciels dont l'écosystème universitaire a besoin pour remplir ses fonctions tout au long du cycle de vie de la recherche. IOI définit l'infrastructure ouverte comme les ensembles plus étroite de services, de normes, de protocoles et de logiciels qui permettre communautés de construire collectivement les infrastructures et les systèmes qui offrent des avantages collectifs sans restrictions, et pour un système d'infrastructure mondiale robuste (IOI sd, «&#8239;About&#8239;»). Le projet FOS aborde les risques et les défis de longue date auxquels sont confrontées les infrastructures de recherche qui ont été exacerbés par la pandémie de COVID-19, y compris un besoin en augmentant de ressources ouvertes et en ligne, des budgets de bibliothèque surchargés et des pénuries de personnel (voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Science Ouverte et COVID-19|Science Ouverte et COVID-19]]&#8239;»). ==Le rapport== Le rapport final du FOS, [https://zenodo.org/record/5218968#.Yh_1FRPMKWA ''Designing a Preparedness Model for the Future of Open Scholarship''], s'appuie sur les cadres de modélisation de la préparation aux situations d'urgence et aux catastrophes utilisés pour se préparer aux crises de santé publique ou aux catastrophes environnementales. Ces cadres traitent des risques immédiats et urgents ainsi que de la durabilité à plus long terme. En demandant comment les infrastructures de recherche peuvent être développées et financées pour assurer la réactivité à la crise et la durabilité à l'avenir, le projet a adopté une approche communautaire de sa recherche en menant des entretiens, en organisant les appels de la communauté et en animant des ateliers avec des parties prenantes travaillant dans des bibliothèques universitaires, des bibliothèques et services d'archives, universités, organismes de recherche et d'innovation, édition et autres organismes de recherche. Les ateliers ont abordé les thèmes du rôle des principes et des valeurs dans le processus de prise de décision collective et les modèles et mécanismes de financement en matière d'infrastructures de recherche. Le rapport indique que pour que la science ouverte prospère, nous devons assurer que les outils, les logiciels et les systèmes qui permettent la production et la diffusion des connaissances sont également entretenus et alignés sur les valeurs de la communauté, avec le soutien, la surveillance et des ressources adéquats. Le rapport soutient qu'une infrastructure ouverte, détenue et exploitée par la communauté est nécessaire pour s'assurer que les valeurs et les besoins de la communauté universitaire sont prioritaires et pris en compte&#8239;», puisque les infrastructures actuelles dominées par les produits commerciaux ne sont pas bien alignées sur les besoins et les valeurs de cette communauté. communauté (6). Il identifie certains défis auxquels sont confrontés les systèmes d'infrastructure ouverts, notamment «l'individualisme institutionnel», le temps nécessaire pour développer et mettre en œuvre des solutions open source par rapport aux solutions commerciales, la maintenance, l'alignement et la dotation en personnel. L'interopérabilité est devenue une préoccupation plus urgente étant donné le risque que certains systèmes d'infrastructure s'arrêtent en raison d'un manque de ressources, ce qui signifie que garantir que le contenu peut être migré est une priorité. Le rapport identifie également la résilience - la capacité d'un système à se remettre d'une crise - comme un facteur clé de succès. S'appuyant sur l'efficacité de l'action collective pour faire progresser le mouvement du libre accès (Joseph 2013), le rapport appelle à une approche similaire pour faire progresser l'infrastructure ouverte, notant que les consortiums de bibliothèques jouent un rôle important, notamment dans l'élaboration d'un programme de changement partagé. Le rapport recommande la création d'un «&#8239;Open infrastructure technology oversight committee&#8239;» comprenant des parties prenantes clés et souligne que les modèles de financement sont un élément clé pour une infrastructure de recherche ouverte durable. Enfin, le rapport présente cinq interventions recommandées, avec des mises à jour sur ce qui a été réalisé jusqu'à présent et des échéanciers futurs possibles. Ces recommandations sont, à court terme (<1 an), de * explorer des modèles permettant une plus grande interopérabilité entre les systèmes de partage d'informations * créer un comité de surveillance des technologies d'infrastructure ouverte. A moyen terme (1–2 ans+), pour * identifier les opportunités de services collectifs et de modèles de soutien pour maximiser les avantages collectifs et améliorer la résilience. Et à long terme, (3 ans+) pour * piloter un fonds de réponse rapide pour soutenir la maintenance du projet, en s'appuyant sur le projet pilote précédent * élaborer un cadre de modèle de financement pour évaluer la faisabilité d'un modèle de financement collectif, en coordonnant les efforts actuellement en cours (28–29). En plus de son rapport final, le projet FOS comprend [https://docs.google.com/spreadsheets/d/1VkxmIOFCMYHFlrY4xm05PAsklA_SXbnaTyoHI20dQfg/edit#gid=311894591 un outil de modélisation financière interactif] et [https://zenodo.org/record/5153496#.Yh_r8RPMKWA un rapport] d'accompagnement qui modélise les coûts et les avantages de l'investissement collectif dans les infrastructures ouvertes. ==Le rapport FOS et le partenariat INKE== Les membres de l'INKE sont impliqués dans plusieurs des initiatives d'infrastructure ouverte référencées dans le rapport FOS. [https://www.coalition-publi.ca/ Coalition Publica], un exemple de partenariat novateur cité dans le rapport, est une collaboration entre les partenaires INKE [https://www.erudit.org/fr/ Érudit] et [https://pkp.sfu.ca/ le Public Knowledge Project (PKP)] pour créer une infrastructure ouverte pour l'édition de revues au Canada. Cette infrastructure comprend [https://pkp.sfu.ca/ojs/ Open Journal Systems], une application de publication de revues open source développée par le PKP que le rapport cite comme un exemple d'infrastructure ouverte réussie. Les membres de l'INKE [https://www.canarie.ca/fr/rnre/ CANARIE], [https://www.carl-abrc.ca/fr/ l'Association des bibliothèques de recherche du Canada (ABRC)] et [https://portagenetwork.ca/fr/ Portage] ont apporté leur soutien à [https://dataverse.scholarsportal.info/fr/ Scholars Portal Dataverse] et à la plate-forme de dépôt de données ouvertes qui est également mentionnée comme un exemple clé d'infrastructure ouverte nécessitant un financement plus durable. Les membres de l'INKE ont également été impliqués dans diverses initiatives visant à faire progresser l'infrastructure ouverte et à améliorer sa durabilité. En mars 2019, l'ABRC et [https://www.crkn-rcdr.ca/fr le Réseau canadien de documentation pour la recherche (RCDR)] se sont joints au SCOSS, une organisation qui facilite le financement collectif d'initiatives de la science ouverte ; deux initiatives précédemment financées sont [https://v2.sherpa.ac.uk/romeo/ Sherpa/RoMEO] et [https://doaj.org/ le Directory of Open Access Journals (DOAJ)] (CARL 2019). L'adhésion au SCOSS signifie que les membres de l'ABRC et du RCDR peuvent participer à un cadre de partage des coûts coordonné (SPARC Europe 2019, 1). En juin 2021, l'ABRC et le RCDR ont co-présenté un webinaire avec SPARC intitulé [https://www.youtube.com/watch?v=GDWr6zVoA-g Perspectives des établissements par rapport aux investissements en infrastructures ouvertes], réunissant des bibliothécaires universitaires du Canada et des États-Unis pour discuter de stratégies d'investissement dans l'infrastructure ouverte. L'ABRC a également collaboré avec [https://www.openaire.eu/ OpenAIRE], une organisation européenne de la science ouverte, pour développer [https://www.openaire.eu/identifying-canadian-research-outputs Canada Explore], un portail pour la recherche canadienne basé sur le OpenAIRE plate-forme (voir «&#8239;[[Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/La Collaboration entre l’ABRC et OpenAIRE|La Collaboration entre l'ABRC et OpenAIRE]]&#8239;»). ==Le rapport FOS et la communauté universitaire élargie== Comme le reconnaît le rapport FOS, de nombreux groupes et organisations au sein de la communauté universitaire travaillent déjà à la construction d'infrastructures ouvertes. En plus de ceux mentionnés dans le rapport, d'autres groupes développent et mettent en œuvre des infrastructures, telles que l'organisation d'identificateurs persistants [https://orcid.org/ ORCID], [https://www.copim.ac.uk/ COPIM (Community-led Open Publication Infrastructures for Monographs)] et [https://www.coar-repositories.org/ COAR (Confederation of Open Access Repositories)] (voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/ORCID : Connecter la recherche et les chercheurs|ORCID : Connecter la recherche et les chercheurs]]&#8239;» ; «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/ORCID : Connecter la recherche et les chercheurs|Les monographies en libre accès]]&#8239;»). Faisant écho aux évaluations du rapport sur l'importance de la construction d'infrastructures ouvertes durables, [https://unesdoc.unesco.org/ark:/48223/pf0000379949_fre la Recommandation de l'UNESCO sur une science ouverte] reconnaît qu'en plus de ses avantages économiques, investir dans des infrastructures ouvertes permet la collaboration, améliore la réutilisation des données de recherche (et donc la réplicabilité et la reproductibilité des recherche), et promeut une plus grande égalité au sein de la communauté mondiale de la recherche (2021). La Recommandation de l'UNESCO indique également «&#8239;Investir dans les infrastructures et les services de la science ouverte&#8239;» comme l'un de ses objectifs clés (6) et appelle les infrastructures ouvertes l'un des «&#8239;piliers essentiels&#8239;» de la science ouverte (7). ==Le rapport FOS et la science ouverte== L'infrastructure ouverte est un élément clé de la science ouverte et de l'écosystème de la communication savante. Comme le note le rapport FOS, l'effondrement des infrastructures pourrait entraîner un manque de diversité dans l'écosystème si les petites presses sont contraintes de fermer, les services et outils ouverts ne peuvent plus être pris en charge et les sociétés savantes ne peuvent plus générer de revenus grâce à des événements en personne. (Thaney 2020). En plus du projet FOS, IOI développe un catalogue de services d'infrastructure ouverte qui décrit et évalue l'infrastructure ouverte, présentant des informations sur chacun sous une forme standardisée pour faciliter la sélection et la prise de décision. De plus, la pandémie de COVID-19 est un contexte important pour le projet FOS, une crise en cours qui a rendu visibles à la fois les vulnérabilités de l'écosystème scientifique, y compris ses infrastructures, et son importance vitale, en particulier l'importance vitale du libre accès et la science ouverte (Barbour et Borchert 2020; Tavernier 2020). Dans un article pour le blog LSE, Kaitlin Thaney, directrice exécutive de l'IOI, note que les institutions ont réagi à la pandémie de l'une des deux manières suivantes : en continuer avec le nombre de fournisseurs de services afin d’assurer la continuité de la recherche à le coût de la flexibilité et de la capacité de changement, ou en voyant cela comme un moment pour s'adapter et renforcer la résilience en coordonnant dans le cadre d'une stratégie à long terme (2020). La collaboration et les efforts collectifs sont essentiels à la vision du rapport FOS d'un avenir durable pour la science ouverte. ==Ouvrages citées== *ABRC (Association des bibliothèques de recherche du Canada). 2019. «&#8239;L’ABRC et le RCDR se joignent à la SCOSS, la Global Sustainability Coalition for Open Science Services&#8239;». 18 mars 2019. [https://www.carl-abrc.ca/fr/nouvelles/labrc-et-le-rcdr-se-joignent-au-scoss/ https://www.carl-abrc.ca/fr/nouvelles/labrc-et-le-rcdr-se-joignent-au-scoss/]. *ABRC (Association des bibliothèques de recherche du Canada). 2021. «&#8239;Webinar: Institutional Perspectives on Investments in Open Infrastructure (June 17, 2021)&#8239;». 23 juin 2021. [https://www.youtube.com/watch?v=GDWr6zVoA-g https://www.youtube.com/watch?v=GDWr6zVoA-g]. *Barbour, Virginia, et Martin Borchert. 2020. «&#8239;Open Science: After the COVID-19 Pandemic There can be No Return to Closed Working&#8239;». Australian Academy of Science. [https://www.science.org.au/curious/policy-features/open-science-after-covid-19-pandemic-there-can-be-no-return-closed-working https://www.science.org.au/curious/policy-features/open-science-after-covid-19-pandemic-there-can-be-no-return-closed-working]. *Goudarzi, Saman, Katrina Pugh, Vanessa Rhinesmith, Heather Staines, et Kaitlin Thaney. 2021. ''Designing a Preparedness Model for the Future of Open Scholarship. Invest in Open Infrastructure''. Juillet 2021. [http://doi.org/10.5281/zenodo.5218968 doi.org/10.5281/zenodo.5218968]. *IOI (Invest in Open Infrastructure). s.d. «&#8239;About IOI&#8239;». [https://investinopen.org/about/ https://investinopen.org/about/]. *Joseph, Heather. 2013. «&#8239;The Open Access Movement Grows Up: Taking Stock of a Revolution&#8239;». ''PLOS Biology'' 11, no. 10: e1001686. [https://doi.org/10.1371/journal.pbio.1001686 https://doi.org/10.1371/journal.pbio.1001686]. *SPARC Europe. 2019. ''A Global Sustainability Committee for Open Science Services: The Case''. [https://sparceurope.org/download/2859/ https://sparceurope.org/download/2859/]. *Tavernier, Willa. 2020. «&#8239;COVID-19 Demonstrates the Value of Open Access&#8239;». ''S&RL News'', mai 2020, [https://crln.acrl.org/index.php/crlnews/article/viewFile/24414/32235 https://crln.acrl.org/index.php/crlnews/article/viewFile/24414/32235]. *Thaney, Kaitlin. 2020. «&#8239;The Open Scholarship Ecosystem Faces a Collapse; It’s Also our Best Hope for a More Resilient Future&#8239;». ''LSE Blog'', 19 juin 2020. [https://blogs.lse.ac.uk/impactofsocialsciences/2020/06/19/the-open-scholarship-ecosystem-faces-collapse-its-also-our-best-hope-for-a-more-resilient-future/ https://blogs.lse.ac.uk/impactofsocialsciences/2020/06/19/the-open-scholarship-ecosystem-faces-collapse-its-also-our-best-hope-for-a-more-resilient-future/]. *UNESCO. 2021. ''Recommendation de l’UNESCO sur une science ouverte''. [https://unesdoc.unesco.org/ark:/48223/pf0000379949_fre https://unesdoc.unesco.org/ark:/48223/pf0000379949_fre]. [[Catégorie:Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024 (livre)]] 7vvlu8q5q9y9if46yi8d831he1gkwnz Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/La Politique de libre accès du l’UKRI 2021 0 82359 744019 742504 2025-06-02T22:36:46Z LodestarChariot2 120009 /* Ouvrages citées */ 744019 wikitext text/x-wiki ''Cette observation a été écrit par Caroline Winter (avec remerciements à Matthew Greenhall et Samuel Moore pour ses commentaires et contribution), pour le Electronic Textual Cultures Laboratory et le partenariat Implementing New Knowledge Environments.'' En août 2021, [https://www.ukri.org/ UK Research and Innovation (UKRI)] a publié [https://www.ukri.org/news/ukri-announces-new-open-access-policy/ une politique organisationnelle de libre accès] qui s'applique aux publications financées par l'un de [https://www.ukri.org/councils/ ses sept conseils de recherche, Research England et Innovate UK]. Cette nouvelle politique est le résultat d'un processus de consultation qui a débuté en 2018, avec une version de politique pour consultation publié en février 2020 (voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Examen et consultation de la politique de L’UKRI sur libre accès|Examen et consultation de la politique de l’UKRI sur libre accès]]&#8239;»). Il s'appuie sur près de deux décennies d'élaboration de politiques de libre accès au Royaume-Uni, notamment le rapport Finch de 2012, la politique et les orientations du Research Excellence Framework (REF) 2021 sur libre accès et les politiques d'accès ouvert existants des conseils de recherche. Dans le cadre de la nouvelle politique de libre accès, les articles de recherche soumis pour publication à compter du 1er avril 2022 doivent être publiés en libre accès immédiat via l'une des deux voies : dorée ou verte. Dans la voie 1 – libre accès dorée - l'article est publié dans une revue ou une plateforme libre accès (y compris des revues hybrides transformatifs) qui répond à un ensemble de normes techniques pour s'aligner sur [https://www.go-fair.org/fair-principles/ les principes FAIR (Findability, Accessibility, Interoperability, Reusability)]. Ces normes incluent l'utilisation d'identificateurs permanents, des normes de métadonnées, un programme de conservation à long terme et l'inclusion de la politique d'auto-archivage dans [https://v2.sherpa.ac.uk/romeo/ SHERPA/RoMEO] (UKRI 2021c ; voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Le Persistent Identifier (PID) Consortium de Royaume-Uni|Le «&#8239;Persistent Identifier (PID) Consortium&#8239;» de Royaume-Uni]]&#8239;»). Dans la voie 2 – libre accès verte - l'article est publié dans une revue payante et le manuscrit accepté de l'auteur ou la version de l’éditeur est déposé dans un dépôt institutionnel ou thématique. Une licence [https://creativecommons.org/about/cclicenses/ Creative Commons] doit également être appliquée, soit Attribution (CC BY) ou Attribution–No Derivatives (CC BY ND) 4.0 International. (UKRI 2021a). Le dépôt doit répondre à des normes techniques similaires à celles de la revue libre accès et doit être enregistré dans [https://v2.sherpa.ac.uk/opendoar/ le Directory of Open Access Repositories (OpenDOAR)]. Tous les articles biomédicaux doivent également être déposés dans [https://europepmc.org/ Europe PubMed Central] (politique UKRI 2021b). Il s'agit de la première politique de libre accès de l’UKRI qui s'applique aux monographies ainsi qu'aux articles (voir «&#8239;[[Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Les monographies en libre accès|Les monographies en libre accès]]&#8239;»). En vertu de la politique, les publications de forme longue - monographies, collections éditées et chapitres de livre - doivent être en libre accès dans les 12 mois suivant la publication, à compter du 1er janvier 2024, soit par publication sur une plate-forme en libre accès (similaire à la voie 1 ci-dessus ou en libre accès dorées) ou par dépôt du manuscrit accepté de l’auteur dans un dépot (similaire à la voie 2 ou à libre accès verte). Comme pour les articles, une licence CC doit être appliquée, soit CC BY (préféré), CC BY ND, ou Attribution–NonCommercial (CC BY NC) (UKRI 2021a). La politique reconnaît que certaines exceptions rares peuvent être faites lorsque la publication en libre accès n'est pas possible et encourage mais n'exige pas le respect des normes de métadonnées et l'utilisation des identificateurs permanents (UKRI 2021b). La politique note que ses exigences en matière de licence ne s'appliquent à aucun matériel protégé par le droit d'auteur par une tierce partie, tel que des images ou des cartes, inclus dans des articles ou des publications de longue durée (Royaume-Uni 2021b). Et, bien que la politique ne s'applique pas aux prépublications, elle soutient leur utilisation et leur diffusion, en particulier dans les situations d'urgence (UKRI 2021b). Pour soutenir la mise en œuvre de la nouvelle politique libre accès, l'UKRI a engagé jusqu'à 47,7 £ millions par an, dont 3,5 £ millions réservés aux monographies libre accès, mais les fonds de soutien ne peuvent être utilisés que pour publier des articles dans des revues hybrides qui ont un accord transformateur en place avec [https://www.jisc.ac.uk/content/open-access/our-role#requirements JISC] (UKRI 2021b ; URKI 2021c). Il s'efforcera de s'assurer que toutes les exigences libre accès futures du Research Excellence Framework (REF) sont conformes à celui-ci et fournira plus de détails sur la mise en œuvre et le financement, en particulier en ce qui concerne les publications de longue durée, plus tard en 2022 (UKRI 2021a ; UKRI 2021b). De plus amples détails sur la mise en œuvre seront disponibles sur le site [https://www.ukri.org/what-we-offer/supporting-healthy-research-and-innovation-culture/open-research/open-access-policies-review/ Shaping Our Open Access Policy] de l'UKRI dès qu'ils seront disponibles. ==Réactions de la communauté INKE== [https://oaaustralasia.org/2021/08/12/new-ukri-open-access-policy/ Open Access Australasia], membre du partenariat INKE par le biais du [https://inke.ca/canadian-australian-partnership-for-open-scholarship/ Canadian–Australian Partnership for Open Scholarship (CAPOS)], a fait une déclaration en faveur de la nouvelle politique, notant qu'elle offre un exemple utile qui pourrait éclairer [https://oa2020.org/wp-content/uploads/POSTER_12_OpenAccessForAustralia_poster_DrCathyFoley.pdf la stratégie nationale australienne de libre accès], actuellement en cours de consultation. ==La nouvelle politique libre accès de l’UKRI dans la presse== L'annonce de la politique a été couverte par la presse universitaire, notamment dans [https://physicsworld.com/a/researchers-and-publishers-respond-to-new-uk-open-access-policy/ ''Physics World''], [https://sciencebusiness.net/news/ukri-funded-research-be-published-open-access-journals ''Science Business''] et [https://universitybusiness.co.uk/research/ukri-publishes-new-open-access-policy-for-publicly-funded-research/ ''University Business'']. Comme le montre sa couverture médiatique, la politique de libre accès de l'UKRI bénéficie en principe d'un large soutien de la part de la communauté universitaire, mais les opinions divergent sur la manière dont elle devrait être mise en œuvre (Duncan 2021). Dans un article au [https://www.timeshighereducation.com/blog/ukris-new-open-access-policy-will-hinder-open-science ''Times Higher Ed''], Carrie Webster (de Springer Nature) affirme que la nouvelle politique de libre accès de l'UKRI fait bien les choses, y compris ses engagements de financement et son exigence que le financement soit utilisé pour soutenir des accords transformatifs. Elle exprime cependant des inquiétudes quant au fait que la politique traite libre accès verte (voie 2) sur un pied d’égalité avec libre accès dorée (voie 1), car cela a le potentiel de saper les objectifs ultimes de la politique en enracinant plutôt qu'en s'éloignant d'un modèle basé sur l'abonnement (Webster 2021). Un article au [https://www.nature.com/articles/d41586-021-02148-8 ''Nature''] de Richard Van Noorden est moins favorable à la politique, le décrivent comme strict et le processus de l'UKRI pour déterminer quelles revues hybrides sont éligibles au soutien des frais de publication comme l’indécision (2021). Comme Webster, sa critique se concentre sur le soutien à libre accès vert, mais il fait part de l'inquiétude de la communauté de l'édition britannique que le soutien à libre accès vert féra souffrir des éditeurs en permettant aux auteurs de se conformer sans payer des frais de publication. ==Réaction de la communauté élargie== L'UKRI a reçu une forte réponse de la communauté au sens large à son projet de politique pour consultation et a partagé [https://www.ukri.org/wp-content/uploads/2021/08/UKRI-060821-UKRIOpenAccessReviewConsultationAnalysis-FINAL.pdf une analyse des 350 réponses qu'elle a reçues]. [https://www.rluk.ac.uk/rluk-welcomes-publication-of-ukris-new-open-access-policy/ Research Libraries UK (RLUK)] a partagé une déclaration de soutien ferme à la nouvelle politique, tout comme [https://www.coalition-s.org/coalition-s-welcomes-the-plan-s-aligned-open-access-policy-from-ukri/ la cOAlition S] et [https://blog.frontiersin.org/2021/08/09/statement-in-support-of-ukris-new-open-access-policy/ Frontiers], ainsi que d'autres parties prenantes ont exprimé leur soutien à la politique avec des inquiétudes quant à sa mise en œuvre. Bon nombre de ces préoccupations concernent l'élimination de tout embargo sur les articles déposés dans les dépôts. Par exemple, [https://www.publishers.org.uk/publications/the-practical-implications-of-ukris-proposed-open-access-policy-for-the-uks-research-sector/ le Publishers Association] déclare que mettre le libre accès verte sur un pied d'égalité avec dorée - plutôt que comme une option de secours lorsque le libre accès dorée n'est pas disponible - sapera à la fois l'industrie de l'édition et le mouvement libre accès (2021). Des préoccupations similaires ont été exprimées par [https://www.alpsp.org/news/ukri-policy-alpsp-response-aug21 le Copyright Committee de l'Association of Learned and Professional Society Publishers (ALPSP)], [https://www.stm-assoc.org/2021_08_09_STM_response_to_UKRI_Open_Access_Policy.pdf STM] (une organisation industrielle pour les éditeurs universitaires), [https://physicsworld.com/a/researchers-and-publishers-respond-to-new-uk-open-access-policy/ l'Institute of Physics (IOP) Publishing], [https://newsroom.taylorandfrancisgroup.com/taylor-francis-response-to-the-ukri-policy-announcement/ Taylor & Francis] et [https://www.thebookseller.com/news/ukri-announces-new-open-access-policy-1274942 ''The Bookseller''] (un magazine spécialisé dans l'édition). [https://openaccess.ox.ac.uk/wp-content/uploads/sites/2/2021/08/Oxford-UKRI-OA-policy-response-09-08-21-1.pdf L'Université d'Oxford] a publié une déclaration en réponse à l'annonce de la politique exprimant sa préoccupation que les questions soulevées en réponse au projet n'aient pas été entièrement traitées. Il indique que le délai du 1er avril pour les articles est trop court, que les révisions de la politique n'ont pas pris en compte le nombre croissant d'accords transformateurs au Royaume-Uni et que les détails nécessaires sur le financement ne sont pas encore disponibles. En outre, il soutient que l'embargo de 12 mois sur les monographies mettra en péril l'avenir des presses savantes (Oxford 2021). Jusqu'au 1er avril, date à laquelle la nouvelle politique devait prise effet, ''Nature'' et les autres revues publiées par Springer Nature n'étaient pas incluses dans [https://v2.sherpa.ac.uk/romeo/tjlists.html la liste des revues transformatifs approuvées par Jisc]. Cela a soulevé des inquiétudes quant au fait que le financement de l'UKRI ne pouvait pas être utilisé pour payer les frais de publication pour ces revues, empêchant ainsi les chercheurs et chercheuses de publier dans ces lieux prestigieux. Un accord temporaire de dernière minute entre Jisc et Springer Nature annoncé le 1er avril, en vigueur jusqu'à la fin de 2022, a temporairement résolu ces préoccupations, et Springer Nature devrait avoir un accord transformateur en place pour 2023 et au-delà. Cet accord reste cependant controversé en raison des frais de publication élevés facturés par ''Nature'' de 8290 £ ou 9500 € (Grove 2022). D'autres intervenants ont exprimé des inquiétudes quant au traitement des monographies par la politique. [https://copim.ac.uk/about-us/ COPIM (Community-led Publication Infrastructures for Monographs)] a publié une réponse à l'appui de la politique, en particulier ses exigences pour les publications savantes de longue durée. Notant que d'autres organisations développent déjà les infrastructures nécessaires à la publication de monographies en libre accès, le COPIM s'oppose à l'exemption de l'éditeur approprié de la politique et aux possibilités d'embargos incluses dans le prochain REF (2021). [https://blog.royalhistsoc.org/2021/08/11/ukri-open-access-protocols-august-2021/ Le Royal Historical Society] du Royaume-Uni soutient généralement la politique et son traitement des publications de longue durée, mais exprime des préoccupations similaires au COPIM, que des détails importants sur le financement et la mise en œuvre restent indéfinis, et comment cette politique affectera la prochaine REF est encore inconnue (Finn et al. 2021 ; COPIM 2021). Faisant écho aux préoccupations concernant les effets du soutien à libre accès hybride basé sur les frais de publication, la réponse du COPIM avertit que l'établissement d'un système similaire de financement des frais de publication des livres ne peut qu'enraciner davantage l'édition hybride et aggraver les inégalités existantes (COPIM 2021). [https://www.samuelmoore.org/2021/08/09/what-does-the-ukri-policy-mean-for-open-access-book-publishing/ Samuel Moore] exprime des préoccupations similaires, faisant valoir que la politique pourrait faire des frais de publication de monographie le principal modèle commercial pour les monographies libre accès plutôt que de soutenir des modèles d'édition plus innovants et dirigés par la communauté (Moore 2021). Dans le même ordre d'idées, [https://blogs.lse.ac.uk/impactofsocialsciences/2021/09/14/genuine-open-access-to-academic-books-requires-collective-solutions/#comments Lucy Barnes d'Open Book Publishers] soutient en réponse à la nouvelle politique que les modèles de financement collectifs sont le meilleur moyen de financer l'édition longue en libre accès sans compter sur les frais de publication de livres (2021). ==La nouvelle politique libre accès de l’UKRI et la science ouverte== Les débats sur les effets potentiels de la politique sur l'industrie de l'édition et sur l'économie du Royaume-Uni dans son ensemble mettent en évidence le rôle de la science ouverte dans l'économie mondiale. La nouvelle politique de libre accès de l’UKRI fait partie de la stratégie globale [https://www.gov.uk/government/publications/build-back-better-our-plan-for-growth Build Back Better] du Royaume-Uni, une réponse à la pandémie de COVID-19 qui comprend des investissements importants dans la recherche et développement pour soutenir la croissance économique (Ficarra et Johnson 2021 ; voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Science Ouverte et COVID-19|Science ouverte et COVID-19]]&#8239;») . Cependant, [https://www.publishers.org.uk/wp-content/uploads/2021/02/FTI-Report-for-Publishers-Association-1.pdf un rapport sur les effets économiques potentiels de la nouvelle politique de libre accès] de FTI Consulting, commandé par le Publishers Association, conclut que la politique affectera négativement l'économie britannique (2021). Plus précisément, il constate que la suppression de la période d'embargo pour les articles publiés via le libre accès verte faire souffrir la capacité des éditeurs à récupérer leurs investissements dans les publications de recherche, avec des répercussions sur l'économie du Royaume-Uni dans son ensemble (9-10, 40). En réponse à ce rapport, [https://theplosblog.plos.org/2021/03/open-response-to-fti-consulting-report/ PLOS] fait valoir qu'en limitant son analyse aux effets économiques du libre accès sur l'industrie de l'édition - et sur les modèles d'édition traditionnels - le rapport ne tient pas compte des avantages généralisés du libre accès dans la science ouverte et au-delà (2021). L'UKRI est un membre fondateur de la cOAlition S, et l'appel de la politique pour un libre accès immédiat et sans embargo s'aligne sur le Plan S et d'autres politiques de financement internationales (voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Plan S et cOAlition S|Plan S et cOAlition S]]&#8239;» et «&#8239;[[Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Mise à jour du Plan S : L’élargissement de l’adhésion de la cOAlition S|Mise à jour du Plan S: L’élargissement de l’adhésion de la cOAlition S]]&#8239;») (O'Grady 2021 ; UKRI 2021a). L'exigence d'une licence Creative Commons met également la politique de l'UKRI en conformité avec la stratégie de conservation des droits du Plan S, qui a soulevé des inquiétudes quant aux impacts sur la science ouverte dans son ensemble, y compris la possibilité de rejets généralisés de manuscrits lorsque la politique de la revue exige le transfert du droit d'auteur et la l'effondrement des revues hybrides qui choisissent de ne passer pas à libre accès, mais Stephen Eglen soutient que bon nombre de ces préoccupations sont exagérées (voir «&#8239;[[Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Mise à jour du Plan S : L’élargissement de l’adhésion de la cOAlition S|Mise à jour du Plan S: La Stratégie de conservation des droits]]&#8239;» ; Eglen 2021). La déclaration du Jisc en réponse à la politique souligne son importance au sein de l'écosystème des communications savantes et de la communauté au sens large, déclarant que la politique aidera la transition durable vers le libre accès complet et immédiat (2021). Étant donné que le Royaume-Uni est un leader mondial de l’édition en libre accès, la nouvelle politique de l’UKRI est une contribution significative à l'avancement de la science ouverte dans le monde entier. ==Ouvrages citées== *Barnes, Lucy. «&#8239;Genuine Open Access to Academic Books Requires Collective Solutions&#8239;». ''LSE Blog''. 14 septembre 2021. [https://blogs.lse.ac.uk/impactofsocialsciences/2021/09/14/genuine-open-access-to-academic-books-requires-collective-solutions/#comments https://blogs.lse.ac.uk/impactofsocialsciences/2021/09/14/genuine-open-access-to-academic-books-requires-collective-solutions/#comments]. *COPIM (Community-led Publication Infrastructures for Monographs). 2021. «&#8239;COPIM Response to new UKRI Open Access Policy&#8239;». 11 août 2021. [https://copim.pubpub.org/pub/copim-response-to-new-ukri-open-access-policy/release/2 https://copim.pubpub.org/pub/copim-response-to-new-ukri-open-access-policy/release/2]. *Duncan, Bruce. «&#8239;URKI Open Access Policy: A Revolution in Scholarly Communication?&#8239;» ''Times Higher Ed''. 19 août 2021. [https://www.timeshighereducation.com/news/ukri-open-access-policy-revolution-scholarly-communication https://www.timeshighereducation.com/news/ukri-open-access-policy-revolution-scholarly-communication]. *Eglen Stephen J. 2021. «&#8239;How will the Rights Retention Strategy affect Scholarly Publishing?&#8239;» ''LSE Blog'', 10 septembre 2021. [https://blogs.lse.ac.uk/impactofsocialsciences/2021/09/10/how-will-the-rights-retention-strategy-affect-scholarly-publishing/ https://blogs.lse.ac.uk/impactofsocialsciences/2021/09/10/how-will-the-rights-retention-strategy-affect-scholarly-publishing/]. *Ficarra, Victoria, et Rob Johnson. 2021. «&#8239;Guest Post – Five Things you Need to Know about UKRI’s New Open Access Policy&#8239;». ''The Scholarly Kitchen''. 3 novembre 2021. [https://scholarlykitchen.sspnet.org/2021/11/03/guest-post-five-things-you-need-to-know-about-ukris-new-open-access-policy/ https://scholarlykitchen.sspnet.org/2021/11/03/guest-post-five-things-you-need-to-know-about-ukris-new-open-access-policy/]. *Finch, Janet et le Working Group on Expanding Access to Published Research Findings. 2012. ''Accessibility, Sustainability, Excellence: How to Expand Access to Research Publications''. Research Information Network. Grande Bretagne. [https://apo.org.au/node/29938 https://apo.org.au/node/29938]. *Finn, Margot, Richard Fisher, Emma Griffin et Peter Mandler. 2021. «&#8239;UKRI Open Access Protocols: August 2021&#8239;». ''Historical Transactions'', Royal Historical Society. [https://blog.royalhistsoc.org/2021/08/11/ukri-open-access-protocols-august-2021/ https://blog.royalhistsoc.org/2021/08/11/ukri-open-access-protocols-august-2021/]. *FTI Consulting. 2021. ''Economic Assessment of the Impact of the New Open Access Policy Developed by UK Research and Innovation''. [https://www.publishers.org.uk/wp-content/uploads/2021/02/FTI-Report-for-Publishers-Association-1.pdf https://www.publishers.org.uk/wp-content/uploads/2021/02/FTI-Report-for-Publishers-Association-1.pdf]. *Grove, Jack. 2022. «&#8239;Late Reprieve Allows Scientists with UK Grants to Publish in Nature&#8239;». ''Times Higher Education (THE)'', 14 avril 2022. [https://advance.lexis.com. https://advance.lexis.com.] *Jisc. 2021. «&#8239;New UKRI Policy is a ‘Significant Driver’ Towards Open Access Research&#8239;». ''Jisc Blog''. 6 août 2021. [https://www.jisc.ac.uk/blog/new-ukri-policy-is-a-significant-driver-towards-open-access-research-06-aug-2021 https://www.jisc.ac.uk/blog/new-ukri-policy-is-a-significant-driver-towards-open-access-research-06-aug-2021]. *Moore, Samuel. 2021. «&#8239;What Does the UKRI Policy Mean for Open Access Book Publishing?&#8239;» 9 août 2021. [https://www.samuelmoore.org/2021/08/09/what-does-the-ukri-policy-mean-for-open-access-book-publishing/ https://www.samuelmoore.org/2021/08/09/what-does-the-ukri-policy-mean-for-open-access-book-publishing/]. *O’Grady, Cathleen. 2021. «&#8239;Major U.K. Science Funder to Require Grantees to Make Papers Immediately Free to All&#8239;». ''Science''. 6 août 2021. [https://www.science.org/content/article/major-uk-science-funder-require-grantees-make-papers-immediately-free-all https://www.science.org/content/article/major-uk-science-funder-require-grantees-make-papers-immediately-free-all]. *Oxford University. 2021. «&#8239;Oxford UKRI OA Policy Response&#8239;». 9 août 2021. [http://openaccess.ox.ac.uk/wp-content/uploads/sites/2/2021/08/Oxford-UKRI-OA-policy-response-09-08-21-1.pdf http://openaccess.ox.ac.uk/wp-content/uploads/sites/2/2021/08/Oxford-UKRI-OA-policy-response-09-08-21-1.pdf]. *PLOS. «&#8239;Open Response to ‘Economic Impact of UKRI Open Access Policy’ Report&#8239;». ''The Official PLOS Blog''. 17 mars 2021. [https://theplosblog.plos.org/2021/03/open-response-to-fti-consulting-report/ https://theplosblog.plos.org/2021/03/open-response-to-fti-consulting-report/]. *Publishers Association. 2021. ''The Practical Implications of UKRI’s Proposed Open Access Policy for the UK’s Research Sector''. 23 juin 2021. [https://www.publishers.org.uk/publications/the-practical-implications-of-ukris-proposed-open-access-policy-for-the-uks-research-sector/ https://www.publishers.org.uk/publications/the-practical-implications-of-ukris-proposed-open-access-policy-for-the-uks-research-sector/]. *UKRI. 2021a. «&#8239;UKRI Announces New Open Access Policy&#8239;». UK Research and Innovation [https://www.ukri.org/news/ukri-announces-new-open-access-policy/ https://www.ukri.org/news/ukri-announces-new-open-access-policy/]. *UKRI. 2021b. ''UKRI Open Access Policy''. UK Research and Innovation, [https://www.ukri.org/publications/ukri-open-access-policy/ https://www.ukri.org/publications/ukri-open-access-policy/]. *UKRI. 2021c. «&#8239;UKRI Open Access Policy – Explanation of Policy Changes&#8239;». 6 août 2021. [https://www.ukri.org/wp-content/uploads/2021/08/UKRI-180821-UKRIOpenAccessPolicyExplanationOfChanges-2.pdf https://www.ukri.org/wp-content/uploads/2021/08/UKRI-180821-UKRIOpenAccessPolicyExplanationOfChanges-2.pdf] *Van Noorden, Richard. «&#8239;Major UK Science Funder Unveils Strict Open-Access Policy&#8239;». ''Nature''. 6 août 2021. [https://doi.org/10.1038/d41586-021-02148-8 https://doi.org/10.1038/d41586-021-02148-8]. *Webster, Carrie. 2021. «&#8239;UKRI’s New Open Access Policy will Hinder Open Science&#8239;». ''Times Higher Ed''. 3 septembre 2021. [https://www.timeshighereducation.com/blog/ukris-new-open-access-policy-will-hinder-open-science https://www.timeshighereducation.com/blog/ukris-new-open-access-policy-will-hinder-open-science]. [[Catégorie:Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024 (livre)]] bphpndc373s3wgy0vqh39iwxf8cd0xd Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Le mémo Nelson : Une politique d’accès public mis à jour aux États-Unis 0 82365 744020 742711 2025-06-02T22:49:08Z LodestarChariot2 120009 /* Ouvrages cités */ 744020 wikitext text/x-wiki ''Cette observation a été écrite par Caroline Winter (avec ses remerciements à Leslie Chan et Kate Shuttleworth pour leurs commentaires et contributions), pour le Electronic Textual Cultures Laboratory et le partenariat Implementing New Knowledge Environments.'' Le 25 août 2022, l'Office of Science and Technology Policy (OSTP) des États-Unis a publié un mémo intitulé [https://ospolicyobservatory.uvic.ca/wp-content/uploads/sites/7744/2025/05/08-2022-OSTP-Public-Access-Memo.pdf ''Ensuring free, immediate, and equitable access to federally funded research''] et un [https://ospolicyobservatory.uvic.ca/wp-content/uploads/sites/7744/2025/05/Nelson-Memo-media-release.pdf communiqué de presse] l’accompagnant. Ce mémo, appelé le mémo Nelson parce qu’il a été écrit par Alondra Nelson, en ce temps-là directrice par intérim de l’OSTP, présente les orientations politiques en matière d’accès public (libre accès) pour les agences fédérales américaines qui financent la recherche et le développement. Le rapport de l’OSTP [https://www.whitehouse.gov/wp-content/uploads/2022/08/08-2022-OSTP-Public-Access-Congressional-Report.pdf ''Economic Landscape of Federal Public Access Policy''], aussi publié en août 2022, examine les effets économiques potentiels du libre accès immédiat à la recherche financée par le gouvernement fédéral. La politique mise à jour a suscité un débat animé au sein de la communauté de la communication savante et au-delà. Cette observation offre un bref résumé des points clés du mémo et un aperçu des premières réponses. Le mémo Nelson s’appuie sur la politique fédérale américaine de libre accès publiée en 2013 par John Holdren, en ce temps-là directeur de l’OSTP, le [https://obamawhitehouse.archives.gov/sites/default/files/microsites/ostp/ostp_public_access_memo_2013.pdf ''Memorandum on Increasing Access to the Results of Federally Funded Research''], appelé le mémo Holdren. Ce mémo de 2013 demandait que les agences fédérales qui fournissaient plus de 100 millions de dollars par an en financement pour la recherche et le développement créent des plans pour rendre les publications et les données de recherche plus accessibles au public, avec un embargo autorisé de 12 mois. Deux des changements importants apportés à cette politique mise à jour sont suivants : * la politique s’applique à tous les organismes de financement fédéraux ; * les publications doivent être en libre accès dès leur publication, sans embargo. Le mémo Nelson spécifie que les organismes de financement fédéraux devraient * Mettre à jour leurs politiques de libre accès pour rendre les publications et les données de la recherche financée accessibles au public dès leur publication ; * Adopter des procédures transparentes garantissant l’intégrité scientifique de ces politiques ; * Collaborer avec l’OSTP pour s’assurer que les résultats de la recherche financée, y compris les données, sont diffusés équitablement. Les agences qui ont élaboré des politiques de libre accès conformément aux directives de 2013 doivent compléter leurs plans mis à jour dans les six mois suivant la publication du mémo Nelson, et d’autres ont un peu moins d’un an pour le faire. Toutes les politiques doivent être publiées au plus tard le 31 décembre 2024 et entrer en vigueur au plus tard le 31 décembre 2025. Le mémo comprend les dispositions pour les publications examinées par les pairs et pour les données de recherche. Les publications financées par le gouvernement fédéral doivent être en libre accès dès leur publication par défaut, dans un dépôt désigné par des agences, bien que le mémo ne précise pas quelle version de la publication doit être disponible (c’est-à-dire le manuscrit accepté par l’auteur ou la version de l’éditeur). Cette disposition s’applique à tous les articles et peut inclure d’autres publications évaluées par les pairs tels que des actes de colloques, des éditoriaux et des chapitres de livre. Notamment, les plans des agences doivent envisager comment maximiser la diffusion équitable, non seulement par la publication en libre accès, mais aussi par la lisibilité automatique, l’accessibilité et les licences ouvertes. Les plans d’accès public aux données de recherche doivent inclure des politiques pour la gestion et le partage des données, et les données de recherche associées aux publications doivent être librement et publiquement accessibles par défaut au moment de la publication, soumis aux conditions légales, éthiques, de confidentialité, et autres restrictions similaires. Les coûts associés à la gestion, la conservation et la publication des données peuvent être inclus dans les budgets de recherche. Le mémo souligne l’importance de l’accès public et ouvert pour le soutien de l’intégrité scientifique et de la recherche et pour le renforcement de la confiance du public dans la recherche financée par le gouvernement fédéral. Il demande aux agences fédérales d’élaborer une politique pour collecter et partager les métadonnées sur les publications et les données de recherche, y compris des identifiants pérenne pour les résultats de la recherche, les chercheurs et les chercheuses, et les subventions fédérales, conformément aux directives afin de réaliser «&#8239;[https://www.whitehouse.gov/wp-content/uploads/2022/01/010422-NSPM-33-Implementation-Guidance.pdf National Security Presidential Memorandum 33 (NSPM-33)]&#8239;», publié par le National Science and Technology Council en janvier 2022. Cette mise à jour de la politique doit être achevée au plus tard le 31 décembre 2026 et entrer en vigueur au plus tard le 31 décembre 2027. Le mémo aborde également la nécessité de coordonner les plans d’accès public entre les agences fédérales. Il décrit le rôle du National Science and Technology Council’s Subcommittee on Open Science, qui a été créé pour faciliter la coordination des plans et fournir des orientations supplémentaires sur la mise en œuvre des exigences du mémo. ==La politique dans la presse== La mise à jour de la politique a été un sujet d’intérêt dans la presse universitaire. Un article de [https://www.science.org/content/article/white-house-requires-immediate-public-access-all-u-s--funded-research-papers-2025 ''Science''] note que, bien que la politique utilise le terme d’accès public, il s’agit essentiellement d’une politique du libre accès, le résultat de décennies de discussions sur la nécessité de rendre accessible au public la recherche financée par le secteur public (Brainard et Kaiser 2022). Un article pour [https://www.insidehighered.com/news/2022/09/12/wholl-pay-public-access-federally-funded-research ''Inside Higher Ed''] note également que cette mise à jour de la politique était en développement depuis près d’une décennie sous les administrations de Barack Obama et de Donald Trump, mais elle a en même temps rencontré l’opposition de la communauté des éditeurs, en particulier à l’élimination de l’embargo (D’Agostino et Lederman 2022). Un article dans [https://www.chronicle.com/article/a-historic-moment-new-guidance-requires-federally-funded-research-to-be-open-access ''The Chronicle''] offre un aperçu des réponses à la mise à jour de la politique des avocats du libre accès, qui y sont généralement fortement favorables, et de l’industrie de l’édition, qui a exprimé des réserves sur la manière dont la politique sera mise en œuvre (Zahneis 2022). ''The Scholarly Kitchen'' a également publié plusieurs articles sur ce sujet dans les semaines qui ont suivi la publication du mémo, y compris les réponses de leur équipe ([https://scholarlykitchen.sspnet.org/2022/08/30/ask-the-chefs-ostp-policy-i/ partie 1] et [https://scholarlykitchen.sspnet.org/2022/08/31/ask-the-chefs-ostp-policy-ii/ partie 2]), un article [https://scholarlykitchen.sspnet.org/2022/09/13/guest-post-quantifying-the-impact-of-the-ostp-policy/ quantifiant l’impact de la politique], un [https://scholarlykitchen.sspnet.org/2022/10/03/the-new-ostp-memo-a-roundup-of-reactions-and-an-interview-preview/?informz=1&nbd=e7acf065-7b8f-4940-9c2f-ebcb1b99d33d&nbd_source=informz résumé de nombreuses réponses et réactions] au mémo, une [https://scholarlykitchen.sspnet.org/2022/10/11/new-light-on-the-new-ostp-memo-an-interview-with-dr-alondra-nelson/ entrevue avec Nelson], et quelques [https://scholarlykitchen.sspnet.org/2022/10/13/thoughts-and-observations-on-the-ostp-responses-to-our-interview-questions/ réflexions sur cette entrevue]. ''Library Journal'' ''InfoDocket'' a également publié un [https://www.infodocket.com/2022/08/25/white-house-office-of-science-and-technology-policy-ostp-issues-new-guidance-to-ensure-free-immediate-and-equitable-access-to-federally-funded-research/ résumé des réponses communautaire] à la fin du mois d’août. La publication de la politique a également été couverte par le[https://www.goodnewsnetwork.org/white-house-bans-paywalls-on-taxpayer-funded-research/ ''Good News Network''], le[https://www.natlawreview.com/article/all-federal-research-agencies-to-update-public-access-policies ''National Law Review''], le[https://www.nytimes.com/2022/08/25/us/white-house-federally-funded-research-access.html ''New York Times''],[https://www.publishersweekly.com/pw/by-topic/international/Frankfurt-Book-Fair/article/90593-frankfurt-spotlight-u-s-to-require-open-access-by-2025.html ''Publishers Weekly''], le[https://www.theregister.com/2022/08/25/science_research_release/ ''Register''] et[https://www.researchinformation.info/news/new-ostp-policy-federally-funded-research '' Research Information''], et le podcast[https://www.sciencefriday.com/segments/public-access-science-biden/ ''Science Friday''], entre autres. ==Réponses du partenariat INKE== Un [https://www.lib.sfu.ca/help/publish/scholarly-publishing/radical-access/ostp-nelson-memo-open-access article de blog] de la Bibliothèque de l’Université Simon Fraser, un des partenaires d’INKE, place la politique mise à jour à côté de [https://www.lib.sfu.ca/help/publish/scholarly-publishing/open-access/open-access-policy la politique libre accès de l’université], qui exige le dépôt du texte finalisé de toutes les publications par l’auteur de l’université dans son entrepôt institutionnel, et d’autres politiques nationales et internationales du libre accès (Liuta 2022). Il s’agit notamment du Plan S et de [https://science.gc.ca/site/science/fr/financement-interorganismes-recherche/politiques-lignes-directrices/libre-acces/politique-trois-organismes-libre-acces-aux-publications?OpenDocument= la Politique des trois organismes sur le libre accès aux publications] du Canada de 2015, qui exige que des articles de revues financés par [https://cihr-irsc.gc.ca/f/193.html les Instituts de recherche en santé du Canada (IRSC)], [https://www.nserc-crsng.gc.ca/index_fra.asp le Conseil de recherches en sciences naturelles et en génie du Canada (CRSNG)] et [https://www.sshrc-crsh.gc.ca/home-accueil-fra.aspx le Conseil de recherches en sciences humaines (CRSH)] soient librement accessible dans les 12 mois suivant la publication (voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Politique des trois organismes sur le libre accès aux publications|Politique des trois organismes sur le libre accès aux publications]]&#8239;»]). Le [https://pkp.sfu.ca/2022/08/29/embargo-no-more/ Public Knowledge Project (PKP)], un des partenaires d’INKE, a exprimé son soutien à la mise à jour de la politique et à ses effets sur l’accès et la qualité de la recherche. En particulier, il salue l’accent mis par la politique sur la transparence et l’importance de la confiance du public (Racy 2022), notant qu’elle s’aligne sur le projet [https://docs.google.com/document/d/1AvIElSv6JYfdsOIiy15Cyvzdg3ENgOwCtkQIB39RCHY/edit Publication Facts Label] du PKP, actuellement en cours. [https://oaaustralasia.org/2022/08/31/open-access-australasia-comment-on-us-white-house-ostp-public-access-guidance/ Open Access Australasia], un des partenaires d’INKE via le [https://inke.ca/canadian-australian-partnership-for-open-scholarship/ Canada–Australia Partnership for Open Scholarship (CAPOS)], a également exprimé son soutien à la mise à jour de la politique, déclarant que la politique est un facteur crucial dans le passage au libre accès et soulignant les changements provoqués par les politiques RCUK et cOAlition S ( 2022 ; voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Examen et consultation de la politique de L’UKRI sur libre accès|Examen et consultation de la politique de l’UKRI sur libre accès]]&#8239;» et «&#8239;[[Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/La Politique de libre accès du l’UKRI 2021|La politique de libre accès du l’UKRI 2021]]&#8239;»). Cette déclaration exprime également l’espoir que la politique conduira à une plus grande diversité de modèles et d’approches du libre accès qui reflètent mieux la diversité de la communauté de la recherche. ==Réponses de la communauté élargie== La communauté élargie a exprimé un appui solide pour le mémo Nelson ainsi que plusieurs préoccupations, mais elle semble unie en pensant que la politique est un tournant pour le libre accès. [https://www.aip.org/fyi/2022/white-house-moves-make-federally-funded-research-free-upon-publication L'American Institute of Physics], par exemple, affirme qu’elle marque un changement tectonique dans le domaine de l’édition scientifique (2022), et [https://www.arl.org/news/arl-celebrates-biden-harris-administrations-historic-policy-to-make-federally-funded-research-immediately-available/ l’Association of Research Libraries] la décrit comme un moment historique pour les communications scientifiques (2022). SPARC a exprimé son appui fort pour la politique dans son [https://sparcopen.org/news/2022/taxpayers-to-get-immediate-access-to-publicly-funded-research/ communiqué de presse] ainsi que dans une [https://sparcopen.org/our-work/2022-updated-ostp-policy-guidance/fact-sheet-white-house-ostp-memo-on-ensuring-free-immediate-and-equitable-access-to-federally-funded-research/ fiche d’information]. Les déclarations des [https://www.nih.gov/about-nih/who-we-are/nih-director/statements/statement-nih-plans-speed-access-federally-funded-research-results National Institutes of Health] et de la [https://www.nlm.nih.gov/news/Expediting_Access_To_Results_Of_Federally_Funded_Research.html National Library of Medicine] expriment leur empressement de mettre en œuvre la politique, mais certaines parties prenantes, en particulier, [https://www.aaas.org/news/aaas-statement-ostp-federally-funded-research-guidance l’'American Association for the Advancement of Science (AAAS)], [https://www.aip.org/fyi/2022/white-house-moves-make-federally-funded-research-free-upon-publication l’'American Institute of Physics] et [https://www.aau.edu/newsroom/press-releases/aau-statement-ostp-decision-make-federally-funded-research-publicly l'Association of American Universities], ont exprimé l’incertitude quant à la question du comment cela serait fait. . Les parties prenantes ont également exprimé plusieurs préoccupations concernant la politique et ses effets potentiels. Certaines de ces préoccupations ont été liées au manque apparent de consultation des parties prenantes, ce qui a été souligné, entre autres, par [https://publishers.org/news/statement-from-shelley-husband-senior-vice-president-government-affairs-association-of-american-publishers-on-decision-by-white-house-office-of-science-and-technology-policy-to-make-private-se/ l'Association of American Publishers] (Husband 2022 ; Michael, Vines et al. 2022). Bien qu’un bon nombre des éditeurs universitaires principaux n’aient pas publié de déclarations sur la politique, [https://newsroom.taylorandfrancisgroup.com/ostp-memorandum/ Taylor & Francis] a exprimé son appui tout en reconnaissant les défis de la mise en œuvre. Une autre préoccupation est le fait que le mémo présente des recommandations plutôt que des directives, et il n’est pas clair quelles seront les conséquences en cas de non-conformité (Anderson 2022 ; Anderson et Wulf 2022). Les préoccupations principales sont liées à sa mise en œuvre, y compris plusieurs concernant le financement. Bien que certains éditeurs en libre accès, tels que [https://theplosblog.plos.org/2022/09/plos-cheers-the-ostp-memorandum/ PLOS] et [https://blog.frontiersin.org/2022/08/29/white-house-announces-new-policy-to-drop-paywalls-around-publicly-funded-research/ Frontiers], aient exprimé leur appui pour la politique mise à jour, d’autres membres du milieu de l’édition ont exprimé des préoccupations au sujet de l’impact de l’élimination de l’embargo sur leur viabilité financière. Le mémo ne décrit pas de modèle d’entreprise particulier, permettant aux agences de décider des meilleurs modèles pour leurs communautés. Cependant, les modèles d’entreprise d’abonnement seront probablement intenables pour la plupart des éditeurs sans embargo. La rapidité de ce changement dépendra en partie des décisions politiques des agences, telles que la version d’une publication dont elles ont besoin pour être en libre accès lors de la publication et la restriction à laquelle une licence doit être appliquée (Clark et Esposito). Le mémo ne promet pas de financement supplémentaire pour le soutien de la politique mise à jour, bien qu’il mentionne que les coûts associés peuvent être inclus dans les budgets de recherche. On ne sait pas quels seront les coûts de mise en œuvre de la politique, comment ils seront payés et par qui. Ceci est vrai pour les publications et pour les données de recherche, qui nécessiteront beaucoup d’infrastructures et un soutien financier important à long terme (voir Clark et Esposito ; Michael, Carpenter et al. 2022). La réponse du [https://datacurationnetwork.org/2022/09/06/dcn-is-ready-to-support-policies-resulting-from-ostp-public-access-memo%25EF%25BF%25BC/ Data Curation Network] à la mise à jour de la politique met en évidence le rôle clé que les dépôts institutionnels joueront dans la fourniture de l’infrastructure nécessaire à sa mise en œuvre. Une déclaration de [https://www.asbmb.org/advocacy/position-statements/asbmb-statement-on-ostp-memo l’American Society for Biochemistry and Molecular Biology] souligne que le financement de la recherche n’a pas suivi le rythme du coût croissant de la recherche et de la publication et appelle l’OSTP et les décideurs politiques à relever ce défi. Certains ont également remis en cause l’exhaustivité et la validité du rapport économique qui a éclairé cette politique (par exemple, D’Agostino 2022 ; Michael, Vines et al. 2022 ; White 2022). Certaines parties prenantes s’inquiètent des effets potentiels de la politique sur l’équité dans le domaine de l’édition savante. Bien que la politique ne promette pas de financement supplémentaire et n’impose pas d’approche ou de modèle spécifique pour libre accès, elle stipule que les agences fédérales devraient permettre l’inclusion des coûts de publication raisonnables dans les budgets de recherches, en consultation avec l’Office of Mangaement and Budget. Les parties prenantes sont concernées donc que le libre accès sera financé principalement par les frais de publication des articles et que les coûts de gestion des données soient également répercutés sur les auteurs (Clark et Esposito 2022 ; Pooley 2022). Notant qu’une dépendance croissante aux frais de publication est probable, Jefferson Pooley souligne que libre accès soutenu financièrement de cette manière est déjà la norme aux États-Unis, surtout la publication dans les revues hybrides et les accords de lecture et de publication et d’autres accords transformatifs (voir «&#8239;[[Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Les accords de libre accès|Les accords de libre accès]]&#8239;»). Il demande des mesures pour atténuer les effets qui en résultent, comme le soutien à des modèles alternatifs et des plafonds sur les frais de publication. Une déclaration de [https://subscribetoopencommunity.org/ la communauté de pratique Subscribe to Open] soutient la politique et demande une multiplicité d’approches pour atteindre ses objectifs (2022). Les bibliothèques de l’University of California décrivent la politique comme soutenant ses efforts afin de faire progresser le libre accès, suggérant que la politique pourrait inciter les éditeurs à abandonner le modèle d’abonnement payant et à développer des modèles d’entreprise entièrement différents conçus pour le libre accès (2022 ; voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/La rupture entre Elsevier et l'University of California|La rupture entre Elsevier et l’University of California]]&#8239;»). Il est également noté que toute augmentation des coûts pour les grands instituts de recherche en raison de l’élargissement de la lecture et de la publication ou de modèles similaires pourrait être compensée par les contributions des chercheurs et des chercheuses incluses dans les propositions de financement (2022). [https://scholarlykitchen.sspnet.org/2022/09/27/academia-zero-embargo/ Roger Schonfeld] note que certains éditeurs miseront sur la valeur qu’ils offrent en fournissant une version de record, citant en exemple [https://www.science.org/journal/science ''Science''], publié par l’AAAS, qui a annoncé [https://www.science.org/doi/10.1126/science.ade8028 une politique de libre accès verte] en réponse au mémo Nelson et en opposition à l’exclusion des tendances du libre accès basées sur les frais de publication. Si le modèle «&#8239;payer pour publier&#8239;» devient plus établi, cependant, une conséquence serait de rendre la publication moins accessible aux chercheurs et chercheuses sans financement ou avec un financement insuffisant, y compris ceux et celles qui sont en début de leur carrière, qui viennent des plus petites institutions et qui font partie des disciplines avec moins de financement, y compris les sciences humaines. Une lettre ouverte à l’OSTP coordonnée par [https://neuromatch.io/ Neuromatch] avec plus de 1300 signatures souligne cette préoccupation, indiquant que la politique peut améliorer l’accès équitable mais rendre la participation à la recherche moins équitable, avec des conséquences graves pour le progrès de la recherche. [https://www.arl.org/news/arl-celebrates-biden-harris-administrations-historic-policy-to-make-federally-funded-research-immediately-available/ L’Association of Research Libraries], cependant, fait l’éloge de la politique comme de celle qui fait progresser l’équité pour les personnes issues des milieux défavorisés et pour les chercheurs et chercheuses en début de leur carrière ainsi que comme de celle qui garantit que les résultats sont accessibles aux personnes handicapées (Aiwuyor 2022). Il souligne aussi l’accent mis par la politique sur l’harmonisation des politiques entre les agences afin de réduire la pression sur des bibliothèques de recherche. Un article du [https://www.libraryjournal.com/story/technology/white-house-make-public-access-to-research-immediate ''Library Journal''] souligne de la même manière l’objectif de la politique d’améliorer l’équité (Peet 2022). ==Le mémo Nelson et la science ouverte== Le mémo Nelson contextualise ses mises à jour de politique dans le cadre de la transition généralisée vers libre accès pour la recherche sur le COVID-19 (voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Science Ouverte et COVID-19|Science ouverte et COVID-19]]&#8239;»). Il note qu’à la suite de cette crise de santé publique, le gouvernement, l’industrie et les chercheurs et chercheuses ont travaillé ensemble volontairement pour adopter une politique d’accès public immédiat, ce qui a donné des conséquences formidables. Ces conséquences sont les suivantes : la recherche et les données ont circulé efficacement et des résultats accessibles ont accéléré la vitesse de la découverte et de la mise en pratique. Il indique également que le libre accès est aligné sur les valeurs américaines fondamentales d’égalité des chances et que rendre la science publique aidera les États-Unis à devenir un leader mondial de la science ouverte. Bien qu’une mise à jour de la politique de 2013 ait été rédigée en 2018, l’élan du mouvement libre accès à cause du COVID-19 a contribué au timing de la publication du mémo Nelson; l’émergence du virus monkeypox et l’intérêt personnel du président américain Biden pour l’accès publique peuvent également être des facteurs contributifs (Najokaitytė et Hudson 2022 ; Nelson 2022). L’accent mis par le mémo sur l’équité et la nécessité d’augmenter la confiance du public dans la science reflètent également les valeurs professionnelles de Nelson. Nelson est professeure de sociologie à l’Université de Columbia et présidente du [https://www.ssrc.org/staff/nelson-alondra/ Social Science Research Council], et ses recherches examinent les intersections entre les inégalités sociales et la science et la technologie. Comme l’ont noté [https://sparcopen.org/news/2022/taxpayers-to-get-immediate-access-to-publicly-funded-research/ SPARC], [https://www.coalition-s.org/coalition-s-welcomes-the-updated-open-access-policy-guidance-from-the-white-house-office-of-science-technology-and-policy/ la cOAlition S] et [https://creativecommons.org/2022/08/26/a-big-win-for-open-access/ Creative Commons], la disposition de la politique qui élimine l’embargo s’aligne dans une certaine mesure sur les politiques internationales de libre accès telles que [https://www.coalition-s.org/ le Plan S] et la [https://unesdoc.unesco.org/ark:/48223/pf0000379949_fre Recommandation de l’UNESCO sur une science ouverte] (voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Plan S et cOAlition S|Plan S et cOAlition S]]&#8239;», «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Mise à jour du Plan S : La Stratégie de conservation des droits|Mise à jour du Plan S : La stratégie de conservation des droits]]&#8239;», «&#8239;[[Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Mise à jour du Plan S : L’élargissement de l’adhésion de la cOAlition S|Mise à jour du Plan S : L’élargissement de l’adhésion de la cOAlition S]]&#8239;» et «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/La Recommandation de l’UNESCO sur la science ouverte|La recommandation de l’UNESCO sur la science ouverte]]&#8239;»). Cependant, contrairement au Plan S, le mémo Nelson n’exclut pas les revues hybrides ni ne demande que le droit d’auteur reste aux auteurs (Clark et Esposito 2022). La déclaration de [https://creativecommons.org/2022/08/26/a-big-win-for-open-access/ Creative Commons] célèbre la politique mais appelle à un soutien supplémentaire pour les licences ouvertes et les infrastructures ouvertes dirigées par la communauté (Green 2022). La politique mise à jour s’applique à toutes les recherches financées par le gouvernement fédéral, y compris les organismes de financement des sciences humaines et sociales qui ont été exclus de la politique de 2013, tels que [https://www.arts.gov/ le National Endowment for the Arts] et [https://www.neh.gov/ le National Endowment for the Humanities]. Le mémo Nelson, cependant, ne fait pas référence aux sciences humaines spécifiquement, contrairement au Plan S et à la Recommandation de l’UNESCO (cOAlition S, s.d. ; UNESCO 2020). Malgré cela, Karin Wulf note que la politique mise à jour renforcera la science ouverte en sciences humaines, ce qui, selon elle, est désespérément nécessaire à notre époque historique actuelle (Michael, Carpenter et al. 2022). L’OSTP a estimé que le financement fédéral américain a soutenu 195 000 à 263 000 articles en 2020, ce qui représente environ 7 à 9 % des articles publiés dans le monde (Brainard et Kaiser 2022). La façon dont les agences mettront en œuvre la politique mise à jour déterminera dans une large mesure son effet sur les auteurs, les éditeurs et l’écosystème de l’édition dans son ensemble. Bien que le mémo Nelson présente une politique nationale de libre accès aux États-Unis, la taille pure de l’effort d’édition savante aux États-Unis signifie que les effets du mémo Nelson seront sûrement répandus, notamment en contribuant à l’élan du mouvement libre accès dans le monde entier. ==Ouvrages cités== *Aiwuyor, Jessica. s.d. «&#8239;ARL Celebrates Biden-Harris Administration’s Historic Policy to Make Federally Funded Research Immediately Available&#8239;». Association of Research Libraries. Le 20 octobre 2022. [https://www.arl.org/news/arl-celebrates-biden-harris-administrations-historic-policy-to-make-federally-funded-research-immediately-available/ https://www.arl.org/news/arl-celebrates-biden-harris-administrations-historic-policy-to-make-federally-funded-research-immediately-available/]. *American Institute of Physics. 2022. «&#8239;White House Moves to Make Federally Funded Research Free Upon Publication&#8239;». American Institute of Physics. Le 30 août 2022. [https://www.aip.org/fyi/2022/white-house-moves-make-federally-funded-research-free-upon-publication https://www.aip.org/fyi/2022/white-house-moves-make-federally-funded-research-free-upon-publication]. *Anderson, Rick. 2022. «&#8239;A New OSTP Memo: Some Initial Observations and Questions&#8239;». ''The Scholarly Kitchen''. Le 29 août 2022. [https://scholarlykitchen.sspnet.org/2022/08/29/a-new-ostp-memo-some-initial-observations-and-questions/ https://scholarlykitchen.sspnet.org/2022/08/29/a-new-ostp-memo-some-initial-observations-and-questions/]. *Anderson, Rick, et Karin Wulf. 2022. «&#8239;Thoughts and Observations on the OSTP Responses to Our Interview Questions&#8239;». ''The Scholarly Kitchen''. Le 13 octobre 2022. [https://scholarlykitchen.sspnet.org/2022/10/13/thoughts-and-observations-on-the-ostp-responses-to-our-interview-questions/ https://scholarlykitchen.sspnet.org/2022/10/13/thoughts-and-observations-on-the-ostp-responses-to-our-interview-questions/]. *Brainard, Jeffrey, et Jocelyn Kaiser. «&#8239;White House Requires Immediate Public Access to All U.S.-Funded Research Papers by 2025&#8239;». ''Science'', le 26 août 2022. [https://www.science.org/content/article/white-house-requires-immediate-public-access-all-u-s--funded-research-papers-2025 https://www.science.org/content/article/white-house-requires-immediate-public-access-all-u-s--funded-research-papers-2025]. *Clark and Esposito. «&#8239;Zero Embargo&#8239;». ''The Brief'', le 29 août 2022. [https://www.ce-strategy.com/the-brief/zero-embargo/ https://www.ce-strategy.com/the-brief/zero-embargo/]. *cOAlition S. s.d. «&#8239;Why Plan S&#8239;». Consulté le 20 octobre 2022. [https://www.coalition-s.org/why-plan-s/ https://www.coalition-s.org/why-plan-s/]. *D’Agostino, Susan. 2022. «&#8239;Who’ll Pay for Public Access to Federally Funded Research?&#8239;» ''Inside Higher Ed''. Le 12 septembre 2022. [https://www.insidehighered.com/news/2022/09/12/wholl-pay-public-access-federally-funded-research https://www.insidehighered.com/news/2022/09/12/wholl-pay-public-access-federally-funded-research]. *D’Agostino, Susan, et Doug Lederman. «&#8239;No Paywall for Taxpayer-Funded Research, U.S. Declares&#8239;». ''Inside Higher Ed'', le 26 août 2022. [https://www.insidehighered.com/news/2022/08/26/us-mandates-immediate-public-access-taxpayer-funded-research https://www.insidehighered.com/news/2022/08/26/us-mandates-immediate-public-access-taxpayer-funded-research]. *Green, Cable. 2022. «&#8239;A Big Win for Open Access: United States Mandates All Publicly Funded Research Be Freely Available with No Embargo&#8239;». ''Creative Commons''. Le 26 août 2022. [https://creativecommons.org/2022/08/26/a-big-win-for-open-access/ https://creativecommons.org/2022/08/26/a-big-win-for-open-access/]. *Holdren, John P. 2013. «&#8239;Increasing Access to the Results of Federally Funded Scientific Research&#8239;». Office of Science and Technology Policy. [https://obamawhitehouse.archives.gov/sites/default/files/microsites/ostp/ostp_public_access_memo_2013.pdf https://obamawhitehouse.archives.gov/sites/default/files/microsites/ostp/ostp_public_access_memo_2013.pdf]. *Husband, Shelley. 2022. «&#8239;Statement from Shelley Husband, Senior Vice President, Government Affairs, AAP, on Decision by The White House Office of Science and Technology Policy to Make Private Sector Publications Freely Available&#8239;». ''Association of American Publishers''. Le 25 août 2022. [https://publishers.org/news/statement-from-shelley-husband-senior-vice-president-government-affairs-association-of-american-publishers-on-decision-by-white-house-office-of-science-and-technology-policy-to-make-private-se/ https://publishers.org/news/statement-from-shelley-husband-senior-vice-president-government-affairs-association-of-american-publishers-on-decision-by-white-house-office-of-science-and-technology-policy-to-make-private-se/]. *Liuta, Ioana. 2022. «&#8239;Important Milestone in the Open Access Movement: Immediate Open Access by 2026, in the US&#8239;». ''Radical Access''. Le 28 octobre 2022. [https://www.lib.sfu.ca/help/publish/scholarly-publishing/radical-access/ostp-nelson-memo-open-access https://www.lib.sfu.ca/help/publish/scholarly-publishing/radical-access/ostp-nelson-memo-open-access]. *Michael, Ann, et al. «&#8239;Ask The Chefs: OSTP Policy Part I&#8239;». ''The Scholarly Kitchen'', le 30 août 2022. [https://scholarlykitchen.sspnet.org/2022/08/30/ask-the-chefs-ostp-policy-i/ https://scholarlykitchen.sspnet.org/2022/08/30/ask-the-chefs-ostp-policy-i/]. *Michael, Ann, et al. 2022. «&#8239;Ask The Chefs: OSTP Policy Part II&#8239;». ''The Scholarly Kitchen''. Le 31 août 2022. [https://scholarlykitchen.sspnet.org/2022/08/31/ask-the-chefs-ostp-policy-ii/ https://scholarlykitchen.sspnet.org/2022/08/31/ask-the-chefs-ostp-policy-ii/]. *Naujokaitytė, Goda, et Richard L. Hudson. s.d. «&#8239;Washington Gives a Big Boost to Drive for Open-Access Scientific Publishing&#8239;». ''Science|Business''. Le 13 octobre 2022. [https://sciencebusiness.net/news/washington-gives-big-boost-drive-open-access-scientific-publishing https://sciencebusiness.net/news/washington-gives-big-boost-drive-open-access-scientific-publishing]. *Nelson, Alondra. 2022. «&#8239;Ensuring Free, Immediate, and Equitable Access to Federally Funded Research&#8239;». Office of Science and Technology Policy. [https://www.whitehouse.gov/wp-content/uploads/2022/08/08-2022-OSTP-Public-Access-Memo.pdf https://www.whitehouse.gov/wp-content/uploads/2022/08/08-2022-OSTP-Public-Access-Memo.pdf]. *Open Access Australasia. «&#8239;Open Access Australasia Comment on US White House OSTP Public Access Guidance&#8239;». Open Access Australasia, le 31 août 2022. [https://oaaustralasia.org/2022/08/31/open-access-australasia-comment-on-us-white-house-ostp-public-access-guidance https://oaaustralasia.org/2022/08/31/open-access-australasia-comment-on-us-white-house-ostp-public-access-guidance]. *«&#8239;Open Letter to the WHOSTP and Subcommittee on Open Science&#8239;». s.d. Consulté le 18 octobre 2022. [https://ostp-letter.github.io https://ostp-letter.github.io]. *Peet, Lisa. 2022. «&#8239;White House: Make Public Access to Research Immediate&#8239;». ''Library Journal'', le 26 septembre 2022. [https://www.libraryjournal.com/story/technology/white-house-make-public-access-to-research-immediate https://www.libraryjournal.com/story/technology/white-house-make-public-access-to-research-immediate]. *Pooley, Jefferson. «&#8239;The APC Question Mark Hovering over the OSTP Announcement&#8239;». ''LSE Blog'', le 2 septembre 2022. [https://blogs.lse.ac.uk/impactofsocialsciences/2022/09/02/the-apc-question-mark-hovering-over-the-ostp-announcement/ https://blogs.lse.ac.uk/impactofsocialsciences/2022/09/02/the-apc-question-mark-hovering-over-the-ostp-announcement/]. *Racy, Famira. «&#8239;Embargo No More!&#8239;» Public Knowledge Project, le 29 août 2022. [https://pkp.sfu.ca/2022/08/29/embargo-no-more/ https://pkp.sfu.ca/2022/08/29/embargo-no-more/]. *Schonfeld, Roger C. 2022. «&#8239;How Will Academia Handle the Zero Embargo?&#8239;» ''The Scholarly Kitchen''. Le 27 septembre 2022. [https://scholarlykitchen.sspnet.org/2022/09/27/academia-zero-embargo/ https://scholarlykitchen.sspnet.org/2022/09/27/academia-zero-embargo/]. *Subscribe to Open Community of Practice. «&#8239;Subscribe-to-Open Community of Practice Statement on the OSTP ‘Nelson Memo’&#8239;». SPARC, le 16 septembre 2022. [https://sparcopen.org/news/2022/subscribe-to-open-community-of-practice-statement-on-the-ostp-nelson-memo/ https://sparcopen.org/news/2022/subscribe-to-open-community-of-practice-statement-on-the-ostp-nelson-memo/]. *UNESCO. 2020. «&#8239;Recommandation de l’UNESCO sur une science ouverte&#8239;». [https://unesdoc.unesco.org/ark:/48223/pf0000379949_fre https://unesdoc.unesco.org/ark:/48223/pf0000379949_fre.] *University of California, Office of Scholarly Communication. 2022. «&#8239;‘Wind in Our Sails’: University of California Hails White House Guidance Accelerating Public Access to Federally Funded Research&#8239;». ''University of California, Office of Scholarly Communication''. Le 26 août 2022. [https://osc.universityofcalifornia.edu/2022/08/wind-in-our-sails-university-of-california-hails-white-house-ostp-guidance/ https://osc.universityofcalifornia.edu/2022/08/wind-in-our-sails-university-of-california-hails-white-house-ostp-guidance/]. *White, Meg. «&#8239;The Nelson Memo: More Questions than Answers&#8239;». ''Charleston Hub'', le 6 septembre 2022.[https://www.charleston-hub.com/2022/09/the-nelson-memo-more-questions-than-answers/ https://www.charleston-hub.com/2022/09/the-nelson-memo-more-questions-than-answers/]. *Zahneis, Megan. «&#8239;‘A Historic Moment’: New Guidance Requires Federally Funded Research to Be Open Access&#8239;». ''The Chronicle of Higher Education'', le 25 août 2022. [https://www.chronicle.com/article/a-historic-moment-new-guidance-requires-federally-funded-research-to-be-open-access https://www.chronicle.com/article/a-historic-moment-new-guidance-requires-federally-funded-research-to-be-open-access]. [[Catégorie:Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024 (livre)]] 1ae6kudh9ghmlm0es57dzsscetamqkn Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/La Semaine internationale du libre accès 2022, le 24–30 octobre 0 82367 744021 742534 2025-06-02T22:54:51Z LodestarChariot2 120009 /* Ouvrage cité */ 744021 wikitext text/x-wiki ''Cette observation a été écrite par Caroline Winter (avec remerciements à Virginia Barbour pour ses commentaires et contributions), pour le Electronic Textual Cultures Laboratory et le partenariat Implementing New Knowledge Environments.'' La 15e [https://www.openaccessweek.org/ Semaine internationale du libre accès] s’est déroulée du 24 au 30 octobre. Le thème de cette année était « Ouvert à la justice climatique », reconnaissant que les effets généralisés du changement climatique sont vécus différemment par différents groupes de personnes. Une des façons dont cette injustice se manifeste est à travers les niveaux inéquitables d’accès aux connaissances et à l’information sur le changement climatique, alors le libre accès « peut créer des voies vers un partage plus équitable des connaissances et servir de moyen de lutte contre les inégalités qui conditionnent les impacts du changement climatique et notre réponse à ces derniers » (« Semaine » 2022). La Semaine internationale du libre accès est une initiative de [https://sparcopen.org/ SPARC] et du [https://www.openaccessweek.org/about Comité consultatif de la Semaine du libre accès]. C’est l’occasion pour les communautés de recherche et du monde entier d’organiser des événements sous une bannière commune et d’attirer l’attention du public sur le libre accès. Cette année, des événements en personne, virtuels et hybrides, allant des ateliers et des conférences publiques à des projections de films et des cours de formation, ont eu lieu. ==Semaine internationale du libre accès dans la presse== La Semaine internationale du libre accès n’a pas été largement couverte par la presse. Cependant, le site Web technologique [https://www.hpcwire.com/off-the-wire/cern-to-host-open-access-week-event-oct-24-28/ ''HPCwire''] a mentionné [https://indico.cern.ch/event/1179488/ les événements organisés par le Scientific Information Service du CERN], qui comprenaient une série de discussions en ligne qui a été enregistrée et peut être visionnée en ligne. [https://www.researchinformation.info/interview/us-every-week-open-access-week ''Research Information''] a également publié une entrevue avec le directeur de la publication d’Oxford University Press, Rhodri Jackson, qui s’est concentrée sur ses événements de la Semaine du libre accès et sur les initiatives du libre accès de l’éditeur. En outre, [https://asiapacificreport.nz/2022/10/26/fiji-academic-warns-over-media-climate-injustice-in-open-access-webinar/ ''Asia Pacific Report''] a mentionné un panel de médias sur l’injustice climatique qui faisait partie de l’agenda [https://oaaustralasia.org/events/open-access-week-2022/ d’Open Access Australasia pour la Semaine du libre accès]. ==La Semaine internationale du libre accès et le Partenariat INKE== Plusieurs membres du Partenariat INKE ont organisé des célébrations. La [https://www.lib.sfu.ca/help/publish/scholarly-publishing/open-access/open-access-week bibliothèque de l’Université Simon Fraser] a organisé une série d’ateliers, une exposition des affiches et des tableaux ainsi qu’une collection sur la justice climatique dans son dépôt institutionnel. Le [https://pkp.sfu.ca/2022/10/20/celebrating-open-access-week-open-for-climate-justice/ Public Knowledge Project] a célébré avec une collection de recherche liée au climat, comprenant des revues ouvertes et des articles publiés avec son logiciel [https://pkp.sfu.ca/ojs/ Open Journal Systems]. [https://oaaustralasia.org/events/open-access-week-2022/ Open Access Australasia,] un partenaire de l’INKE via le [https://inke.ca/canadian-australian-partnership-for-open-scholarship/ Canadian–Australian Partnership for Open Scholarship (CAPOS),] a organisé un programme d’événements comprenant des tables rondes et un « hackathon » collaboratif dont le but était de développer un guide ouvert des ressources sur la justice climatique pour les enseignants. Les enregistrements de tous les webinaires sont disponibles pour visionnement. Selon Virginia Barbour, directrice d’Open Access Australasia, un des objectifs principaux des événements de la semaine en Australie et en Nouvelle-Zélande était l’inclusion des chercheurs et chercheuses, des journalistes et des militants et militantes du climat de la région Pacifique, où, bien sûr, les effets du changement climatique se font sentir le plus intensément. Les membres de la communauté de recherche du Pacifique ont souligné toutes sortes des inégalités en ce qui concerne la recherche : non seulement le manque d’accès à la recherche, mais aussi les obstacles à la publication de la recherche en raison du coût et, enfin, le manque de la consultation et du partage de la recherche avec les communautés affectées. Les journalistes du Pacifique ont soulevé les risques d’un manque de diversité dans le journalisme, en particulier dans les langues locales. ==La Semaine internationale du libre accès et communauté universitaire élargie== Voici un aperçu des événements qui ont eu lieu au Canada et dans le monde. Une liste plus complète est disponible sur [https://www.openaccessweek.org/events le site Web de la Semaine internationale du libre accès]. De nombreuses universités canadiennes ont organisé des événements pour célébrer la semaine. [https://library.concordia.ca/research/open-access/open-access-week.php La Bibliothèque de l’Université Concordia] a organisé un salon transdisciplinaire comprenant des conférences, des ateliers et des expositions numériques interactives. [https://libraryguides.mcgill.ca/c.php?g=518294&p=3544275 La Bibliothèque de l’Université McGill] a également organisé des ateliers ainsi qu’une projection du film ''Paywall: The Business of Scholarship'' (voir « [[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Le Film Paywall : The Business of Scholarship|Le Film ''Paywall: The Business of Scholarship'']] »).] [https://uwaterloo.ca/open-scholarship/news/archive/2022-10 L’Université de Waterloo] a publié une série d’articles dans son ''Daily Bulletin'' sur la justice climatique. [https://utsc.library.utoronto.ca/join-us-open-access-week-2022 L’Université de Toronto Scarborough] a organisé un quiz sur le libre accès sur Twitter et a encouragé sa communauté de recherche à déposer les travaux dans le dépôt institutionnel en l’honneur de la Semaine du libre accès. De même, [https://library.uwinnipeg.ca/news/2022/10/open-access-week-20221.html l’Université de Winnipeg] a partagé un portail de recherche ouverte sur les changements climatiques accueillie dans son dépôt institutionnel. En Afrique, [https://www.eifl.net/events/open-access-week-2022 Electronic Information for Libraries (EIFL)] a marqué la semaine en mettant en avant son [https://www.eifl.net/programmes/open-access-programme programme], qui plaide en faveur du libre accès et de la recherche ouverte aux niveaux national et international et renforce les capacités de publication de revues ouvertes et de dépôts en libre accès, entre autres activités. La Semaine du libre accès a été largement célébrée en Europe. [https://scienceeurope.org/news/open-access-week-2022-science-europe/ Science Europe] a souligné la publication récente de son document de la nouvelle orientation [https://scienceeurope.org/our-resources/direction-paper-open-science/ ''Open Science as Part of a Well-Functioning Research System,''] soulignant également ses efforts pour faire progresser le libre accès diamant (voir « [[Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Un plan d’action pour faire avancer le libre accès diamant|Un plan d’action pour faire progresser le libre accès diamant]] »). L’organisation européenne d’infrastructure de science ouvertes [https://www.openaire.eu/oaweek2022 OpenAIRE] a organisé deux séries de webinaires, avec deux sessions axées sur l’élaboration des politiques: Research Communities & Climate Action et Being Open to Drive Change and Open Data in the Forefront: Driving Policy Decisions for Climate Justice. Le [https://openaccess.dk/oaw2022 Danish Network for Open Access] a organisé une série de webinaires, et de nombreuses autres organisations de recherche européennes ont également célébré avec des événements au cours de la semaine. Aux États-Unis, [https://acrl.ala.org/acrlinsider/celebrate-open-access-week-2022/ l’Association of College and Research Libraries] de l’American Library Association a célébré en mettant en avant ses livres, revues et bulletins d’information en libre accès ainsi que certains de ses ateliers, podcasts et webinaires ouverts. De nombreuses bibliothèques universitaires ont également organisé des événements pour marquer la semaine, rassemblés dans une liste de [https://www.arl.org/blog/arl-member-libraries-promote-open-access-week-2022/ l'Association of Research Libraries]. Plusieurs éditeurs ont également marqué la Semaine internationale du libre accès. Cambridge University Press a célébré en mettant en avant certaines de ses initiatives en libre accès, telles que son programme [https://www.research4life.org/ Research4Life] pour les institutions des pays à revenu faible et intermédiaire et son programme [https://www.cambridge.org/core/services/open-research/open-access/oa-book-pilot-flip-it-open Flip it Open], grâce auquel les monographies sont inversées pour être ouvertes une fois qu’elles atteignent un certain niveau de vente (voir « [[Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Une mise à jour sur les monographies en libre accès|Une mise à jour sur les monographies en libre accès]] »). MIT Press a mis en évidence certains de ses articles de revues et livres en libre accès liés à la justice climatique et à ses initiatives de publication en libre accès, y compris son modèle de publication Direct to Open pour les monographies et les collections éditées (voir « [[Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Les accords de libre accès|Les monographies en libre accès]] »). Le blogue Early Career Researchers Community du PLOS a présenté un [https://ecrcommunity.plos.org/2022/10/30/open-access-week-2022-open-for-climate-justice/ article sur la Semaine du libre accès], notant que les chercheurs et chercheuses émergents jouent un rôle important dans l’avancement du libre accès. ==La Semaine internationale du libre accès et la science ouverte== Le libre accès est une composante importante de la science ouverte, et en attirant l’attention du public et en renforçant la communauté autour du libre accès, la Semaine internationale du libre accès contribue à faire progresser la science ouverte plus largement. ==Ouvrage cité== *«&#8239;Semaine de l'open access 2022: Ouvert pour la justice climatique&#8239;». 2022. International Open Access Week. [https://www.openaccessweek.org/theme/fr https://www.openaccessweek.org/theme/fr]. [[Catégorie:Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024 (livre)]] m9mqjwzsf1lyzcdgcuhg83ocas1jbgg Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Les droits de propriété intellectuelle et la science ouverte en Europe 0 82370 744022 742615 2025-06-02T23:05:22Z LodestarChariot2 120009 /* Ouvrages cités */ 744022 wikitext text/x-wiki ''Cette observation a été écrite par Caroline Winter, avec ses remerciements à Iryna Kuchma et John Willinsky pour leurs commentaires et contributions.'' L'intersection des droits de propriété intellectuelle (DPI) et de la science ouverte est depuis longtemps une question d'intérêt pour le milieu de la recherche et pour l'industrie. Les politiques et la législation en matière de propriété intellectuelle visent à établir un équilibre entre les droits moraux et économiques des créateurs et créatrices de leurs œuvres et les droits et intérêts du grand public. La nécessité de comprendre comment les DPI et la science ouverte interagissent est devenue plus pressante à mesure que le mouvement de la science ouverte a progressé. Cela est particulièrement vrai dans le contexte de la pandémie de COVID-19, qui a mis en évidence le pouvoir de la recherche ouverte et collaborative de résoudre des défis complexes et mondiaux (voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Science Ouverte et COVID-19|Science ouverte et COVID-19]]&#8239;»). En 2019, les membres de l'UNESCO ont demandé un instrument pour construire un consensus international autour de la science ouverte, et la [https://unesdoc.unesco.org/ark:/48223/pf0000379949_fre Recommandation de l'UNESCO sur une science ouverte] a été publiée en novembre 2021 (voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/La Recommandation de l’UNESCO sur la science ouverte|La Recommandation de l'UNESCO sur la science ouverte]]&#8239;»). La tension possible entre la science ouverte et les DPI a été l'une des questions clés identifiées lors des consultations de l'UNESCO. En avril 2021, l'UNESCO a abordé cette question en organisant une réunion d'experts en ligne [https://www.unesco.org/en/articles/expert-meeting-open-science-and-intellectual-property-rights sur la science ouverte et les DPI], réunissant plus de 500 participants, y compris six experts et expertes invités. Comme il est indiqué dans le [https://en.unesco.org/sites/default/files/report_expert_meeting_ipr_os_23apr.pdf rapport de la Réunion d'experts], les messages clés suivants sont ressortis de la discussion : # Étant donné qu'il existe des tensions possibles entre les DPI et la science ouverte, des politiques et des approches stratégiques équilibrées sont nécessaires. # Plutôt que d'être un obstacle à la science ouverte, un cadre de propriété intellectuelle bien défini peut promouvoir l'ouverture et la collaboration : par exemple, les licences ouvertes peuvent aider à garantir que toutes les contributions à la recherche sont reconnues. # Il est également nécessaire de comprendre les complexités et les diverses formes des DPI et leurs différentes implications pour la science ouverte, y compris la façon dont elles se croisent avec d'autres systèmes réglementaires (UNESCO 2021). En Europe, les tensions possibles entre les DPI et la science ouverte ont été abordées dans plusieurs études et rapports publiés au cours des dernières années, parallèlement à des politiques appelant à une plus grande ouverture, telles que [https://www.coalition-s.org/ le Plan S] (lancé en 2018) (voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Plan S et cOAlition S|Plan S et coAlition S]]&#8239;», «&#8239;[[Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Mise à jour du Plan S : L’élargissement de l’adhésion de la cOAlition S|Mise à jour du Plan S : l’élargissement de l’adhésion de la cOAlition S]]&#8239;» et «&#8239;[[Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Les Fonds de recherche du Québec rejoignent la cOAlition S|Les Fonds de Recherche du Québec se rejoignent la cOAlition S]]&#8239;»). En 2017, le [https://commission.europa.eu/about-european-commission/departments-and-executive-agencies/joint-research-centre_en Centre commun de recherche (JRC) de la Commission européenne] et la [https://commission.europa.eu/about-european-commission/departments-and-executive-agencies/research-and-innovation_en Direction générale de la recherche et de l'innovation] ont organisé un atelier sur [https://op.europa.eu/en/publication-detail/-/publication/8294fcb4-8df7-11e7-b92d-01aa75ed71a1/language-en ''IPR, technology transfer & open science'']. Les conclusions de l'atelier comprenaient que l'équilibre était nécessaire, que les DPI était un outil important pour assurer l'attribution en science ouverte, que les stratégies d'équilibre entre les deux devraient être éclairées par les meilleures pratiques existantes, et que le traitement de cette question était particulièrement urgent alors que l[https://eosc-portal.eu/ 'European Open Science Cloud] était en cours de développement (Crouzier 2017). En 2020, European Association of Research and Technology Associations (EARTO) a publié le livre blanc [https://www.earto.eu/wp-content/uploads/EARTO-Paper-Towards-a-Balanced-Approach-Between-IPRs-and-Open-Science-Policy-Final.pdf ''Towards a Balanced Approach Between IPRs and Open Science Policy'']. Bien qu'il appelle également à l'équilibre, le document suggère des cadres politiques et des approches qui soutiennent la commercialisation et l'innovation ouverte, un modèle de recherche, de développement et d'innovation impliquant la collaboration entre les universités, les entreprises et d'autres parties prenantes. En avril 2022, la European Federation of Academies of Sciences and Humanities (l’ALLEA) a publié la déclaration [https://allea.org/wp-content/uploads/2022/04/ALLEA-Statement-Aligning-IPR-with-Open-Science.pdf ''Aligning Intellectual Property Rights with Open Science'']. Cette déclaration met l'accent sur la commercialisation des innovations par le biais de brevets et souligne que la science ouverte peut être mise en œuvre dans le cadre des DPI. Par exemple, les brevets accordent aux créateurs et créatrices des droits exclusifs sur les innovations pendant un certain temps, mais lorsque les brevets expirent, ces innovations deviennent des connaissances ouvertes. L'étude de 2022 de Christina Angelopoulos [https://op.europa.eu/en/publication-detail/-/publication/884062d5-1145-11ed-8fa0-01aa75ed71a1 ''Study on EU Copyright and Related Rights and Access to and Reuse of Scientific Publications, Including Open Access''] analyse le rôle du régime de droits d'auteur de l'UE dans l'accès et la réutilisation des publications savantes. Elle offre des recommandations législatives et non législatives pour faciliter l'accès et demande un examen attentif des effets – intentionnels et non intentionnels – de chacun. Le rapport [https://op.europa.eu/en/publication-detail/-/publication/42d27e04-b715-11ec-b6f4-01aa75ed71a1/language-en ''Open Science and Intellectual Property Rights: How Can They Better Interact? State of the Art and Reflections''] a également été publié en avril 2022 par la Commission européenne. Ce rapport présente les résultats d'une méta-analyse de la littérature sur la science ouverte et la propriété intellectuelle de la dernière décennie, y compris la recherche publiée et la littérature grise (documents de politique, rapports et livres blancs). Il soutient que, bien qu'il existe une tension entre la science ouverte et la propriété intellectuelle, elles ne sont pas fondamentalement incompatibles. Elles doivent plutôt être équilibrées, c’est-à-dire aussi ouvertes que possible, aussi fermées que nécessaire (p. 2). Le rapport de la Commission européenne présente quelques conclusions générales ainsi que des recommandations pour des décideurs et décideuses politiques, chercheurs et chercheuses et des praticiens et praticiennes qui font écho à celles des autres rapports décrits ici. Ces constatations et recommandations peuvent être résumées en plusieurs thèmes : # Il doit y avoir un équilibre entre la protection de la propriété intellectuelle et le partage ouvert des connaissances, avec l'ouverture comme valeur par défaut. Idéalement, un cadre mondial des DPI devrait être mis au point pour la science ouverte qui soit adaptée à l'évolution des technologies et qui protège l'ouverture de la science fondamentale. # D'autres recherches sur la relation entre les DPI et la science ouverte sont nécessaires, en particulier celles sur l'effet de la réglementation de la propriété intellectuelle sur l'innovation, aux niveaux national et européen. Une meilleure compréhension de la valeur des œuvres et de l'infrastructure du domaine public, y compris l'Internet, est également nécessaire. # Bien que le financement gouvernemental et les réglementations en matière de propriété intellectuelle aient tendance à encourager les innovations qui peuvent aider à résoudre des défis mondiaux complexes (p. ex. la recherche sur la COVID-19), nous devons considérer de manière holistique la véritable valeur de la science ouverte et collaborative et les coûts réels de la protection des innovations potentiellement vitales en tant que propriété intellectuelle. # Les choix des chercheurs et chercheuses quant à leur travail doivent être respectés. Ils ne devraient pas être pénalisés pour avoir fait la science ouverte, par exemple en raison de charges administratives ou financières supplémentaires. En même temps, leurs DPI et les modalités de réutilisation des données doivent être respectés. # Les praticiens et praticiennes doivent être au courant des meilleures pratiques de la communauté des logiciels ouverts, y compris l'utilisation des licences à jour, la diversité des licences, la normalisation des licences et le processus de les rendre lisibles par l’homme et la machine, la création des communautés de pratique et la mentalité «&#8239;release early, release often&#8239;». Au niveau politique, le rapport appelle à la création d'un Office for Free Intellectual Property Rights and Open Science, qui serait aligné sur [https://eur-lex.europa.eu/legal-content/FR/TXT/HTML/?uri=CELEX:52020DC0760&qid=1689012632159 le Plan d’action en faveur de la propriété intellectuelle] de l'Union européenne et qui pourrait être financé par Horizon Europe. Il appelle également à une révision de la législation européenne en matière de propriété intellectuelle relative aux hyperliens, aux exceptions au droit d'auteur pour l'exploration de textes et de données et aux prélèvements sur le droit d'auteur. Le rapport se termine par un appel à réviser et à adapter la réglementation en matière de propriété intellectuelle pour l'aligner sur les nouvelles technologies développées au cours des dernières décennies. Il soutient que l'ouverture de recherche et de la science bien que leurs processus devraient entraîner une transformation prometteuse de la science (p. 9). Un nouveau paradigme de propriété intellectuelle est nécessaire pour cette nouvelle ère numérique. ==DPI et la science ouvert dans la presse== Bien que le rapport de la Commission européenne n'ait pas été largement couvert dans la presse, la propriété intellectuelle et la science ouverte sont des questions d'intérêt pour les communautés universitaires et celles plus larges en Europe et en Amérique du Nord. Un article paru en 2020 dans [https://www.affairesuniversitaires.ca/articles-de-fond/article/le-neuro-de-montreal-porteur-de-changement-dans-les-sciences-universitaires/?_ga=2.127238605.1924387654.1689180763-1262500445.1689180763 ''University Affairs/Affaires universitaires''], par exemple, souligne la nécessité d'avoir des DPI moins restrictifs en biomédecine à travers l'exemple des chercheurs et chercheuses qui ont accéléré le développement d’un vaccin potentiel contre le SRAS en 2003, ce qui n'a été possible qu'en contournant les DPI (Voinigescu). Un document d'information récent d'Itzel Saldivar pour [https://www.timeshighereducation.com/campus/what-you-dont-know-about-ip-protections-should ''Times Higher Education''] décrit diverses formes de propriété intellectuelle – des brevets, droits d'auteur et marques de commerce – et soutient que les chercheurs et chercheuses devraient comprendre comment les DPI les affectent et affectent leur travail. Un article de Claire Woodcock dans ''Vice'' explique comment la [https://www.vice.com/en/article/epzyde/librarians-are-finding-thousands-of-books-no-longer-protected-by-copyright-law New York Public Library a découvert ]des milliers d'œuvres créatives publiées avant 1964 qui sont maintenant dans le domaine public parce que leur droit d'auteur n'a pas été renouvelé, une découverte faite à l'aide de XML source ouverte. Dans le cadre de discussions animées sur les promesses et les pièges de l’intelligence artificielle générative, un article du [https://www.wsj.com/articles/ai-chatgpt-dall-e-microsoft-rutkowski-github-artificial-intelligence-11675466857 ''Wall Street Journal''] traite des recours collectifs lancés par les créateurs et créatrices des médias qui affirment que les données utilisées pour former Dall-E 2, Stable Diffusion et des systèmes d’intelligence artificielle génératifs similaires sont de la propriété intellectuelle volée. ==Les réponses du Partenariat INKE== Plusieurs partenaires de l'INKE s'intéressent à des questions liées aux droits de propriété intellectuelle et à la science ouverte. Au nom de ses membres, [https://www.carl-abrc.ca/fr/ l'Association des bibliothèques de recherche du Canada (ABRC)] entreprend des initiatives liées à la politique sur le droit d'auteur. Par exemple, elle a contribué à [https://www.carl-abrc.ca/fr/influencer-les-politiques/droit-dauteur/examen-2018/ l'examen législatif de 2018 de la Loi sur le droit d'auteur] et a soumis une [https://www.carl-abrc.ca/wp-content/uploads/2021/04/FCAB-ABRC_Reponse_conjointe_consultation_prolongation_droit_dauteur.pdf réponse conjointe avec la Fédération canadienne des associations de bibliothèques (FCAB) à l'accord Canada-United States-Mexico (CUSMA)] en 2021. En 2020, [https://www.carl-abrc.ca/wp-content/uploads/2020/10/200921-le-droit-dauteur-de-la-Couronne.pdf l'ABRC et le FCAB ont soumis une lettre conjointe ][https://www.carl-abrc.ca/wp-content/uploads/2020/10/200921-le-droit-dauteur-de-la-Couronne.pdf aux ministres fédéraux ][https://www.carl-abrc.ca/wp-content/uploads/2020/10/200921-le-droit-dauteur-de-la-Couronne.pdf au sujet du droit d'auteur de la Couronne], demandant des licences ouvertes pour l'information gouvernementale afin d'améliorer l'accès du public à l'information sur la COVID-19. Il a également publié une [https://www.carl-abrc.ca/wp-content/uploads/docs/CARL_Statement_on_Fair_Dealing_2016_FR-1.pdf déclaration sur l'utilisation équitable et le droit d'auteur] en 2016 et est intervenu dans l'[https://www.carl-abrc.ca/influencing-policy/copyright/ affaire York University v. Access Copyright]. À l'automne 2022, John Willinsky du [https://pkp.sfu.ca/ Public Knowledge Project (PKP)] a fait une [https://pkp.sfu.ca/2022/10/18/the-pkp-amend-copyright-tour/ tournée Amend Copyright] en Europe et en Amérique du Nord pour plaider en faveur de l'inclusion du droit d'auteur dans les intentions du mouvement de libre accès. Sa position sur les licences légales pour les publications de recherche, dans lesquelles les DPI sont placés au service du libre accès, est décrite dans son livre en libre accès [https://doi.org/10.7551/mitpress/14201.001.0001 ''Copyright's Broken Promise: How to Restore the Law's Ability to Promote the Progress of Science ''](Willinsky). [https://www.crkn-rcdr.ca/fr/projet-sur-les-declarations-de-droits Le Projet sur les déclarations de droits] du [https://www.crkn-rcdr.ca/fr Réseau canadien de documentation pour la recherche (RCDR)] cherche une solution au problème des renseignements manquants et incomplets sur les droits dans [https://www.crkn-rcdr.ca/fr/collections-de-canadiana les collections Canadiana du RCDR]. Le projet est en train d'élaborer un cadre pour déterminer comment les matériaux du patrimoine numérique dans l'ensemble de la collection afin de protéger les droits des créateurs tout en rendant les collections aussi ouvertes et réutilisables que possible. ==Les réactions de l’ensemble de la communauté universitaire élargie== Dans un article de blog pour [https://www.the-guild.eu/blog/connecting-the-dots-iprs-knowledge-transfer-innova.html ''The Guild''], Alessandra Baccigotti, l'une des experts et expertes invités à la réunion d'experts de l'UNESCO, discute de la réunion au côté de la première [https://eua.eu/partners-news/969-eu-knowledge-valorisation-week-2023.html Semaine européenne de valorisation des connaissances], organisée par la Commission européenne, qui s'est déroulée du 27 au 30 avril 2021. Elle note qu'il y a souvent un scepticisme au sein de la communauté de la science ouverte sur les DPI et la valorisation des connaissances ou la recherche et l'innovation, et tout comme l'UNESCO et d'autres organisations travaillent à l'établissement de connaissances et d'un consensus sur la science ouverte, la même chose doit être faite pour les DPI. ==DPI et la science ouverte== Il a été largement reconnu au début de la pandémie de COVID-19 que l'ouverture et la collaboration étaient essentielles pour lutter contre la maladie, comme discuté [https://www.oecd.org/coronavirus/policy-responses/why-open-science-is-critical-to-combatting-covid-19-cd6ab2f9/ par l’OECD]. E. Richard Gold note dans un article paru dans [https://www.nature.com/articles/s41587-022-01485-x ''Nature''] que la réponse du milieu de la recherche à la pandémie a remis en question certaines hypothèses sur les DPI, y compris le fait que de solides réglementations en matière de DPI stimulent l'innovation. Au fur et à mesure que la pandémie a mis en évidence des questions plus larges telles que le droit à la santé et le droit à la connaissance, la nécessité d'examiner les DPI et la science ouverte d'une manière holistique est devenue plus claire. Bien que ces problèmes aient été mis en avant par la pandémie, la réflexion sur les DPI et l'ouverture a changé parallèlement à la transition vers le libre accès. Willinsky note que dans le passé, les éditeurs avaient tendance à considérer le libre accès comme une menace pour leurs DPI, mais à mesure que le libre accès s'enracine, les éditeurs réfléchissent à la façon dont leurs DPI peuvent soutenir le libre accès à l'avenir. En effet, cet aperçu des récents rapports de politique sur les DPI et la science ouverte en Europe montre que, dans ce contexte politique, les droits de propriété intellectuelle sont de plus en plus compris comme étant au service de la science ouverte plutôt qu'en opposition à celle-ci. ==Ouvrages cités== *ALLEA (European Federation of Academies of Sciences and Humanities). 2022. «&#8239;Aligning Intellectual Property Rights with Open Science: An ALLEA Statement&#8239;». [https://allea.org/wp-content/uploads/2022/04/ALLEA-Statement-Aligning-IPR-with-Open-Science.pdf https://allea.org/wp-content/uploads/2022/04/ALLEA-Statement-Aligning-IPR-with-Open-Science.pdf]. *Angelopoulos, Christina. 2022. ''Study on EU Copyright and Related Rights and Access to and Reuse of Scientific Publications, Including Open Access: Exceptions and Limitations, Rights Retention Strategies and the Secondary Publication Right''. Office des publications de l’Union européenne. [https://data.europa.eu/doi/10.2777/891665 https://data.europa.eu/doi/10.2777/891665]. *Commission européenne, Direction générale pour Research and Innovation. 2022. ''Open Science and Intellectual Property Rights: How Can They Better Interact? State of the Art and Reflections: Executive Summary''. Office des publications de l’Union européenne. [https://data.europa.eu/doi/10.2777/347305 https://data.europa.eu/doi/10.2777/347305]. *EARTO (European Association of Research and Technology Organizations). 2020. «&#8239;Towards a Balanced Approach between IPRs and Open Science Policy&#8239;». [https://www.earto.eu/wp-content/uploads/EARTO-Paper-Towards-a-Balanced-Approach-Between-IPRs-and-Open-Science-Policy-Final.pdf https://www.earto.eu/wp-content/uploads/EARTO-Paper-Towards-a-Balanced-Approach-Between-IPRs-and-Open-Science-Policy-Final.pdf]. *UNESCO. 2021. «&#8239;Towards a UNESCO Recommendation on Open Science: Online Expert Meeting on Open Science and Intellectual Property Rights&#8239;». [https://en.unesco.org/sites/default/files/report_expert_meeting_ipr_os_23apr.pdf https://en.unesco.org/sites/default/files/report_expert_meeting_ipr_os_23apr.pdf]. *UNESCO. 2022. «&#8239;Expert Meeting on Open Science and Intellectual Property Rights&#8239;». [https://www.unesco.org/en/articles/expert-meeting-open-science-and-intellectual-property-rights https://www.unesco.org/en/articles/expert-meeting-open-science-and-intellectual-property-rights]. *Voinigescu, Eva. 2020. «&#8239;Le Neuro de Montréal : porteur de changement dans les sciences universitaires ?&#8239;» ''University Affairs/Affaires universitaires'', le 24 juin 2020. [https://www.affairesuniversitaires.ca/articles-de-fond/article/le-neuro-de-montreal-porteur-de-changement-dans-les-sciences-universitaires https://www.affairesuniversitaires.ca/articles-de-fond/article/le-neuro-de-montreal-porteur-de-changement-dans-les-sciences-universitaires]. *Willinsky, John. 2022. ''Copyright’s Broken Promise: How to Restore the Law’s Ability to Promote the Progress of Science''. MIT Press. [https://direct.mit.edu/books/book/5507/Copyright-s-Broken-PromiseHow-to-Restore-the-Law-s https://direct.mit.edu/books/book/5507/Copyright-s-Broken-PromiseHow-to-Restore-the-Law-s]. [[Catégorie:Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024 (livre)]] a8opipv8hxtut3lbi5qmpjw29z2mifr Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/La sécurité de la recherche et la science ouverte au Canada 0 82372 744023 742625 2025-06-02T23:10:56Z LodestarChariot2 120009 /* Ouvrages cités */ 744023 wikitext text/x-wiki ''Cette observation a été écrite par Caroline Winter (avec des remerciements à Aaron Mauro et John Simpson pour leurs commentaires et contributions), pour le Electronic Textual Cultures Laboratory et le partenariat Implementing New Knowledge Environments.'' La sécurité de la recherche, c'est-à-dire la capacité d’identifier les risques pour les processus et les produits de la recherche et de prendre des mesures pour les atténuer, est une préoccupation de longue date pour la communauté de la recherche et ses parties prenantes, y compris les individus et individues jusqu’aux gouvernements nationaux. Bien que l'ouverture et la collaboration soient essentielles pour faire avancer la recherche, une plus grande ouverture peut également entraîner de plus grands risques. Sécuriser les données et les connaissances numériques et d'autres extrants intangibles est particulièrement difficile. Cela a été mis en évidence pendant la pandémie de COVID-19, lorsque le pivot vers des environnements de travail virtuels et des niveaux sans précédent de collaboration mondiale et de partage de la recherche se sont accompagnés de menaces de sécurité accrues (voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Science Ouverte et COVID-19|Science ouverte et COVID-19]]&#8239;»). La sécurité de la recherche est une vaste question qui se rapporte à toutes les facettes de la recherche. Pour les chercheurs et chercheuses et les institutions individuelles, le vol de données et d'autres problèmes de sécurité peuvent entraver la recherche, menacer la propriété intellectuelle et affecter l'admissibilité au financement (voir «&#8239;[[Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Les droits de propriété intellectuelle et la science ouverte en Europe|Les droits de propriété intellectuelle et la science ouverte en Europe]]&#8239;»). La sécurité de la recherche est également une question de sécurité nationale puisque les données et les connaissances détournées peuvent être utilisées à des fins de renseignement national ou militaire néfastes. La sécurité est particulièrement préoccupante pour la recherche économiquement précieuse et à double usage – celle qui a des applications civiles et militaires potentielles – comme dans les domaines des infrastructures essentielles et de la recherche sur des sujets humains ainsi que de l'informatique quantique et de l'intelligence artificielle, qui sont tous deux des outils potentiels pour les cyberattaques ainsi que les domaines cibles actuels (Gouvernement du Canada 2023; OCDE 2022 ; Owens 2023a ; Science Canada 2021). Le vol de données de recherche et/ou personnelles est une menace courante, car les données stockées sur les disques durs et les clés USB peuvent être volées ou égarées et les cyberattaques peuvent causer des violations de données et endommager les systèmes informatiques. Les attaques d'hameçonnage ont tendance à cibler des chercheurs et chercheuses individuels pour qui la sécurité n'est peut-être pas une priorité (OCDE 2022). La sécurité de la recherche est également menacée par les «&#8239;acteurs malfaisants&#8239;», qui peuvent être des collaborateurs, des chercheurs invités, des étudiants ou d'autres personnes qui visent à détourner ou à altérer la recherche pour leur propre profit (p. ex., dans le cas de concurrents commerciaux) ou pour le bénéfice d'autres personnes (p. ex. des états hostiles, des groupes du crime organisé, des organisations terroristes). Ces acteurs malfaisants peuvent agir par choix ou être forcés ou contraints (Science Canada 2021). Étant donné que la sécurité de la recherche est une question de plus en plus urgente, l'élaboration de politiques dans ce domaine est très active. Le document politique de l'Organisation de coopération et de développement économiques (OCDE) [https://doi.org/10.1787/39ee9438-fr ''Intégrité et sécurité dans l'écosystème mondial de la recherche''], publié en juin 2022, traite d'un certain nombre de politiques et d'initiatives de sécurité de la recherche de l'Australie, du Japon, des Pays-Bas, du Royaume-Uni et des États-Unis, élaborées par des gouvernements nationaux, des organismes de financement, des établissements de recherche publics, des associations universitaires, des universités, des projets de recherche internationaux, et des organisations politiques internationales (p. ex., le G7, la Commission européenne, le Global Research Council). Bon nombre de ces politiques traitent de l'établissement d'évaluations des risques dans les processus existants (p. ex. l'évaluation des demandes de financement), de la détermination et de la gestion des menaces et des conflits d'intérêts, ainsi que des lignes directrices sur la diligence raisonnable. Le document politique de l'OCDE reconnaît que le sujet de la sécurité de la recherche peut être difficile à discuter, controversé et polarisant, mais souligne qu'il est essentiel de le considérer néanmoins. Il offre sept recommandations de haut niveau pour la communauté de la recherche : # Souligner l'importance de la liberté de la recherche scientifique et de la collaboration internationale en tant qu'élément clé de l'écosystème mondial de la recherche # Intégrer les considérations relatives à la sécurité de la recherche dans les cadres nationaux et institutionnels pour l'intégrité de la recherche # Promouvoir une approche proportionnée et systématique de la gestion des risques dans la recherche # Promouvoir l'ouverture et la transparence en matière de conflits d'intérêts ou d'engagement # Mettre au point des directives claires, rationaliser les procédures et limiter la bureaucratie inutile # Mobiliser l'ensemble des secteurs et des institutions pour élaborer des politiques plus intégrées et efficaces # Améliorer le partage d’informations sur l'intégrité et la sécurité de la recherche à l’échelle internationale (10) Le Canada a également élaboré des politiques sur la sécurité de la recherche. En décembre 2019, le U15 Regroupement des universités de recherche du Canada et Universités Canada ont publié [https://www.univcan.ca/wp-content/uploads/2020/08/attenuer-les-risques-economiques-et-geopolitiques-associes-aux-projets-de-recherche-sensibles-dec-2019.pdf ''Atténuer les risques économiques et géopolitiques associés aux projets de recherche sensibles : Guide à l'intention des chercheurs universitaires'']. Le guide traite de divers types de risques en plus de l'appropriation illicite de données. Par exemple, il souligne que, comme tous les chercheurs ne jouissent pas du même degré de liberté académique, la publication de certains résultats pourrait mettre en danger les partenaires internationaux et que les risques pour les droits humains doivent être évalués dans le cadre des plans de voyage des chercheurs (10). Le gouvernement du Canada a également publié un groupe d'énoncés de politique connexes sur la sécurité de la recherche : [https://www.canada.ca/fr/service-renseignement-securite/nouvelles/2020/05/declaration-du-cse-et-scrs-le-14-mai-2020.html '''Déclaration du CSE et SCRS, le 14 mai 2020 ''']: Cette déclaration du Centre de la sécurité des télécommunications (CST) et du Service canadien du renseignement de sécurité (SCRS) répond aux préoccupations accrues au sujet de la recherche et de la sécurité nationale liées à l'incertitude générée par la COVID-19. Il met en garde contre les menaces à la propriété intellectuelle ainsi qu'aux renseignements personnels, citant une [https://www.cyber.gc.ca/fr/alertes-avis/cybermenaces-pesant-sur-les-organismes-de-sante-canadiens alerte du Centre canadien pour la cybersécurité] et une [https://www.canada.ca/fr/affaires-mondiales/nouvelles/2020/04/declaration-sur-les-cybermenaces-visant-le-secteur-de-la-sante.html déclaration d'Affaires mondiales Canada] sur l'augmentation des cybermenaces pour le secteur de la santé. [https://www.canada.ca/fr/innovation-sciences-developpement-economique/nouvelles/2020/09/enonce-de-politique-sur-la-securite-de-la-recherche-et-la-covid-19.html '''Énoncé de politique sur la sécurité de la recherche et la COVID-19, le 14 septembre 2020 ''']: Cet énoncé d'Innovation, Sciences et Développement économique Canada (ISDE) réaffirme l'engagement du gouvernement du Canada à l'égard de la science ouverte et rappelle à la communauté de la recherche de demeurer vigilant et d'examiner ses politiques et pratiques en matière de cybersécurité face aux menaces à la sécurité continues. [https://www.canada.ca/fr/innovation-sciences-developpement-economique/nouvelles/2021/03/enonce-de-politique-sur-la-securite-de-la-recherche--printemps2021.html '''Énoncé de politique sur la sécurité de la recherche – Printemps 2021, le 24 mars 2021 ''']: Cet énoncé d'ISDE fait état d'une augmentation des niveaux de menace pour la recherche et la sécurité nationale et rappelle à la communauté de la recherche l'énoncé de politique de septembre 2020. Il note également qu'il a demandé au Groupe de travail mixte du gouvernement du Canada et des universités d'élaborer des lignes directrices sur les risques pour guider les chercheurs dans l'examen des questions de sécurité nationale liées à leurs recherches. Ces [https://science.gc.ca/site/science/fr/protegez-votre-recherche/lignes-directrices-outils-pour-mise-oeuvre-securite-recherche/lignes-directrices-securite-nationale-pour-partenariats-recherche Lignes directrices sur la sécurité nationale pour les partenariats de recherche] ont été publiées en juillet 2021. [https://www.canada.ca/fr/innovation-sciences-developpement-economique/nouvelles/2023/02/declaration-des-ministres-champagne-duclos-et-mendicino-sur-la-protection-de-la-recherche-canadienne.html '''Déclaration des ministres Champagne, Duclos et Mendicino sur la protection de la recherche canadienne, le 14 février 2023 ''']: Cette déclaration d'ISDE des Ministères de l'Innovation, des Sciences et de l'Industrie ; Santé ; et la Sécurité publique note encore une fois un niveau accru de menaces et annonce un changement dans la politique de financement pour les trois organismes : «&#8239;Une demande de subvention de recherche dans un domaine sensible sera refusée si l'un des chercheurs travaillant sur le projet est affilié à une université, un institut de recherche ou un laboratoire rattaché à une organisation militaire ou à un organisme de défense nationale ou de sécurité d’un acteur étatique étranger qui représente un risque pour notre sécurité nationale&#8239;» (ISDE 2023). De plus, le [https://www.budget.canada.ca/2022/report-rapport/chap2-fr.html budget fédéral de 2022 du Canada ]a instauré un financement de 125 millions de dollars pour le [https://www.rsf-fsr.gc.ca/apply-demande/research_security-securite-recherche-fra.aspx Fonds de soutien à la recherche ]pour aider les établissements postsecondaires à renforcer leur capacité en matière de sécurité de la recherche, ainsi que 34,6 millions de dollars sur cinq ans et un financement permanent de 8,4 millions de dollars pour établir un centre de la sécurité de la recherche pour conseiller les établissements de recherche. Bien que la sécurité de la recherche soit une question complexe, les chercheurs peuvent prendre des mesures pour se protéger et protéger leur travail. Le portail [https://science.gc.ca/site/science/fr/protegez-votre-recherche Protégez votre recherche] du gouvernement du Canada comprend de l'information sur la sécurité de la recherche ainsi que des outils et des lignes directrices à l'intention des chercheurs et des établissements. Les outils [https://science.gc.ca/site/science/fr/protegez-votre-recherche/lignes-directrices-outils-pour-mise-oeuvre-securite-recherche/evaluez-votre-profil-risque Évaluez votre profil de risque] et [https://science.gc.ca/site/science/fr/protegez-votre-recherche/lignes-directrices-outils-pour-mise-oeuvre-securite-recherche/attenuez-risques-lies-securite-recherche Atténuez les risques liés à la sécurité de la recherche] fournissent des conseils pratiques précis pour aider les chercheurs à évaluer et à gérer les risques propres à leurs projets. Les ressources partagées par l'entremise de ce portail sont celles du [https://science.gc.ca/site/science/fr/protegez-votre-recherche/renseignements-generaux-securite-recherche/propos-gouvernement-canada-groupe-travail-universites Groupe de travail sur les universités], qui travaille à la science ouverte, collaborative et sécurisée au Canada. ==La sécurité de la recherche dans la presse== L'une des questions abordées dans la presse universitaire et populaire était un programme pilote élaboré en réponse à l'énoncé de politique de mars 2021 dans lequel les demandes de financement pour les [https://www.nserc-crsng.gc.ca/innovate-innover/alliance-alliance/index_fra.asp Subventions Alliance du CRSNG] ont été examinées par le SCRS et le CST. Des articles dans [https://www.affairesuniversitaires.ca/actualites/actualites-article/le-manque-de-clarte-lors-des-evaluations-de-risque-pour-la-securite-nationale-est-denonce/ ''Affaires universitaires''], [https://www.cbc.ca/news/politics/ottawa-reserach-champagne-security-1.6099163 ''CBC News''], le ''Globe and Mail ''([https://www.theglobeandmail.com/politics/article-ottawa-imposes-national-security-risk-assessments-for-university/ annonçant le projet pilote en 2021] et ses [https://www.theglobeandmail.com/canada/article-nserc-research-grants-sensitive/ résultats en 2023]) et [https://sciencebusiness.net/news/Cybersecurity/canadian-security-services-block-more-30-grant-proposals ''ScienceBusiness''] rapportent que, sur les quelque 1000 demandes de financement reçues par le CRSNG, 48 ont été signalées pcomme ayant besoin d’être examinéesur examen et 32 d'entre elles se sont vu refuser le financement pour des raisons de sécurité. À la suite de ce programme pilote, des examens de sécurité sont prévus pour toutes les demandes de financement des trois organismes. Cependant, certains chercheurs ont critiqué le programme pour son manque de transparence et de clarté (Owens 2023b). L'examen préalable ne peut pas mettre fin aux projets potentiellement risqués, puisque les projets qui se voient refuser du financement du CRSNG peuvent obtenir un financement équivalent auprès de leurs partenaires internationaux, et les projets qui ne cherchent pas à obtenir le financement fédéral ne seront pas examinés (Fife et Chase 2021). En mai 2023, le [https://www.thestar.com/news/canada/canada-set-to-name-foreign-labs-universities-that-pose-risk-to-national-security/article_4344a58d-f9f0-5e93-8604-82529aaff253.html ''Toronto Star''] a rapporté que l'ISDE était en train d'élaborer une politique énumérant des domaines de recherche et des établissements de préoccupation spécifiques pour relever certains de ces défis. Une autre question abordée dans la presse est la menace spécifique à la sécurité de la recherche de la part de l'État chinois. Écrivant au sujet du programme pilote de dépistage, Brian Owens note que «&#8239;[b]ien qu’on n’y nomme aucune organisation ni aucun pays explicitement&#8239;» dans la Déclaration sur la protection de la recherche canadienne de février 2023, «&#8239;il est généralement admis que les laboratoires et les entreprises chinoises présentent un risque particulier en raison de leurs liens étroits et souvent nébuleux avec les forces armées ainsi que des allégations d’usage abusif des droits de propriété intellectuelle&#8239;» (Owens 2023b). La Chine a été largement discutée comme une menace pour la sécurité de la recherche dans la presse internationale, y compris des articles dans [https://globalnews.ca/news/9488207/canada-china-research-crackdown/ ''Global News''], [https://www.science.org/content/article/canada-moves-ban-funding-risky-foreign-collaborations ''Science''] et [https://www.timeshighereducation.com/news/canadian-scientists-questioned-agents-over-china-links ''Times Higher Education'']. Bien que la plupart des politiques (y compris la politique s’inclus le d’OCDE) aient adopté une approche agnostique par pays, des préoccupations ont été soulevées – comme dans des articles pour l'[https://www.theatlantic.com/ideas/archive/2021/12/china-initiative-intellectual-property-theft/621058/ ''Atlantic'']'', ''la [https://www.chronicle.com/newsletter/latitudes/2023-04-12 ''Chronicle of Higher Education''], [https://policyoptions.irpp.org/magazines/july-2023/canadian-research-china-collaboration/ ''Policy Options''] et [https://www.youtube.com/watch?v=IxobEDHW-Zs ''ScienceBusiness''], et [https://www.affairesuniversitaires.ca/articles-de-fond/article/la-securite-nationale-et-la-recherche-font-ils-bon-menage/ ''Affaires universitaires'']'' – ''au sujet de l'accent implicite mis sur les menaces de la Chine. [https://www.caut.ca/bulletin/2023/05/executive-directors-corner-academic-freedom-and-national-security David Robinson] décrit ces risques dans un article pour le bulletin de l'Association canadienne des professeurs d'université (ACPPU) : <blockquote> La recherche universitaire peut présenter des risques légitimes pour la sécurité nationale, mais nous devons, en tant que communauté, nous garder de tout excès. Nous devons veiller à ce que les universitaires ne soient pas ciblés en raison de leur origine ethnique et à ce que les règles ne soient pas si larges qu’elles restreignent la recherche et l'érudition légitimes. La loi sur l'influence étrangère ne doit pas non plus être utilisée à mauvais escient pour cibler les universitaires qui critiquent la politique militaire ou étrangère du Canada. (Robinson 2023) </blockquote> Comme le fait remarquer Robinson, l'accent mis sur les menaces de la Chine a conduit à un climat de peur de collaborer avec des chercheurs et chercheuses chinois qui entrave la recherche et les relations de collaboration et met les chercheurs et chercheuses individuels en danger. ==Réponses de la communauté INKE== Les recherches d'Aaron Mauro, membre du partenariat INKE, se concentrent actuellement sur la cybersécurité de la recherche. Son livre de 2022 [https://www.bloomsbury.com/us/hacking-in-the-humanities-9781350231009/ ''Hacking in the Humanities : Cybersecurity, Speculative Fiction, and Navigating a Digital Future'' (2022) ]'' ''traite d'une approche de recherche qui prioritise la sécurité. Son [https://www.fu-berlin.de/en/sites/dhc/programme/termine/_Termin-Archiv_EN/DHCLs/2022-06-07_DHCL-Mauro.html discours du même nom] au Dahlem Humanities Center en 2022 soutient que les projets d’humanités numériques doivent adopter les meilleures pratiques de sécurité dans la façon dont nous planifions, menons et communiquons la recherche et que les humanistes numériques sont bien placés pour poser les questions critiques nécessaires. Mauro a donné une conférence au Digital Humanities Summer Institute (DHSI) 2021intitulée [https://web.archive.org/web/20210227025734/https:/dhsi.org/dhsi-2021-online-edition-institute-lectures/ «&#8239;Human Exploits : Cybersecurity and the Humanities&#8239;»,] et enseigne un cours DHSI sur [https://dhsi.org/on-campus-courses2024/ la cybersécurité pour les humanistes]. Parmi d'autres écrits liés à la cybersécurité, Mauro a écrit plusieurs articles pour ''The Conversation. ''Dans [https://theconversation.com/working-from-home-during-the-coronavirus-pandemic-creates-new-cybersecurity-threats-134954 «&#8239;Working from Home during the Coronovirus Pandemic Creates New Cybersecurity Threats&#8239;»,] il décrit comment les menaces telles que l’hameçonnage et le ransomware sont devenues de plus en plus courantes pendant la pandémie et le besoin d'une infrastructure plus sécurisée et de meilleures habitudes de sécurité par les utilisateurs. Dans [https://theconversation.com/ukrainian-cultural-artifacts-are-at-risk-during-the-russian-invasion-but-digitizing-them-may-offer-some-protection-185673 «&#8239;Ukrainian Cultural Artifacts are at Risk during the Russian Invasion, but Digitizing Them my Offer Some Protection&#8239;»,] il décrit comment les cyberattaques et la rhétorique russes menacent le patrimoine culturel ukrainien ainsi que sa sécurité nationale. Bien que la numérisation puisse créer des sauvegardes de documents du patrimoine culturel, note-t-il, elle dépend des infrastructures qui sont également menacées (pour plus sur la numérisation des documents du patrimoine culturel, voir «&#8239;[[Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/La Stratégie canadienne de numérisation du patrimoine documentaire|La Stratégie canadienne de numérisation du patrimoine documentaire]]&#8239;»). ==La sécurité de la recherche et la communauté universitaire élargie== De nombreuses initiatives dans l'ensemble de la communauté universitaire canadien portent sur des questions de sécurité de la recherche. À l'échelle nationale, par exemple, l'Alliance de recherche numérique du Canada (l'Alliance) a lancé en décembre 2022 [https://alliancecan.ca/fr/nouveautes/nouvelles/les-politiques-et-normes-de-cybersecurite-sont-maintenant-disponibles un ensemble de normes et de politiques de cybersécurité] liées à l'infrastructure nationale, abordant [https://alliancecan.ca/fr/document/741 la classification des données], la [https://alliancecan.ca/fr/document/739 gestion des données], [https://alliancecan.ca/fr/document/737 la gestion des vulnérabilités] et [https://alliancecan.ca/fr/document/733 la gestion des risques liés à la cybersécurité]. L'Alliance souligne également [https://alliancecan.ca/fr/nouveautes/nouvelles/mois-de-la-sensibilisation-la-cybersecurite le Mois de la sensibilisation à la cybersécurité 2023] avec une série d'ateliers en ligne tenus tout au long du mois d'octobre, chacun portant sur une question liée à la sécurité de la recherche numérique. Toujours à l'échelle nationale, le [https://canssoc.ca/fr/ Canadian Shared Security Operations Centre (CanSSOC)], une collaboration entre [https://www.canarie.ca/fr/ CANARIE] et [https://www.canarie.ca/nren/ le Réseau national de la recherche et de l'éducation (RNRE), ]coordonne les services de cybersécurité locaux, régionaux et nationaux partout au Canada. Les institutions et les organisations prennent également des mesures. Par exemple, en septembre 2021, le U15 a publié une [https://u15.ca/fr/publications/statements-releases/declaration-du-u15-sur-la-protection-des-valeurs-canadiennes-et-de-la-recherche-canadienne/ Déclaration du U15 sur la protection des valeurs canadiennes et de la recherche canadienne] qui souligne la nécessité que les politiques de sécurité soient claires, transparentes et prises en compte, reconnaissant que <blockquote> la liberté académique et l'autonomie institutionnelle font partie des principes fondamentaux qui font que nos institutions sont à l'abri de toute ingérence politique, peuvent parler en toute franchise aux autorités et sont en mesure de répondre aux besoins sociaux, culturels et économiques des Canadiens. (Regroupement 2021) </blockquote> En février 2023, l'Université de Waterloo a organisé une [https://uwaterloo.ca/research/research-security-conference conférence sur la sécurité de la recherche] afin de sensibiliser les gens à des questions clés et d'encourager la discussion, y compris sur le potentiel de discrimination raciale en raison des mesures de sécurité. Il a également abordé l'évolution du rôle des bureaux des services de recherche, car de nombreux établissements ont maintenant des divisions, des bureaux et / ou du financement dédié à la sécurité de la recherche. Et, bien qu'il n’est pas spécifiquement une politique de sécurité de la recherche, [https://fnigc.ca/fr/les-principes-de-pcap-des-premieres-nations/ Les principes de PCAP® des Premières Nations] du Centre de gouvernance de l'information des Premières Nations traitent de la propriété, du contrôle, de l'accès et de la possession, qui ont tous trait à l'intégrité et à la sécurité des données. ==Sécurité de la recherche et la science ouverte== Un défi clé pour la science ouverte et sécurisée est que l'ouverture, la collaboration et le partage qui sont à la base des mouvements ouverts sont précisément ce que les acteurs malfaisants exploitent pour saper la sécurité de la recherche. Similairement, les infrastructures numériques et les technologies de communication en ligne qui rendent possible la science ouverte sont également particulièrement vulnérables aux attaques. Un défi de sécurité connexe qui est aussi particulièrement pertinent pour la science ouverte est que plus les informations sont partagées ouvertement, plus le risque qu'elles soient utilisées à des fins néfastes est grand, comme [https://www.wired.co.uk/article/making-science-more-open-is-good-for-research-but-bad-for-security Grace Browne] s’explique dans un article pour ''Wired''. La recherche sur la COVID-19 pourrait être utilisée pour développer des bioarmes, par exemple, et le code d'intelligence générale artificielle génératif pourrait être utilisé pour diffuser de la désinformation. L'essor des serveurs de préimpression ouverts, en particulier pour la recherche à double usage, est particulièrement préoccupante parce que cette recherche n'est pas encore évaluée par les pairs et peut contenir des erreurs ou poser des risques potentiels pour la sécurité qui n'ont pas été identifiés. Notant que l'ouverture amplifie le risque déjà existant que la recherche soit utilisée de manière non intentionnelle et nuisible, Browne soutient qu'il est temps que la science ouverte réponde à ses risques, avant que le pire ne se réalise (Browne 2022). En plus des efforts canadiens décrits ci-dessus, des efforts sont en cours dans le monde entier pour développer une culture de recherche axée sur la sécurité, souvent liée à des questions qui recoupent la science ouverte. Par exemple, les [https://www.nature.com/articles/s41597-020-0486-7 TRUST Principles for Digital Repositories] (transparence, responsabilité, accent mis sur l'utilisateur, durabilité, technologie), qui reconnaissent que les infrastructures numériques que les chercheurs utilisent pour déposer et sourcer des données doivent être sécurisées et fiables (voir «&#8239;[[Observations fondamentales : Observatoire des politiques sur les savoirs ouverts, 2017-2020/Les principes TRUST pour les dépôts numériques|Les principes TRUST pour les dépôts numériques]]&#8239;»). Dans leur [https://www.carl-abrc.ca/fr/nouvelles/principes-trust-pour-les-depots-numeriques/ approbation conjointe des principes], l'Association des bibliothèques de recherche du Canada (ABRC) et Portage (2020) ont noté que la technologie comprend «&#8239;la capacité d’identifier immédiatement des menaces de sécurité et d'y répondre de manière efficace&#8239;». Educause a un [https://www.educause.edu/cybersecurity-and-privacy-guide guide de sécurité et de confidentialité] contenant des informations et des ressources pour soutenir l'élaboration de politiques et les programmes d'éducation pour la communauté de l'enseignement supérieur. En janvier 2022, la Commission européenne a publié [https://op.europa.eu/en/publication-detail/-/publication/3faf52e8-79a2-11ec-9136-01aa75ed71a1 ''Tackling R&I Foreign Interference''], un document de travail contenant des lignes directrices spécifiques pour les organismes de recherche afin d'atténuer les risques de sécurité tout en faisant progresser la science ouverte. Ce ne sont là que quelques exemples d'initiatives en cours dans le monde pour s'attaquer à la question complexe de la sécurité de la recherche. Ils reflètent le consensus parmi les intervenants en matière de sécurité de la recherche selon lequel l'ouverture doit être équilibrée avec la sécurité tout en respectant les libertés académiques : une reconnaissance des avantages de travailler ouvertement et en collaboration au-delà des frontières nationales et des risques légitimes pour la sécurité encourus. ==Ouvrages cités== *ABRC (Association des bibliothèques de recherche du Canada). 2020. «&#8239;L'ABRC et Portage adhérent aux principes TRUST pour les dépôts numériques&#8239;». Le 31 juillet 2020. [https://www.carl-abrc.ca/news/trust-principles-for-digital-repositories/ https://www.carl-abrc.ca/news/trust-principles-for-digital-repositories/]. *Browne, Grace. 2022. «&#8239;Making Science More Open is Good for Research––But Bad for Security&#8239;». ''Wired'', le 22 avril 2022. [https://www.wired.com/story/making-science-more-open-good-research-bad-security/ https://www.wired.com/story/making-science-more-open-good-research-bad-security/]. *Fife, Robert, et Steven Chase. 2021. «&#8239;Ottawa Imposes National-Security Risk Assessments for University Researchers Seeking Federal Funds&#8239;». ''The Globe and Mail'', le 12 juillet 2021. [https://www.theglobeandmail.com/politics/article-ottawa-imposes-national-security-risk-assessments-for-university/ https://www.theglobeandmail.com/politics/article-ottawa-imposes-national-security-risk-assessments-for-university/]. *Gouvernement du Canada. 2021. «&#8239;Qui constitue une menace?&#8239;» Le 11 juillet 2021. [https://science.gc.ca/site/science/fr/protegez-votre-recherche/renseignements-generaux-securite-recherche/qui-constitue-menace https://science.gc.ca/site/science/fr/protegez-votre-recherche/renseignements-generaux-securite-recherche/qui-constitue-menace]. *Gouvernement du Canada. 2023. «&#8239;Pourquoi devriez-vous protéger votre recherche?&#8239;» Le 31 mars 2023. [https://science.gc.ca/site/science/fr/protegez-votre-recherche/renseignements-generaux-securite-recherche/pourquoi-devriez-vous-proteger-votre-recherche https://science.gc.ca/site/science/fr/protegez-votre-recherche/renseignements-generaux-securite-recherche/pourquoi-devriez-vous-proteger-votre-recherche]. *ISDE (Innovation, Sciences et Développement Économique Canada). 2023. «&#8239;Déclaration des ministres Champagne, Duclos et Mendicino sur la protection de la recherche canadienne&#8239;». Gouvernement du Canada. February 14, 2023. [https://www.canada.ca/fr/innovation-sciences-developpement-economique/nouvelles/2023/02/declaration-des-ministres-champagne-duclos-et-mendicino-sur-la-protection-de-la-recherche-canadienne.html https://www.canada.ca/fr/innovation-sciences-developpement-economique/nouvelles/2023/02/declaration-des-ministres-champagne-duclos-et-mendicino-sur-la-protection-de-la-recherche-canadienne.html]. *Mauro, Aaron. 2022. «&#8239;Hacking in the Humanities : Cybersecurity, Speculative Fiction, and Navigating a Digital Future&#8239;». Dahlem Humanities Center (DHC). Le 7 juin 2022. [https://www.fu-berlin.de/en/sites/dhc/videothek/Videothek/908-DHCL-Mauro/index.html https://www.fu-berlin.de/en/sites/dhc/videothek/Videothek/908-DHCL-Mauro/index.html]. *OCDE (Organisation de coopération et de développement économiques). 2022. «&#8239;Intégrité et sécurité dans l'écosystème mondial de la recherche&#8239;». OECD Science, Technology and Industry Policy Papers, no. 130. [https://doi.org/10.1787/39ee9438-fr https://doi.org/10.1787/39ee9438-fr]. *Owens, Brian. 2023a. «&#8239;La sécurité nationale et la recherche font-ils bon ménage ?&#8239;». ''Affaires universitaires'', le 14 juin 2023. [https://www.affairesuniversitaires.ca/articles-de-fond/article/la-securite-nationale-et-la-recherche-font-ils-bon-menage/ https://www.affairesuniversitaires.ca/articles-de-fond/article/la-securite-nationale-et-la-recherche-font-ils-bon-menage/]. *Owens, Brian. 2023b. «&#8239;Le manque de clarté lors des évaluations de risque pour la sécurité nationale est dénoncé&#8239;». ''Affaires universitaires'', le 23 mars 2023. [https://www.affairesuniversitaires.ca/actualites/actualites-article/le-manque-de-clarte-lors-des-evaluations-de-risque-pour-la-securite-nationale-est-denonce/ https://www.affairesuniversitaires.ca/actualites/actualites-article/le-manque-de-clarte-lors-des-evaluations-de-risque-pour-la-securite-nationale-est-denonce/]. *Robinson, David. 2023. «&#8239;Liberté académique et sécurité nationale&#8239;». ''Bulletin de l'ACPPU'', le juin 2023. [https://www.caut.ca/fr/bulletin/2023/05/le-coin-du-directeur-general-liberte-academique-et-securite-nationale https://www.caut.ca/fr/bulletin/2023/05/le-coin-du-directeur-general-liberte-academique-et-securite-nationale]. *Regroupement des universités de recherche canadiennes U15. 2021. «&#8239;Déclaration du U15 sur la protection des valeurs canadiennes et de la recherche canadienne&#8239;». Groupe U15 des universités de recherche canadiennes. Le 28 septembre 2021. [https://u15.ca/fr/publications/statements-releases/declaration-du-u15-sur-la-protection-des-valeurs-canadiennes-et-de-la-recherche-canadienne/ https://u15.ca/fr/publications/statements-releases/declaration-du-u15-sur-la-protection-des-valeurs-canadiennes-et-de-la-recherche-canadienne/]. *Regroupement des universités de recherche canadiennes et universités du Canada U15. 2019. «&#8239;Atténuer les risques économiques et géopolitiques associés aux projets de recherche sensibles : guide à l’intention des chercheurs universitaires&#8239;». [https://www.univcan.ca/wp-content/uploads/2020/08/attenuer-les-risques-economiques-et-geopolitiques-associes-aux-projets-de-recherche-sensibles-dec-2019.pdf https://www.univcan.ca/wp-content/uploads/2020/08/attenuer-les-risques-economiques-et-geopolitiques-associes-aux-projets-de-recherche-sensibles-dec-2019.pdf]. *Science Canada. 2021. «&#8239;CSIS Research Security Briefing&#8239;». Le 9 juillet 2021. [https://www.youtube.com/watch?v=LSu5ObwzM8c https://www.youtube.com/watch?v=LSu5ObwzM8c]. [[Catégorie:Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024 (livre)]] oytrvidhwbhjrqppvpxn1qaapq7ignq Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/La communauté avant la commercialisation 0 82375 744024 742756 2025-06-02T23:19:12Z LodestarChariot2 120009 /* Références */ 744024 wikitext text/x-wiki ''Ce rapport «&#8239;Insights and Signals&#8239;» a été rédigé par Brittany Amell (avec nos remerciements à Claire Duncan et Jessica Dallaire-Clark pour leurs commentaires et contributions), pour le Electronic Textual Cultures Laboratory et le partenariat Implementing New Knowledge Environments.'' Ce rapport sur les perspectives et les signaux se concentre sur le thème de la Semaine internationale du libre accès de cette année, qui se déroule du 21 octobre au 27 octobre. Organisée chaque année depuis 2008, la semaine du libre accès est une célébration mondiale et une promotion de l'accès gratuit, immédiat et en ligne à la recherche et à l'érudition. Des individus, des groupes et des organisations se connectent à travers les disciplines, les fuseaux horaires, les continents et les secteurs pour faire progresser la compréhension et le plaidoyer en faveur de l'érudition ouverte. [https://www.openaccessweek.org/theme/fr Le comité consultatif de la Semaine du libre accès,] en partenariat avec [https://sparcopen.org SPARC], a décidé de reprendre le thème de 2023, ''la communauté avant la commercialisation''. C'est la première fois qu'un thème est réutilisé depuis le début de la Semaine du libre accès, une décision que le comité consultatif de la Semaine du libre accès 2024 décrit comme une étape sans précédent mais nécessaire, étant donné l'importance de ce sujet et le besoin urgent de transformer la conversation collective en «&#8239;action collective&#8239;» ([https://www.openaccessweek.org/theme/fr Semaine internationale du libre accès 2024).] Ce rapport aborde le thème de la Semaine de l'accès à l'information 2024, ainsi que quelques événements notables prévus pendant la Semaine de l'accès à l'information. Ce rapport comprend également un tour d'horizon exhaustif de certains développements en matière d'accès à l'information dans le monde. Les développements mentionnés sont les suivants : * Annonces de la [https://www.gatesfoundation.org/about/policies-and-resources/open-access-policy Fondation Bill et Melinda Gates], du [https://blog.mdpi.com/2024/02/27/open-access-in-japan/ Japon], du [https://science.gc.ca/site/science/fr/financement-interorganismes-recherche/politiques-lignes-directrices/libre-acces/rapport-nous-avons-entendu-activites-mobilisation-revision-politique-trois-organismes-libre-acces Canada] (en français), de la [https://www.swissuniversities.ch/en/topics/open-science/open-access/national-strategy Suisse] et du [https://www.ukri.org/news/ukri-updates-guidance-for-open-access-policy/ Royaume-Uni] concernant la révision de leurs politiques ou stratégies respectives en matière de libre accès. * [https://barcelona-declaration.org/downloads/barcelonadeclaration_fran%25c3%25a7ais.pdf Déclaration de Barcelone sur l'information de recherche ouverte (en français)] * Engagements financiers importants pour le développement d'infrastructures de recherche en libre accès de la part du [https://www.nature.com/articles/d41586-024-01493-8 Japon] et du [https://frq.gouv.qc.ca/dix-millions-de-dollars-accordes-a-la-creation-du-reseau-quebecois-de-recherche-et-de-mutualisation-pour-les-revues-scientifiques/ Québec] (en français) * Le [https://blog.doaj.org/2024/06/14/press-release-pubscholar-joins-the-movement-to-support-the-directory-of-open-access-journals/ partenariat récemment annoncé] (en anglais) entre PubScholar (une plateforme académique publique créée par l'Académie chinoise des sciences) et l'annuaire des revues en libre accès (Directory of Open Access Journals) * [https://apropos.erudit.org/partenariat/ 10 ans de soutien à la publication équitable en libre accès au] Canada par le biais du ''Partenariat pour le libre accès'', une initiative menée par les partenaires INKE [https://www.crkn-rcdr.ca/fr/propos-du-rcdr Réseau canadien de documentation pour la recherche ] et Érudit[https://apropos.erudit.org/?lang=en . ] * Deux rapports publiés en anglais par [https://investinopen.org/blog/announcing-the-2024-survey-of-recent-open-science-policy-developments/ Invest in Open Infrastructure], l'un sur l[https://zenodo.org/records/11499591?ref=investinopen.org 'évolution de la politique en matière de science ouverte] en Afrique, en Europe, en Amérique latine et aux États-Unis, et l'autre sur l'[https://zenodo.org/records/10934089 état de l'infrastructure ouverte en 2024.] * Un autre rapport en anglais, publié par le Centre for Global Development (CGD), sur les [https://www.cgdev.org/blog/g20-open-access-policies-opportunity-harmonisation positions politiques des membres du G20 en matière de libre accès.] ==La communauté avant la commercialisation== Le thème de la Semaine du libre accès 2024 réitère son appel à placer «&#8239;la communauté avant la commercialisation&#8239;». À fait opportun, alors que l'on apprend que les éditeurs d'ouvrages savants à but lucratif ont vu leurs bénéfices augmenter pour 2023 - prenez, par exemple, la société mère d'Elsevier, RELX, qui a annoncé une augmentation de 10 % de ses bénéfices pour 2023 (ce qui équivaut approximativement à 3 189 967 950,00 dollars canadiens). Elsevier représente 33,7 % des revenus de RELX et 40,5 % de ses bénéfices, écrit Craig Nicholson dans [https://www.researchprofessionalnews.com/rr-news-europe-infrastructure-2024-2-elsevier-parent-reports-10-hike-in-profits-for-2023/ cet article pour Research Professional News]). Ce thème est également lié aux préoccupations actuelles dans le monde concernant comme «&#8239;la ruée vers l’intégration de l’intelligence artificielle dans les systèmes universitaires commerciaux sans consulter la communauté&#8239;» ([https://www.openaccessweek.org/theme/fr Semaine internationale du libre accès 2024]). Le thème «&#8239;la communauté avant la commercialisation&#8239;» est sous-tendu par des questions sur les conséquences de la prise de contrôle croissante des conditions de production et de diffusion des connaissances par des organisations à but lucratif, ainsi que par d'autres questions qui incluent les implications que les modèles commerciaux pourraient avoir pour exacerber les inégalités ou saper la liberté académique ([https://www.openaccessweek.org/theme/fr Semaine internationale du libre accès 2024]). Ce thème et les questions qu'il soulève sont également en phase avec les quatre recommandations de haut niveau publiées par le comité de pilotage de Budapest sur le libre accès à l'occasion du [https://www.budapestopenaccessinitiative.org/boai20/boai20-french-translation/ 20e anniversaire de l'initiative de Budapest sur le libre accès]. À titre de référence, ces recommandations sont les suivantes e * Accueillir la recherche ouverte sur l'infrastructure ouverte * Réformer les pratiques et les politiques d'évaluation de la recherche (et éliminer les mesures dissuasives de l'EA) * Donner la priorité à des canaux d'édition et de distribution inclusifs et cesser d'exclure les auteurs pour des raisons économiques. * Éviter de concentrer la nouvelle littérature OA dans des revues commerciales (à but lucratif) et favoriser les modèles OA qui profitent à toutes les régions du monde. ([https://www.budapestopenaccessinitiative.org/boai20/boai20-french-translation/ Groupe de pilotage BOAI20 2022]) Plusieurs [https://www.openaccessweek.org/events événements] (en anglais) sont prévus dans le monde entier. En voici quelques exemples : * 20 octobre 2024 : Danny Kingsley (Deakin) sur la communauté et la commercialisation (la version anglaise est [https://www.openaccessweek.org/events/2024/keynote-address-community-over-commercialisation ici)]. * 21 octobre 2024 : Table ronde sur le libre accès aux diamants (la version anglaise est [https://www.openaccessweek.org/events/2024/panel-discussion-diamond-open-access-sustainable-concept-or-utopian ici]) * 21 octobre 2024 : Table ronde sur la communauté et la commercialisation (la version anglaise est [https://www.openaccessweek.org/events/2024/panel-discussion-community-over-commercialisation ici]) * 24 octobre 2024 : Conférence, donnée par David Gaertner (Institute for Critical Indigenous Studies, UBC), intitulée «&#8239;'Stop Generating' : Generative AI in the Contexts of Indigenous Studies,&#8239;» organisée par The University of British Columbia Vancouver and Okanagan Libraries (la version anglaise est [https://www.openaccessweek.org/events/2024/stop-generating-generative-ai-in-the-contexts-of-indigenous-studies ici]). * 23 octobre 2024 : Conférence donnée par le Dr. Monica Granados, intitulée «&#8239;Handing you the keys to open access,&#8239;» organisée par les bibliothèques de l'Université métropolitaine de Toronto ([https://www.openaccessweek.org/events/2024/open-access-week-2024-handing-you-the-keys-to-open-access la version anglaise est ici]). Une liste complète des [https://www.openaccessweek.org/events événements est disponible sur le site de la Semaine du libre accès.] ==Un tour d'horizon non exhaustif des mises à jour de l'Open Access pour 2024== Bien que 2023 ait été déclarée [https://www.nature.com/articles/d41586-023-00019-y Année du libre accès par la NASA] (ainsi que par une coalition de plus de 85 universités américaines et 10 agences fédérales), 2024 a été une année chargée pour le libre accès. Cette section propose un tour d'horizon exhaustif des mises à jour, développements et autres nouvelles liées au libre accès dans le monde et au Canada, organisé par mois. '''Le mois de janvier '''débute avec la publication d'un article dans Scientometrics par Huang, Neylon et Montgomery (la version anglaise est [https://doi.org/10.1007/s11192-023-04894-0 ici]) qui montre que les publications en libre accès, en particulier celles qui sont mises à disposition en dehors de l'éditeur (par exemple, via un dépôt institutionnel), sont citées par un plus grand nombre de personnes à travers le monde. En '''février''', le Japon a annoncé des changements dans sa politique de libre accès. À partir d'avril 2025, les chercheurs bénéficiant d'un financement public seront tenus de mettre leurs travaux en libre accès via des dépôts institutionnels ([https://blog.mdpi.com/2024/02/27/open-access-in-japan/ McKenna 2024]). En '''mars, '''[https://www.gatesfoundation.org/about/policies-and-resources/open-access-policy la Fondation Bill et Melinda Gates a annoncé l']adoption d'une politique de libre accès comprenant un engagement à fournir une assistance pour le développement d'une infrastructure ouverte, l'obligation pour les bénéficiaires de subventions de publier des préimprimés et l'arrêt du soutien aux frais de traitement des articles. En '''mars '''également, [https://ec.europa.eu/commission/presscorner/detail/en/ip_24_1701 la République de Corée (Corée du Sud) a rejoint Horizon Europe], le principal programme de financement de l'UE, ce qui signifie que les chercheurs sud-coréens qui reçoivent des fonds du programme seront tenus de publier leurs recherches en OA (McKenna 2023). La Corée du Sud n'a pas encore de politique nationale officielle en matière d'OA ([https://www.cgdev.org/blog/g20-open-access-policies-opportunity-harmonisation Demeshko et Drake, 2024]). '''En avril, '''la [https://barcelona-declaration.org/downloads/barcelonadeclaration_fran%25C3%25A7ais.pdf Déclaration de Barcelone sur l'information de recherche ouverte] a été publiée à l'issue d'un vaste processus de collaboration auquel ont participé plus de 25 experts. La Déclaration énonce quatre engagements : * Faire de la transparence la règle par défaut pour les informations que nous utilisons et produisons dans le domaine de la recherche * Travailler avec des services et des systèmes qui soutiennent et permettent l'accès à l'information sur la recherche ouverte * Soutenir la durabilité des infrastructures d'information sur la recherche ouverte * Soutenir l'action collective pour accélérer la transition vers l'ouverture des informations sur la recherche Plus de 40 organisations ajoutent leur nom à la [https://barcelona-declaration.org/signatories/ liste des signataires] avant la fin du mois d'avril ([https://sparcopen.org/news/2024/barcelona-declaration-pushes-for-open-default-to-research-information/ SPARC 2024]). La liste continue de s'allonger, mais en dehors d'[https://apropos.erudit.org/barcelona-declaration/?lang=en Érudit] et de [https://pkp.sfu.ca/2024/06/04/pkp-barcelona-declaration/ PKP], il y a une absence notable d'universités canadiennes et d'autres organismes de recherche. En '''mai''', la Suisse [https://www.swissuniversities.ch/en/topics/open-science/open-access/national-strategy a publié sa stratégie nationale révisée en matière de libre accès]. Les mises à jour de la Stratégie comprennent le maintien des engagements visant à garantir que la publication dans le libre accès diamant est accessible aux auteurs. Ailleurs, le Royaume-Uni a annoncé des mises à jour de sa politique de libre accès, qui comprend désormais l'obligation de publier des monographies, des chapitres de livres et des collections éditées en plus des articles de recherche évalués par les pairs ([https://www.ukri.org/publications/ukri-open-access-policy/ UK Research and Innovation 2021 ; ][https://www.ukri.org/news/ukri-updates-guidance-for-open-access-policy/ UK Research and Innovation 2023]). Au Canada, le Fonds de recherche du Québec a annoncé la création du [https://frq.gouv.qc.ca/dix-millions-de-dollars-accordes-a-la-creation-du-reseau-quebecois-de-recherche-et-de-mutualisation-pour-les-revues-scientifiques/ Réseau québécois de recherche et de mutualisation pour les revues scientifiques], ainsi qu'un engagement financier important (10 millions de dollars canadiens sur cinq ans). L'un des principaux objectifs du Réseau sera «&#8239;soutenir la publication scientifique de langue française dans le système universitaire québécois&#8239;» en offrant, entre autres, «&#8239;un appui soutenu pour aider les revues scientifiques québécoises&#8239;» à établir un modèle d'édition en libre accès (Bilodeau 2024). En '''juin, '''le Japon a annoncé le déblocage d'un financement de 63 millions USD destiné au développement des infrastructures nécessaires pour soutenir sa stratégie de libre accès ([https://www.nature.com/articles/d41586-024-01493-8 Chawla 2024] ; [https://open-access.network/en/services/news/article/green-open-access-for-japan Open Access Network 2024]). Un partenariat entre PubScholar (une plateforme académique publique créée par l'Académie chinoise des sciences) et le Directory of Open Access Journals a également été annoncé en juin (lire la [https://blog.doaj.org/2024/06/14/press-release-pubscholar-joins-the-movement-to-support-the-directory-of-open-access-journals/ version anglaise ici]). Par ailleurs, Invest in Open Infrastructure a publié une [https://zenodo.org/records/11499591?ref=investinopen.org étude sur l'évolution des politiques en matière de science ouverte ]en Afrique, en Europe, en Amérique latine et aux États-Unis. Cette étude s'appuie sur un rapport publié plus tôt dans l'année sur [https://zenodo.org/records/10934089 l'état de l'infrastructure ouverte en 2024]. Les deux rapports offrent une vue d'ensemble des politiques ou stratégies de science ouverte récemment mises en œuvre ou à venir sur le continent africain (Sellanga et al. 2024, 5). En '''juillet''', l'UNESCO a [https://www.unesco.org/fr/articles/annonce-de-lalliance-mondiale-pour-lacces-ouvert-diamant annoncé et présenté l'Alliance Mondiale pour l’accès ouvert Diamant] (un enregistrement de l'annonce est disponible [https://www.youtube.com/watch?v=ZmNblPxt_nU ici]). En '''août''', les trois agences nationales de financement de la recherche au Canada ont [https://science.gc.ca/site/science/fr/financement-interorganismes-recherche/politiques-lignes-directrices/libre-acces/rapport-nous-avons-entendu-activites-mobilisation-revision-politique-trois-organismes-libre-acces publié un rapport résumant les résultats de leur enquête sur l'examen des politiques de libre accès]. Au total, 1 431 personnes ont répondu à l'enquête. Parmi les principales conclusions, on note un soutien notable des participants aux modèles d'accès libre peu ou pas coûteux (tels que l'accès libre diamant ou vert). Les obstacles à la publication en libre accès comprennent les frais de traitement des articles, ainsi que l'infrastructure limitée et les incitations pour les revues scientifiques à publier des manuscrits en libre accès. En '''septembre, '''l'UNESCO, la [https://www.nrf.ac.za/second-open-access-essay-competition-2024-africa-region-community-over-commercialisation-for-diamond-open-access/ NRF], SPARC, [https://www.redalyc.org/ Redalyc] et [https://amelica.org/index.php/en/home/ AmeliCA ][https://www.nrf.ac.za/second-open-access-essay-competition-2024-africa-region-community-over-commercialisation-for-diamond-open-access/ ont annoncé] un appel à candidatures pour ''la deuxième édition du concours d'essais en libre accès''. La première édition du concours, qui s'est tenue en Amérique latine en 2020, a reçu 68 manuscrits d'étudiants de premier et deuxième cycles situés dans 13 pays différents. Le thème du concours de cette année est «&#8239;''La communauté plutôt que la commercialisation pour le libre accès au diamant''&#8239;». Les lauréats bénéficieront d'un soutien pour assister au [https://doasummit.uct.ac.za/fr/ deuxième sommet Mondial sur l’accès ouvert Diamant, qui se tiendra au Cap]. Les essais gagnants seront publiés en 2025. En '''octobre''', [https://www.crkn-rcdr.ca/fr/propos-du-rcdr le Réseau canadien de documentation pour la recherche ](RCDR) et [https://apropos.erudit.org/ Érudit], partenaires de l'INKE, célèbrent [https://apropos.erudit.org/partenariat/ dix ans de soutien à l'édition équitable en libre accès] par l'intermédiaire du Partenariat pour le libre accès (POA). S'inscrivant dans le mouvement diamantaire du libre accès, le Partenariat soutient plus de 240 revues savantes non commerciales au Canada grâce aux contributions financières fournies conjointement par un nombre impressionnant de bibliothèques universitaires au Canada (54 pour être exact) et dans le monde (39 en France et en Belgique). Chaque année, on estime que le POA permet la publication de plus de 2000 articles en accès libre immédiat ([https://apropos.erudit.org/partenariat/ Érudit], n.d.). Claire Duncan, responsable de la stratégie et de l'engagement au RCDR, nous a fait part du commentaire suivant : «&#8239;Les dix années de ce partenariat sont une véritable expression des possibilités novatrices qu'offre la priorité donnée au libre accès dirigé par la communauté. Grâce au POA, nous favorisons l'accès à des contenus de recherche essentiels et nous nous faisons les champions de la bibliodiversité et de la durabilité dans l'écosystème de la recherche au Canada. Cette initiative communautaire engage les bibliothèques, les revues et les fournisseurs d'infrastructure dans une collaboration visant à mettre en place un système canadien de publication en libre accès équitable, non commercial et robuste. Notre partenariat soutient les revues appartenant à la communauté par un financement durable et les aide en fin de compte à évoluer vers un modèle d'accès libre diamantaire où le contenu est disponible en libre accès et où les auteurs peuvent publier en libre accès sans aucun frais.&#8239;» '''Le mois d'octobre '''a également vu la [https://www.cgdev.org/publication/how-science-diplomacy-can-reshape-global-research-publishing-theory-change publication d'un rapport du Centre for Global Development (CGD]) sur les positions des membres du G20 en matière de politique de libre accès. L'analyse menée par le CGD montre que la plupart des membres ont mis en place une certaine forme de politique ou de stratégie en matière de libre accès (voir [https://www.cgdev.org/blog/g20-open-access-policies-opportunity-harmonisation le résumé des principales conclusions en anglais ici]). Plusieurs pays, dont la France, l'Inde, le Mexique et la Turquie, exigent la publication immédiate en libre accès, et d'autres membres (comme le Canada, l'UE et le Japon) sont en train de réviser leurs politiques de libre accès en faveur du libre accès immédiat. Selon le CGD, l'Afrique du Sud, la Russie, la Corée du Sud, l'Indonésie, le Brésil et l'Union africaine figurent parmi les membres du G20 qui n'ont pas mis en place de politiques nationales officielles en matière de libre accès ([https://www.cgdev.org/blog/g20-open-access-policies-opportunity-harmonisation Demeshko et Drake 2024]). Enfin, le '''mois d'octobre '''a également été marqué par la publication du [https://www.stm-assoc.org/oa-dashboard-2024/ tableau de bord STM OA Dashboard pour 2024] (en anglais). Selon ce tableau de bord, trois fois plus des articles de revues, des comptes rendus et des documents de conférence ont été publiés en libre accès en 2024 qu'en 2013 (11 %). Malheureusement, comme le note STM dans sa méthodologie, une limitation importante de cette dernière est qu'elle ne prend en compte que les formes d'accès aux publications de type bronze, or, vert et par abonnement uniquement. Les publications en libre accès de type platine ou diamant sont incluses dans la catégorie d'accès or. En '''décembre, '''le deuxième [https://doasummit.uct.ac.za/fr/ sommet mondial sur le libre accès aux diamants] sera organisé par l'université du Cap. Les conclusions du premier sommet mondial sur le libre accès au diamant, qui [https://globaldiamantoa.org/fr/home-2-4-6/ s'est tenu à Toluca, au Mexique], [https://globaldiamantoa.org/wp-content/uploads/2023/11/202310-Sommet-Mondial-AOD-Conclusions.pdf sont disponibles ici]. Plusieurs partenaires de l'INKE ont participé au premier sommet mondial, notamment Érudit et PKP (lire leur [https://www.coalition-publi.ca/news-nouvelles/summit-diamond-oa-toluca réflexion commune sur l'expérience ici]). Érudit et PKP, tous deux partenaires du projet d'infrastructure canadien [https://www.coalition-publi.ca/le-projet Coalition Publica], ont été reconnus l'année dernière lors du Sommet mondial comme jouant un rôle important dans l'alimentation et le maintien des conversations sur le libre accès et la science ouverte. À l'horizon '''2025''', les 194 États membres de l'UNESCO devront [https://www.unesco.org/en/open-science/2025reports soumettre des] rapports nationaux sur la [https://www.unesco.org/en/open-science/implementation mise en œuvre de la Recommandation de l'UNESCO de 2021 sur la science ouverte] avant la fin du mois de février 2025. Les rapports seront utilisés pour déterminer l'état d'avancement des efforts de mise en œuvre, ainsi que les tendances régionales et mondiales en matière de science ouverte. En outre, les politiques et stratégies d'information liées à la science ouverte et à l'accès ouvert seront rassemblées à l'aide des rapports et incorporées dans l'[https://www.unesco.org/en/go-spin?hub=686 Observatoire mondial des instruments de politique STI de l'UNESCO]. Nous prévoyons également la publication d'une politique révisée de libre accès par les trois agences nationales de financement de la recherche au Canada. ==Questions et considérations clés== Si l'année 2024 a été marquée par de nombreuses réussites dans le domaine de l'accès libre, de nombreux défis subsistent. Par exemple, bien qu'une étude portant sur 420 millions de citations ait montré que les publications en libre accès étaient citées par un plus grand nombre de personnes dans le monde, des disparités Nord-Sud notables continuent de prévaloir ([https://blogs.lse.ac.uk/impactofsocialsciences/2024/01/30/open-access-works-420-million-citations-show-oa-outputs-are-cited-by-more-researchers-from-more-places/ Huang, Neylon et Montgomery, 2024]). Dans un [https://blogs.lse.ac.uk/impactofsocialsciences/2024/01/30/open-access-works-420-million-citations-show-oa-outputs-are-cited-by-more-researchers-from-more-places/ article explicatif rédigé pour le blog Impact of Social Sciences], Huang, Neylon et Montgomery (2024) soulignent que les chercheurs situés dans le nord de l'Europe qui ont publié en libre accès ont connu les plus fortes augmentations du nombre de citations, ainsi que la plus forte augmentation du nombre de fois où leurs travaux ont été cités par des chercheurs d'Afrique subsaharienne - mais la même chose n'était pas vraie dans le sens inverse. Comme le note [https://www.nature.com/articles/d41586-024-01748-4 Else (2024)], l'accès à une infrastructure ouverte joue un rôle clé dans la capacité des chercheurs situés dans les pays à faible revenu à rendre leurs travaux librement accessibles. Souvent, l'objectif de cette infrastructure est de rendre à la communauté le contrôle de la publication et de la diffusion, explique Kathleen Fitzpatrick dans une allocution intitulée «&#8239;[https://hsscommons.ca/fr/publications/7413/1 Open Infrastructures for the Future of Knowledge Production]&#8239;» ([https://hsscommons.ca/en/publications/7413/1 Infrastructures ouvertes pour l'avenir de la production de connaissances]) prononcée devant les participants à la réunion «&#8239;Implementing New Knowledge Environments&#8239;» (Mise en œuvre de nouveaux environnements de connaissances) qui s'est tenue à Montréal [https://inke.ca/creative-approaches-to-open-social-scholarship-canada/ en juin dernier] et qui portait sur les approches créatives de l'érudition sociale ouverte au Canada. Cependant, ces infrastructures dépendent souvent d'autres infrastructures détenues et contrôlées par des entreprises (comme Amazon Web Services), ce qui remet en question la durabilité à long terme de ces infrastructures et systèmes (Fitzpatrick 2024). En effet, ces questions plus profondes concernant l'écosystème plus large de l'édition savante, y compris la façon dont l'impact de la recherche est mesuré et défini, continueront sans doute à être au premier plan de la lutte pour le libre accès à l'horizon 2025 et au-delà. Ou, si elles ne le sont pas, elles devraient l'être, car, comme le souligne Susan Murray (African Journals OnLine), «&#8239;[https://doi.org/10.1038/d41586-024-01748-4 sans changer certains des aspects les plus enracinés des systèmes de recherche locaux, les avantages du libre accès pour les chercheurs des pays à faible revenu pourraient ne pas se concrétiser pleinement]&#8239;» (Else, 2024). ==Références== *Bilodeau, Maxime. 2024. «&#8239;Libre accès : une mine de diamants sous ses pieds.«&#8239;» ''Affaires universitaires ''(blog). 21 août 2024. [https://www.affairesuniversitaires.ca/actualites/actualites-article/libre-acces-une-mine-de-diamants-sous-ses-pieds/ https://www.affairesuniversitaires.ca/actualites/actualites-article/libre-acces-une-mine-de-diamants-sous-ses-pieds/] *Groupe de pilotage BOAI20. 2022. «&#8239;L’initiative de Budapest pour l’accès ouvert : recommandations du 20e anniversaire&#8239;». ''Initiative de Budapest pour l’accès ouvert''. 15 mars 2022. [https://www.budapestopenaccessinitiative.org/boai20/boai20-french-translation/ https://www.budapestopenaccessinitiative.org/boai20/boai20-french-translation/] *Chawla, Dalmeet Singh. 2024. «&#8239;Japan's Push to Make All Research Open Access Is Taking Shape&#8239;» (La volonté du Japon de rendre toute la recherche libre d'accès prend forme). ''Nature'', mai. [https://doi.org/10.1038/d41586-024-01493-8 https://doi.org/10.1038/d41586-024-01493-8]. *Demeshko, Anastassia, et Tom Drake. s.d. «&#8239;G20 Open Access Policies : An Opportunity for Harmonisation&#8239;». ''Center for Global Development ''(blog). Consulté le 8 octobre 2024. [https://www.cgdev.org/blog/g20-open-access-policies-opportunity-harmonisation https://www.cgdev.org/blog/g20-open-access-policies-opportunity-harmonisation]. *DOAJ. 2024. «&#8239;Communiqué de presse : PubScholar rejoint le mouvement de soutien au répertoire des revues en libre accès&#8239;». ''Blog du DOAJ''. 14 juin 2024. [https://blog.doaj.org/2024/06/14/press-release-pubscholar-joins-the-movement-to-support-the-directory-of-open-access-journals/ https://blog.doaj.org/2024/06/14/press-release-pubscholar-joins-the-movement-to-support-the-directory-of-open-access-journals/]. *Else, Holly. 2024. «&#8239;Open Access Is Working - but Researchers in Lower-Income Countries Enjoy Fewer Benefits&#8239;» (Le libre accès fonctionne, mais les chercheurs des pays à faible revenu bénéficient de moins d'avantages). ''Nature'', juin. [https://doi.org/10.1038/d41586-024-01748-4 https://doi.org/10.1038/d41586-024-01748-4]. *Érudit. n.d. «&#8239;Le POA : soutenir un libre accès équitable&#8239;». ''Érudit''. Consulté le 8 octobre 2024. [https://apropos.erudit.org/partenariat/ https://apropos.erudit.org/partenariat/]. *Fitzpatrick, Kathleen. 2024. «&#8239;Open Infrastructures for the Future of Knowledge Production&#8239;» (Infrastructures ouvertes pour l'avenir de la production de connaissances). Keynote présentée à ''Creative Approaches to Open Social Scholarship : Canada (réunion du partenariat Implementing New Knowledge Environments (INKE))''. Montréal, Canada. [https://hsscommons.ca/fr/publications/7413/1/ https://hsscommons.ca/fr/publications/7413/1/]. *Gordon, Ashley. 2024. «&#8239;La déclaration de Barcelone prône l'accès libre à l'information sur la recherche&#8239;». ''SPARC''. 16 avril 2024. [https://sparcopen.org/news/2024/barcelona-declaration-pushes-for-open-default-to-research-information/ https://sparcopen.org/news/2024/barcelona-declaration-pushes-for-open-default-to-research-information/]. *Huang, Chun-Kai, Cameron Neylon et Lucy Montgomery. 2024. «&#8239;Open Access Works - 420 Million Citations Show OA Outputs Are Cited by More Researchers from More Places&#8239;» (L'accès libre fonctionne - 420 millions de citations montrent que les résultats de l'accès libre sont cités par plus de chercheurs dans plus d'endroits). ''Impact of Social Sciences ''(blog). 30 janvier 2024. [https://blogs.lse.ac.uk/impactofsocialsciences/2024/01/30/open-access-works-420-million-citations-show-oa-outputs-are-cited-by-more-researchers-from-more-places/ https://blogs.lse.ac.uk/impactofsocialsciences/2024/01/30/open-access-works-420-million-citations-show-oa-outputs-are-cited-by-more-researchers-from-more-places/] *Huang, Chun-Kai, Cameron Neylon, Lucy Montgomery, Richard Hosking, James P. Diprose, Rebecca N. Handcock et Katie Wilson. 2024. «&#8239;Les résultats de la recherche en libre accès font l'objet de citations plus diversifiées&#8239;». ''Scientometrics ''129 (2) : 825–45. [https://doi.org/10.1007/s11192-023-04894-0 https://doi.org/10.1007/s11192-023-04894-0]. *Semaine internationale du libre accès. 2024. «&#8239;Semaine internationale du libre accès 2024 : Community over Commercialization[https://www.openaccessweek.org/theme/en&#8239;». ]https://www.openaccessweek.org/theme/en. *McKenna, Jack. 2024. «&#8239;Open Access in Japan&#8239;». ''MDPI Blog ''(blog). 27 février 2024. [https://mdpiblog.wordpress.sciforum.net/2024/02/27/open-access-in-japan/ https://mdpiblog.wordpress.sciforum.net/2024/02/27/open-access-in-japan/]. *Nicholson, Craig. 2024. «&#8239;Elsevier Parent annonce une hausse de 10 % de ses bénéfices pour 2023&#8239;». ''Research Professional News''. 15 février 2024. [https://www.researchprofessionalnews.com/rr-news-europe-infrastructure-2024-2-elsevier-parent-reports-10-hike-in-profits-for-2023/ https://www.researchprofessionalnews.com/rr-news-europe-infrastructure-2024-2-elsevier-parent-reports-10-hike-in-profits-for-2023/]. *«&#8239;Tableau de bord de l'OA 2024&#8239;». 2024. Tableau de bord OA. ''STM ''(blog). 2024. [https://www.stm-assoc.org/oa-dashboard-2024/ https://www.stm-assoc.org/oa-dashboard-2024/]. *Open Access Network (Réseau d'accès ouvert). 2024. «&#8239;Green Open Access for Japan&#8239;» («&#8239;L'accès ouvert et vert pour le Japon&#8239;»). ''Open Access Network News''. 5 juin 2024. [https://open-access.network/en/services/news/article/green-open-access-for-japan https://open-access.network/en/services/news/article/green-open-access-for-japan]. *Sellanga, Jerry, Gail Steinhart, Emmy Tsang et Nicky Wako. 2024. «&#8239;2024 Survey of Recent Open Science Policy Developments&#8239;» («&#8239;Enquête 2024 sur les développements récents de la politique de la science ouverte&#8239;»). ''Invest in Open Infrastructure.'' [https://doi.org/10.5281/zenodo.11499591 https://doi.org/10.5281/zenodo.11499591]. *Steinhart, Gail, Lauren Collister, Chun-Kai (Karl) Huang, Sarah Lippincott, Cameron Neylon, David Riordan, Jerry Sellanga, Katherine Skinner, Kaitlin Thaney et Emmy Tsang. 2024. «&#8239;2024 State of Open Infrastructure: Trends in Characteristics, Funding, Governance, Adoption, and Policy&#8239;» («&#8239;État de l'infrastructure ouverte en 2024 : endances en matière de caractéristiques, de financement, de gouvernance, d'adoption et de politique&#8239;»). ''Invest in Open Infrastructure''. [https://doi.org/10.5281/zenodo.10934089 https://doi.org/10.5281/zenodo.10934089]. *Recherche et innovation au Royaume-Uni. 2021. «&#8239;UKRI Open Access Policy&#8239;» («&#8239;Politique de libre accès de l'UKRI&#8239;»). ''UK Research and Innovation''. 6 août 2021. [https://www.ukri.org/publications/ukri-open-access-policy/ https://www.ukri.org/publications/ukri-open-access-policy/]. *Recherche et innovation au Royaume-Uni. 2023. «&#8239;UKRI Updates Guidance for Open Access Policy&#8239;» («&#8239;L'UKRI met à jour ses orientations en matière de politique de accès ouvert&#8239;»). ''UK Research and Innovation''. 24 mai 2023. [https://www.ukri.org/news/ukri-updates-guidance-for-open-access-policy/ https://www.ukri.org/news/ukri-updates-guidance-for-open-access-policy/] *UNESCO. 2024. «&#8239;Annonce de l’Alliance Mondiale pour l’accès ouvert Diamant&#8239;». ''Événement de l'UNESCO''. 10 juillet 2024. [https://www.unesco.org/fr/articles/annonce-de-lalliance-mondiale-pour-lacces-ouvert-diamant https://www.unesco.org/fr/articles/annonce-de-lalliance-mondiale-pour-lacces-ouvert-diamant] [[Catégorie:Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024 (livre)]] 795vbthmh51uf1cr3v2a8ngwi6eg4jr Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Réponses à l’intelligence artificielle 0 82376 744025 742851 2025-06-02T23:21:44Z LodestarChariot2 120009 /* Références */ 744025 wikitext text/x-wiki ''Ce rapport «&#8239;Insights and Signals&#8239;» a été rédigé par Brittany Amell (avec nos remerciements à John Willinsky, John Maxwell et William Bowen pour leurs commentaires et contributions), pour le Electronic Textual Cultures Laboratory et le partenariat Implementing New Knowledge Environments.'' Les rapports'' «&#8239;Policy Insights and Signals&#8239;» ''scrutent l'horizon afin d'identifier et d'analyser les tendances émergentes et les signaux précurseurs susceptibles d'influer sur les orientations politiques futures en matière de libre accès et d'érudition ouverte et sociale. Ils ont tendance à mettre en évidence les changements dans la technologie, l'opinion et les sentiments du public, et/ou les changements réglementaires à l'intérieur et à l'extérieur du Canada. Tout comme les observations politiques de l'OSPO, les rapports sur les perspectives et les signaux visent à aider les partenaires à élaborer des stratégies proactives, réactives et tournées vers l'avenir. Ce rapport'' Insights and Signals'' est le premier d'une série qui se concentre sur l'évolution des discussions centrées sur l'intelligence artificielle (IA), en particulier l'IA générative (genAI) et les grands modèles de langage (LLM), et sur les implications qu'elles peuvent avoir pour l'accès libre et la recherche sociale ouverte. D'autres rapports «&#8239;Insights and Signals&#8239;» consacrés à l'intelligence artificielle vous intéressent ? Vous les trouverez [[Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/L’IA générative et l’édition savante|ici]] et [[Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Les agences fédérales de financement de la recherche annoncent un projet de lignes directrices sur l’utilisation de l’intelligence artificielle générative|ici]]. Les points abordés dans ce rapport sont les suivants * Une brève introduction à l'intelligence artificielle générative, avec des commentaires de John Maxwell * [https://www.consilium.europa.eu/fr/press/press-releases/2024/05/21/artificial-intelligence-ai-act-council-gives-final-green-light-to-the-first-worldwide-rules-on-ai/ La première loi mondiale sur l'intelligence artificielle] adoptée en mai 2024 par le Conseil de l'Union européenne. * L'inclusion de l'intelligence artificielle dans la [https://www.parl.ca/legisinfo/fr/projet-de-loi/44-1/c-27 loi de mise en œuvre de la Charte numérique du Canada] (2022), ainsi que les critiques de [https://news.westernu.ca/2024/04/proposed-ai-legislation/ Joanna Redden] (2024), professeure associée à la faculté d'études sur l'information et les médias de l'université Western, de critique la législation proposée par le Canada en matière d'intelligence artificielle dans sa forme actuelle. * Plusieurs réactions à l'IA au Canada de la part de revues, d'établissements postsecondaires, de sociétés savantes et d'organismes subventionnaires, ainsi que certaines préoccupations fondamentales soulevées par ces groupes. * Une [https://www.pm.gc.ca/fr/nouvelles/communiques/2024/04/07/pour-avantage-canadien-matiere-dintelligence-artificielle annonce] du premier ministre Justin Trudeau (2024) concernant son intention de consacrer 2,4 milliards de dollars pour assurer un avantage canadien en matière d'intelligence artificielle * Réponses des partenaires de l'INKE John Willinsky (fondateur du Public Knowledge Project) et John Maxwell (professeur associé d'édition à l'Université Simon Fraser) * Certains silences discursifs proposés à prendre en considération, tels que les perspectives sur l[https://montrealethics.ai/in-consideration-of-indigenous-data-sovereignty-data-mining-as-a-colonial-practice/ 'extraction des données comme pratique,] et la [https://ubctoday.ubc.ca/news/june-06-2024/indigenous-data-stewardship-stands-against-extractivist-ai souveraineté des données autochtones ] Ce rapport se termine par quelques questions et considérations clés. '''Remarque : Nous vous présentons nos excuses en avance, car la plupart des sources mentionnées dans ce rapport sont disponibles en anglais uniquement.''' ==Présentation succincte de l'intelligence artificielle générative== Les débats largement répandus sur l'avenir de l'intelligence artificielle et la nécessité de cadres éthiques et de politiques réglementaires pour atténuer les dommages potentiels, relancés en 2022 par la première version du système d'intelligence artificielle générative (IA) [https://chat.openai.com/auth/login ChatGPT] d'OpenAI, continuent de retenir l'attention des chercheurs et des médias. Les outils d'intelligence artificielle générative tels que ChatGPT et [https://www.bing.com/ Bing] de Microsoft (tous deux alimentés par GPT-4 d'OpenAI) et [https://gemini.google.com/ Gemini de Google] (Bard, précédemment) peuvent être utilisés pour générer de la poésie, des essais, du code, des traductions et des réponses à des examens, ainsi que des images et des vidéos. Cependant, si ces outils ont un potentiel énorme, ils créent également des défis et, dans certains cas, des préjudices (par exemple, [https://datajusticelab.org/data-harm-record/ «&#8239;Data Harm Record&#8239;» par Redden et al. 2020] ; voir également, de manière générale, [https://mitpress.mit.edu/9780262548328/more-than-a-glitch/ Broussard 2024], Noble 2018 et O'Neil 2016). Selon Josh Nicholson, cofondateur et PDG de Scite.ai, le modèle de langage large Galactica de Meta pour la science a été «&#8239;retiré en moins d'une semaine parce qu'il était si problématique. Vous pouviez lui donner des instructions et obtenir un article complet en retour, mais il pouvait être raciste ou complètement erroné&#8239;» ([https://www.wiley.com/en-us/network/research-libraries/libraries-archives-databases/open-access/making-ai-an-opportunity-for-open-access cité dans Wiley 2024], 1). L'intelligence artificielle générative, ou genAI comme nous l'appelons ici, est utilisée pour décrire des outils tels que ceux mentionnés ci-dessus, mais elle décrit en réalité un changement fondamental dans la conception des instructions qui peuvent être suivies pour accomplir une tâche, également connues sous le nom d'algorithmes (Danaher et al. 2017). Ce changement a entraîné l'abandon des algorithmes «&#8239;descendants&#8239;» (où les ensembles de règles pour les algorithmes étaient définis de manière exhaustive par les programmeurs) au profit d'algorithmes d'apprentissage automatique «&#8239;ascendants&#8239;» (où un algorithme est essentiellement formé pour développer son propre ensemble de règles). Les algorithmes d'apprentissage automatique consistent à donner à la machine des données, un objectif, un retour d'information pour lui indiquer qu'elle est sur la bonne voie, puis à lui laisser du temps pour trouver la meilleure façon de suivre les instructions et d'atteindre l'objectif (Fry 2018, p. 11). En d'autres termes, la genAI s'appuie sur l'utilisation de diverses techniques statistiques pour produire les résultats qui émerveillent nombre d'entre nous (Gorwa et al. 2020 ; [https://blogs.lse.ac.uk/politicsandpolicy/why-artificial-intelligence-is-a-misnomer/ Whiteley 2023]). En effet, le poème que vous avez demandé à ChatGPT de générer est le résultat de calculs probabilistes qui sélectionnent les mots en fonction de leur probabilité de s'adapter (statistiquement) au contexte. Cela semble moins romantique, mais c'est peut-être important - John Maxwell (professeur associé d'édition à l'université Simon Fraser), partenaire d'INKE, le pense en tout cas. Répondant à cet article par courriel, John Maxwell a écrit : «&#8239;Je suis de plus en plus préoccupé par le fait qu'en réagissant (à la fois individuellement et collectivement, de manière causale et formelle) à l'essor de l'apprentissage en profondeur, du texte génératif et des technologies de l'image - en suivant l'exemple de l'industrie qui les ‹ IA › - nous jouons le jeu d'un groupe de promoteurs d'investissements très habiles et, en même temps, nous sabotons nos propres sensibilités critiques à l'égard des diverses innovations rassemblées sous ce parapluie&#8239;». (Vous pouvez lire l'intégralité de la réponse de John Maxwell en défilant jusqu'à la section «&#8239;Réponses du partenariat INKE&#8239;» ci-dessous). Maxwell n'est pas le seul à tirer la sonnette d'alarme. Dans un [https://blogs.lse.ac.uk/politicsandpolicy/why-artificial-intelligence-is-a-misnomer/ article] publié sur le blog de la l'École d'économie et de sciences politiques de Londres, Paul Whiteley affirme que «&#8239;l’intelligence artificielle&#8239;» est une appellation erronée, inventée par l'informaticien John McCarthy en 1950 (et anthropomorphisée par le reste d'entre nous depuis lors). Même ChatGPT est d'accord. Lorsque nous avons demandé à ChatGPT s'il pensait que les utilisateurs avaient tendance à l'anthropomorphiser, il a généré le «&#8239;résultat statistique&#8239;» suivant : <blockquote> Oui, les gens m'anthropomorphisent souvent ! C'est tout à fait naturel ; le langage humain et l'interaction impliquent souvent des hypothèses sur des expériences, une compréhension ou des intentions partagées. Étant donné que mes réponses relèvent de la conversation et imitent les schémas du langage humain, les utilisateurs peuvent parfois m'attribuer des pensées, des sentiments ou des intentions, même si je n'ai pas d'expérience, de conscience ou de compréhension personnelle. La familiarité de la conversation peut faire oublier que les réponses proviennent de modèles plutôt que d'un sentiment intérieur. C'est fascinant parce que cela met en évidence à quel point les gens sont prêts à chercher une connexion, même avec une technologie qui est fondamentalement différente de l'esprit humain. </blockquote> John Maxwell (professeur associé d'édition à l'université Simon Fraser et partenaire de l'INKE) nous met toutefois en garde contre cette anthropomorphisation, car elle rend difficile l'élaboration des réponses politiques significatives : <blockquote> Alors que, par exemple, «&#8239;LLM&#8239;» définit une technologie spécifique avec des caractéristiques spécifiques pour lesquelles nous pourrions développer une réponse politique cohérente, le terme «&#8239;IA&#8239;» est un fourre-tout de science-fiction qui comporte un ensemble de connotations utopiques, dystopiques et eschatologiques bien médiatisées (et monétisées). Il est peu probable que nous puissions apporter une réponse significative à un objet aussi mal défini. J'espère que, lorsque nous commencerons à élaborer des lignes directrices et des politiques, nous pourrons commencer à différencier ces technologies et à les désigner par leurs noms et fonctions spécifiques, au lieu de répéter le battage médiatique selon lequel ces boîtes noires massives, mystérieuses et appartenant à des entreprises, résoudront simultanément les problèmes de l'humanité tout en constituant une menace existentielle. </blockquote> ==L'UE annonce l'approbation de la première loi mondiale sur l'intelligence artificielle== Sur le plan politique, le Conseil de l'UE [https://www.consilium.europa.eu/fr/press/press-releases/2024/05/21/artificial-intelligence-ai-act-council-gives-final-green-light-to-the-first-worldwide-rules-on-ai/ a officiellement approuvé] en mai dernier la [https://www.consilium.europa.eu/fr/press/press-releases/2024/05/21/artificial-intelligence-ai-act-council-gives-final-green-light-to-the-first-worldwide-rules-on-ai/ première loi mondiale sur l'intelligence artificielle.] La législation suivra une «&#8239;approche fondée sur le risque, ce qui signifie que plus le risque de causer des dommages à la société est élevé, plus les règles sont strictes&#8239;», explique le Conseil dans un [https://www.consilium.europa.eu/en/press/press-releases/2024/05/21/artificial-intelligence-ai-act-council-gives-final-green-light-to-the-first-worldwide-rules-on-ai/ communiqué de presse]. «&#8239;Avec la législation sur l'IA, l'Europe souligne l'importance de la confiance, de la transparence et de l'obligation de rendre des comptes pour ce qui est des nouvelles technologies, tout en veillant dans le même temps à ce que cette technologie en évolution rapide puisse prospérer et stimuler l'innovation européenne&#8239;», déclare Mathieu Michel, Secrétaire d'État fédéral belge à la Digitalisation, chargé de la Simplification administrative, de la Protection de la vie privée et de la Régie des bâtiments ([https://www.consilium.europa.eu/fr/press/press-releases/2024/05/21/artificial-intelligence-ai-act-council-gives-final-green-light-to-the-first-worldwide-rules-on-ai/ Conseil, 2024]). Quatre organes directeurs, dont «&#8239;un groupe scientifique d'experts indépendants&#8239;», seront chargés de veiller à l'application de la loi sur l'IA. Trois autres organes comprennent un bureau de l'IA au sein de la Commission européenne, un forum consultatif pour les parties prenantes et un conseil de l'IA composé de représentants des États membres ([https://www.consilium.europa.eu/fr/press/press-releases/2024/05/21/artificial-intelligence-ai-act-council-gives-final-green-light-to-the-first-worldwide-rules-on-ai/ Conseil, 2024]). ==Vers une réglementation de l'intelligence artificielle au Canada?== ''' '''Au Canada, l'inclusion de l'intelligence artificielle dans le projet de la loi C-27 (Loi de 2022 sur la mise en œuvre de la Charte du numérique) fait toujours l'objet d'un examen en comité à la Chambre des communes depuis sa deuxième lecture il y a plus d'un an, en avril 2023. [https://news.westernu.ca/2024/04/proposed-ai-legislation/ Selon Joanna Redden] (2024), professeure à la faculté d'études sur l'information et les médias de l'Université Western, qui critique la législation canadienne sur l'IA proposée dans sa forme actuelle, de nombreux Canadiens ont déjà peu confiance dans l'utilisation croissante de l'IA, même si [https://medium.com/politics-ai/an-overview-of-national-ai-strategies-2a70ec6edfd le Canada a été le premier pays à introduire une stratégie nationale en matière d'IA]. Faisant écho aux préoccupations de personnes telles qu'[https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4658004 Andrew Clement] (professeur émérite, Université de Toronto), ainsi que [https://www.amo-oma.ca/en/ai-policy-report/ McKelvey et ses collègues (2024]), Redden suggère que cette méfiance est due, en partie, à un manque de consultation publique significative, «&#8239;en dépit des préoccupations profondes du public&#8239;». Redden note que la législation proposée est non seulement «&#8239;déjà en décalage avec les besoins des Canadiens&#8239;», mais qu'elle est également «&#8239;en deçà des approches réglementaires adoptées par d'autres nations&#8239;», telles que celle récemment approuvée par [https://www.consilium.europa.eu/fr/press/press-releases/2024/05/21/artificial-intelligence-ai-act-council-gives-final-green-light-to-the-first-worldwide-rules-on-ai/ l'Union européenne] ou le [https://www.whitehouse.gov/briefing-room/presidential-actions/2023/10/30/executive-order-on-the-safe-secure-and-trustworthy-development-and-use-of-artificial-intelligence/ décret publié par la Maison Blanche] en 2023. Certains des besoins identifiés par Redden incluent la garantie que les utilisations de l’IA par les entreprises et les gouvernements sont transparentes et qu’il existe des mécanismes efficaces pour maintenir la surveillance et la responsabilité. En outre, Redden soutient qu’il est essentiel de consacrer des fonds pour garantir le maintien des «&#8239;registres d’IA&#8239;» publics. En outre, Joanna Redden estime qu'il est essentiel de consacrer des fonds à la tenue de «registres d'IA&#8239;» publics (note : les registres d'IA, [https://tagcanada.shinyapps.io/register/ tels que celui mis au point par Redden et ses collègues], permettent de savoir où et comment l'IA et d'autres systèmes automatisés sont utilisés). Si elle est adoptée, la [https://www.parl.ca/legisinfo/fr/projet-de-loi/44-1/c-27 Loi de 2022 sur la mise en œuvre de la Charte du numérique] (également connue sous le nom de «&#8239;loi édictant la loi sur la protection de la vie privée du consommateur, la loi sur le Tribunal de la protection des renseignements personnels et des données et la loi sur l'intelligence artificielle et les données, et apportant des modifications corrélatives et connexes à d'autres lois&#8239;») serait la première loi axée sur la réglementation de l'IA au Canada. Actuellement, les gestionnaires et les développeurs d'IA générative au Canada sont invités à s'engager volontairement à [https://ised-isde.canada.ca/site/ised/en/voluntary-code-conduct-responsible-development-and-management-advanced-generative-ai-systems respecter ]un [https://ised-isde.canada.ca/site/isde/fr/code-conduite-volontaire-visant-developpement-gestion-responsables-systemes-dia-generative-avances Code de conduite volontaire visant un développement et une gestion responsables des systèmes d'IA générative avancés]. Ce code de conduite volontaire met l'accent sur six résultats : la responsabilité, la sécurité, la justice et l'équité, la transparence, la surveillance humaine et le suivi, ainsi que la validité et la robustesse. ==Réponses des revues, des établissements d'enseignement postsecondaire, des sociétés savantes et des organismes subventionnaires à l'IA au Canada== Dans le but de freiner l'utilisation abusive de l'IA générative, '''plusieurs revues '''(voir [https://www.cmaj.ca/content/195/34/E1168 ici], [https://www.caaa.ca/fr/ ici] et [https://www.jogc.com/article/S1701-2163(23)00167-6/fulltext ici]), '''établissements d'enseignement postsecondaire '''(voir [https://uwaterloo.ca/information-systems-technology/about/policies-standards-and-guidelines/guidance-artificial-intelligence-use ici] et [https://www.senecapolytechnic.ca/about/policies/generative-ai-policy.html ici] pour des exemples, ainsi qu'[https://cdlra-acrfl.ca/wp-content/uploads/2024/05/2023-AI-Special-Topics-Report.pdf ici] pour un commentaire plus général et [https://higheredstrategy.com/ai-observatory-home/ ici] pour l'observatoire de HESA sur l'IA dans le secteur postsecondaire au Canada), '''associations savantes '''(voir [https://publicationethics.org/guidance/cope-position/authorship-and-ai-tools ici] et [https://www.carl-abrc.ca/wp-content/uploads/2023/12/Generative-Artificial-Intelligence-A-Brief-Primer-FR.pdf ici]) et '''organismes subventionnaires '''(en savoir plus [https://science.gc.ca/site/science/fr/financement-interorganismes-recherche/politiques-lignes-directrices/lutilisation-lintelligence-artificielle-generative-dans-lelaboration-levaluation-propositions ici] et [https://ospolicyobservatory.uvic.ca/trois-organismes-ia/ ici]) sont en train d'élaborer et de publier des déclarations, des politiques et/ou des lignes directrices qui définissent les attentes concernant ce qui est considéré comme une utilisation équitable ou responsable de l'IA dans leurs contextes respectifs. Les préoccupations relatives à la responsabilité, à la paternité, à la transparence, à la divulgation de l'utilisation, à la responsabilité, à l'exactitude, à la partialité, à la sécurité, à la confidentialité et à la vie privée, ainsi qu'aux droits d'auteur et à la propriété intellectuelle reviennent constamment dans ces déclarations, politiques et lignes directrices. Plusieurs revues ainsi que de grands éditeurs tels que SAGE, Elsevier et Wiley interdisent explicitement de citer un outil d'IA (tel que ChatGPT) comme auteur car, comme l'écrit Tulandi (2023) dans une revue médicale canadienne, «&#8239;la qualité d'auteur implique des responsabilités et des tâches qui ne peuvent être attribuées et exécutées que par des êtres humains&#8239;» (paragraphe 7). Outre les préoccupations soulevées ci-dessus, l'ABRC, ou l'[https://www.carl-abrc.ca/wp-content/uploads/2023/12/Generative-Artificial-Intelligence-A-Brief-Primer-FR.pdf Association des bibliothèques de recherche du Canada (2023)], recommande que les réponses à l'IA générative tiennent également compte des impacts sociaux associés à l'utilisation de l'IA, notamment qui a accès aux outils d'IA générative et qui n'y a pas accès, que ce soit pour des raisons financières ou autres. [https://blog.core.ac.uk/2023/03/17/core-gpt-combining-open-access-research-and-ai-for-credible-trustworthy-question-answering/ Citant les travaux d'un groupe de chercheurs associés à l'Open University au Royaume-Uni], l'ABRC (2023) se demande également si la combinaison d'articles en libre accès et d'articles payants dans le développement d'ensembles de données utilisés pour former l'IA générative pourrait améliorer sa fiabilité et sa crédibilité, bien qu'elle note également le risque d'implications juridiques. Alors que les débats relatifs à la loi de mise en œuvre de la Charte numérique se poursuivent, le Premier ministre Justin Trudeau (2024) a [https://www.pm.gc.ca/fr/nouvelles/communiques/2024/04/07/pour-avantage-canadien-matiere-dintelligence-artificielle annoncé son intention] de consacrer 2,4 milliards de dollars à la «&#8239;sécurisation de l'avantage du Canada en matière d'IA&#8239;», bien qu'il soit intéressant de noter que seulement 2 % de ce financement (50 millions de dollars) est destiné à l'exploration des impacts sociaux associés à l'utilisation accrue de l'IA. ==Questions et considérations clés== Les idées et les signaux décrits ci-dessus indiquent que les développements récents de l'IA générative, ainsi que son intégration continue dans divers contextes académiques (et plus largement dans la société), posent des défis importants aux personnes impliquées dans l'élaboration des réponses politiques. En même temps, même s'il est important de prêter attention aux réponses existantes, les silences discursifs ou les absences (c'est-à-dire ce qui n'est '''pas '''dit, ou peut-être ce qui '''n'est pas '''amplifié et repris dans les rapports sur ce sujet) sont tout aussi importants et méritent d'être pris en considération. Parmi les absences notables proposées, citons la question de savoir si l'utilisation du contenu en ligne par les LLM est considérée comme une utilisation équitable (ainsi que d'autres considérations relatives au droit d'auteur). D'autres absences importantes concernent l'impact social et écologique des grands modèles de langage (LLM) et les matériaux, la main-d'œuvre et la puissance de calcul nécessaires pour les maintenir – en parallèle avec les conversations sur la durabilité dans les humanités numériques (comme [https://doi.org/10.1093/llc/fqab025 celle] de Johanna Drucker 2021 ou [https://www.thebritishacademy.ac.uk/publishing/journal-british-academy/10/facing-the-challenge-of-digital-sustainability-as-humanities-researchers/ celle] de Joanna Tucker 2022). D'autres incluent les implications des LLM pour les souverainetés des données Autochtone ([https://www.unesco.org/fr/articles/un-nouveau-rapport-et-des-lignes-directrices-pour-maintenir-la-souverainete-des-donnees-autochtones l'UNESCO publie un nouveau rapport et des lignes directrices pour maintenir la souveraineté des données autochtones qui s’inscrivent dans les développements de l'intelligence artificielle]), ainsi que les implications que les souverainetés (des données) autochtone peuvent avoir pour la réflexion sur «&#8239;l’IA éthique&#8239;» (Gaertner 2024 ; Roberts and Montoya 2024). Par exemple, en réfléchissant à l'intersection entre les nouvelles formes d'[https://www.arts.ubc.ca/news/indigenous-data-stewardship-stands-against-extractivist-ai/ IA et la souveraineté et la gestion des données autochtones], le professeur associé David Gaertner (Institute for Critical Indigenous Studies, UBC) établit d'autres liens entre l'IA formée sur de grands modèles linguistiques et les impacts du colonialisme de peuplement : <blockquote> Les technologies de l'IA, formées sur de grands modèles linguistiques, reflètent la privation des droits et la violence imposées par le colonialisme de peuplement tout en les redistribuant à l'échelle. Les algorithmes institutionnalisent une dynamique de pouvoir dans laquelle les récits linguistiques et culturels dominants sont davantage ancrés et amplifiés dans l'infrastructure sociale, tandis que l'expression personnelle devient de plus en plus obsolète et marginale. L'émergence des rapports détaillant la manière dont l'internet se cannibalise actuellement et génère de nouveaux contenus d'IA à partir de matériaux d'IA existants, également connue sous le nom de «&#8239;[https://en.wikipedia.org/wiki/Dead_Internet_theory théorie de l'Internet Mort]&#8239;», amplifie encore ces préoccupations. </blockquote> Cependant, nombreux sont ceux qui soulignent que les questions relatives au développement et à l'utilisation éthiques de l'IA sont souvent adressées aux entreprises privées et aux organisations qui utilisent leurs modèles. Qu'en est-il des membres de la communauté, des universitaires et des parties prenantes ? L'IA restera-t-elle uniquement entre les mains des entreprises privées et des sociétés à but lucratif ? Pas nécessairement. Certains commencent à explorer des approches de l'apprentissage automatique fondées sur les biens communs, comme [https://openfuture.eu/our-work/ai-and-the-commons/ Open Future, une] organisation à but non lucratif basée en Europe qui souhaite étudier les risques et les avantages potentiels associés aux nouveaux cadres de partage des modèles d'IA sous licence libre. Le commentaire suivant, que John Willinsky (fondateur du Public Knowledge Project et partenaire de l'INKE) a partagé avec nous, va dans le même sens : <blockquote> Bien qu'il y ait des raisons de s'inquiéter des récentes avancées de l'IA, les universitaires ont également la responsabilité d'explorer les contributions et les avancées potentielles de l'IA pour la recherche et l'érudition. Depuis un certain temps, le [https://pkp.sfu.ca/ Public Knowledge Project] se tourne vers l'IA pour résoudre les problèmes urgents liés à l'équité et à la qualité des ressources dans les communications savantes, avec un succès limité. Il mène actuellement des recherches sur la capacité des grands modèles de langage à relever le défi de longue date que représente le développement d'un moyen durable pour les revues accès libre diamant de publier dans les formats standard HTML et PDF, ainsi que d'exporter des fichiers en JATS XML. (Le commentaire de John Willinsky peut être lu dans son intégralité ci-dessous). </blockquote> Il est intéressant de noter que plusieurs modèles d'IA ont [https://www.forbes.com/sites/bernardmarr/2024/05/07/the-best-open-source-generative-ai-models-available-today/ déjà été publiés] sous la [https://www.apache.org/licenses/LICENSE-2.0 licence Apache 2.0] (une licence de logiciel permissive qui autorise l'utilisation du logiciel à toutes fins, y compris la distribution, la modification et la distribution de versions modifiées sans redevances, selon [https://en.wikipedia.org/wiki/Apache_License Wikipédia]), et d'autres pourraient être publiés avant la fin de l'année (des [https://www.theverge.com/2024/10/24/24278999/openai-plans-orion-ai-model-release-december rumeurs ]indiquent qu'OpenAI publiera son dernier modèle, «&#8239;Orion&#8239;», en décembre 2024). ==Réponses du partenariat INKE== ''Réponse de John Willinsky (Fondateur, Public Knowledge Project) :'' <blockquote> Bien qu'il y ait des raisons de s'inquiéter des récentes avancées de l'IA, les universitaires ont également la responsabilité d'explorer les contributions et les avancées potentielles de l'IA pour la recherche et l'érudition. Depuis un certain temps, le [https://pkp.sfu.ca/ Public Knowledge Project] se tourne vers l'IA pour résoudre les problèmes urgents liés à l'équité et à la qualité des ressources dans les communications savantes, avec un succès limité. Il mène actuellement des recherches sur la capacité des grands modèles de langage à relever le défi de longue date que représente le développement d'un moyen durable pour les revues Diamond OA de publier dans les formats standard HTML et PDF, ainsi que d'exporter des fichiers en JATS XML. L'objectif principal de ce travail est d'établir si les LLM peuvent être suffisamment adaptés pour automatiser de manière fiable le balisage HTML et JATS XML des manuscrits des auteurs (étant donné que ce balisage nécessite actuellement des compétences techniques ou des paiements qui dépassent la capacité de la plupart des revues Diamond OA). Ce travail a atteint le stade initial de la preuve de concept, et les travaux se poursuivent sur sa valeur comparative (par rapport à d'autres outils) et sur les moyens d'intégrer et de maintenir un tel service de balisage dans le flux de travail éditorial. </blockquote> ''Réponse de John Maxwell (professeur associé d'édition à l'université Simon Fraser) :'' <blockquote> Je crains de plus en plus qu'en réagissant (à la fois individuellement et collectivement, de manière causale et formelle) à l'essor des technologies d'apprentissage en profondeur, de texte génératif et d'image - en suivant l'exemple de l'industrie qui les appelle «&#8239;IA&#8239;» - nous fassions le jeu d'un groupe de promoteurs d'investissements très habiles et que nous minions en même temps notre propre sensibilité critique à l'égard des diverses innovations rassemblées sous cette égide. Le terme «&#8239;IA&#8239;» sert depuis plusieurs décennies déjà de marque d'aspiration pour une grande variété de technologies informatiques. Aujourd'hui, c'est le nom de marque d'un investissement massif de capitaux finançant une collection d'approches disparates d'apprentissage profond : LLM, modèles de diffusion, systèmes de reconnaissance faciale et autres outils. Il s'agit de technologies spécifiques qui existent et qui ont un impact sur les études et le travail. Mais alors que, par exemple, «&#8239;LLM&#8239;» définit une technologie spécifique avec des caractéristiques spécifiques pour lesquelles nous pourrions développer une réponse politique cohérente, le terme «&#8239;IA&#8239;» est un fourre-tout de science-fiction qui porte avec lui un ensemble de connotations utopiques, dystopiques et eschatologiques bien médiatisées (et monétisées). Il est peu probable que nous puissions apporter une réponse significative à un objet aussi mal défini. J'espère que, lorsque nous commencerons à élaborer des lignes directrices et des politiques, nous pourrons commencer à différencier ces technologies et à les désigner par leurs noms et fonctions spécifiques, au lieu de répéter le battage médiatique selon lequel ces boîtes noires massives, mystérieuses et appartenant à des entreprises résoudront simultanément les problèmes de l'humanité tout en constituant une menace existentielle. Il semblerait que les investisseurs en capital-risque et les hommes du battage médiatique nous aient devancés sur la ligne de départ ; nous devons rapidement mettre en place un appareil critique (par exemple, des études scientifiques et technologiques) pour l'analyse et l'élaboration de politiques et de lignes directrices efficaces. </blockquote> ==Références== *Association bibliothèques de recherche du Canada. 2023. «&#8239;Intelligence artificielle générative : Une brève introduction pour les établissements de l’ABRC&#8239;». [https://www.carl-abrc.ca/wp-content/uploads/2023/12/Generative-Artificial-Intelligence-A-Brief-Primer-FR.pdf https://www.carl-abrc.ca/wp-content/uploads/2023/12/Generative-Artificial-Intelligence-A-Brief-Primer-FR.pdf]. *Broussard, Meredith. 2024. ''More than a Glitch: Confronting Race, Gender, and Ability Bias in Tech''. First MIT Press paperback edition. Cambridge, Massachusetts and London, England: The MIT Press. *«&#8239;C-27 (44-1) : Loi édictant la Loi sur la protection de la vie privée des consommateurs, la Loi sur le Tribunal de la protection des renseignements personnels et des données et la Loi sur l'intelligence artificielle et les données et apportant des modifications corrélatives et connexes à d'autres lois&#8239;». Parlement du Canada. Consulté le 30 octobre 2024. [https://www.parl.ca/legisinfo/fr/projet-de-loi/44-1/c-27 https://www.parl.ca/legisinfo/fr/projet-de-loi/44-1/c-27] *Drucker, Johanna. 2021. «&#8239;Sustainability and Complexity: Knowledge and Authority in the Digital Humanities&#8239;». ''Digital Scholarship in the Humanities'' 36 (2): ii86–ii94. [https://doi.org/10.1093/llc/fqab025 https://doi.org/10.1093/llc/fqab025]. *Fitzpatrick, Kathleen. 2024. «&#8239;Open Infrastructures for the Future of Knowledge Production&#8239;». Keynote presented at ''Creative Approaches to Open Social Scholarship: Canada (An Implementing New Knowledge Environments (INKE) Partnership Gathering)''. Montreal, Canada.[https://doi.org/10.25547/6GG1-7B37 https://doi.org/10.25547/6GG1-7B37]. *Fry, Hannah. 2019. ''Hello World: Being Human in the Age of Algorithms''. New York: W.W. Norton & Company. *Gaertner, David. 2024. «&#8239;Indigenous Data Stewardship Stands against Extractivist AI&#8239;». ''UBC Faculty of Arts'' (blog). 18 juin 2024. [https://www.arts.ubc.ca/news/indigenous-data-stewardship-stands-against-extractivist-ai/ https://www.arts.ubc.ca/news/indigenous-data-stewardship-stands-against-extractivist-ai/] *Gorwa, Robert, Reuben Binns, and Christian Katzenbach. 2020. «&#8239;Algorithmic Content Moderation: Technical and Political Challenges in the Automation of Platform Governance&#8239;». ''Big Data & Society'' 7 (1): 2053951719897945. [https://doi.org/10.1177/2053951719897945 https://doi.org/10.1177/2053951719897945]. *McKelvey, Fenwick, Sophie Toupin, and Maurice Jones. 2024. «&#8239;Introduction&#8239;». In ''Northern Lights and Silicon Dreams: AI Governance in Canada (2011-2022)'', edited by Fenwick McKelvey, Johnathan Roberge, and Sophie Toupin, 7–30. Montreal, Canada: Shaping AI. [https://www.amo-oma.ca/wp-content/uploads/2024/04/ORA-CA-Policy.pdf https://www.amo-oma.ca/wp-content/uploads/2024/04/ORA-CA-Policy.pdf]. *Noble, Safiya Umoja. 2018. ''Algorithms of Oppression: How Search Engines Reinforce Racism''. New York: New York University Press. *O’Neil, Cathy. 2017. ''Weapons of Math Destruction: How Big Data Increases Inequality and Threatens Democracy''. New York: Crown. *Pride, David. 2023. «&#8239;CORE-GPT: Combining Open Access Research and AI for Credible, Trustworthy Question Answering&#8239;». ''CORE'' (blog). 17 mars 2023. [https://blog.core.ac.uk/2023/03/17/core-gpt-combining-open-access-research-and-ai-for-credible-trustworthy-question-answering/ https://blog.core.ac.uk/2023/03/17/core-gpt-combining-open-access-research-and-ai-for-credible-trustworthy-question-answering/]. *Redden, Joanna, Jessica Brand, and Vanesa Terzieva. 2020. «&#8239;Data Harm Record&#8239;». Data Justice Lab. 2020. [https://datajusticelab.org/data-harm-record/ https://datajusticelab.org/data-harm-record/]. *Redden, Joanna. 2024. «&#8239;Canada’s AI Legislation Misses the Mark&#8239;». ''Western News'' (blog). 12 avril 2024. [https://news.westernu.ca/2024/04/proposed-ai-legislation/ https://news.westernu.ca/2024/04/proposed-ai-legislation/]. *Roberts, Jennafer Shae, and Laura N. Montoya. 2023. «&#8239;In Consideration of Indigenous Data Sovereignty: Data Mining as a Colonial Practice&#8239;». In ''Proceedings of the Future Technologies Conference (FTC) 2023, Volume 2'', edited by Kohei Arai, 180–96. Cham: Springer Nature Switzerland. [https://doi.org/10.1007/978-3-031-47451-4_13 https://doi.org/10.1007/978-3-031-47451-4_13]. *Roberts, Jennafer Shae. 2024. «&#8239;In Consideration of Indigenous Data Sovereignty: Data Mining as a Colonial Practice&#8239;». ''Montreal AI Ethics Institute'' (blog). 23 janvier 2024. [https://montrealethics.ai/in-consideration-of-indigenous-data-sovereignty-data-mining-as-a-colonial-practice/ https://montrealethics.ai/in-consideration-of-indigenous-data-sovereignty-data-mining-as-a-colonial-practice/]. *Tucker, Joanna. 2022. «&#8239;Facing the Challenge of Digital Sustainability as Humanities Researchers&#8239;». ''Journal of the British Academy'', 10: 93–120. [https://doi.org/10.5871/jba/010.093 https://doi.org/10.5871/jba/010.093]. [[Catégorie:Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024 (livre)]] 82160whfmle38fshg3j66ot9abx36h4 Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/L’IA générative et l’édition savante 0 82377 744026 742852 2025-06-02T23:27:25Z LodestarChariot2 120009 /* Références */ 744026 wikitext text/x-wiki ''Ce rapport « Insights and Signals » a été rédigé par Brittany Amell (avec nos remerciements à John Willinsky, John Maxwell et William Bowen pour leurs commentaires et contributions), pour le Electronic Textual Cultures Laboratory et le partenariat Implementing New Knowledge Environments.'' ==Résumé== Les rapports'' «&#8239;Policy Insights and Signals&#8239;» ''scrutent l’horizon afin d’identifier et d’analyser les tendances émergentes et les signaux précurseurs susceptibles d’influer sur les orientations politiques futures en matière de libre accès et d’érudition ouverte et sociale. Ils ont tendance à mettre en évidence les changements dans la technologie, l’opinion et les sentiments du public, et/ou les changements réglementaires à l’intérieur et à l’extérieur du Canada. Tout comme les observations politiques de l’OSPO, les rapports sur les perspectives et les signaux visent à aider les partenaires à élaborer des stratégies proactives, réactives et tournées vers l’avenir. Ce rapport sur les perspectives et les signaux poursuit l'examen par l'OSPO de l'évolution du dialogue sur les implications de l'IA générative pour les bourses d'études ouvertes et l'édition en libre accès. «&#8239;L'IA générative fait référence à une classe d'algorithmes qui guident la création de divers types de contenu ([https://sites.broadviewpress.com/ai/talking/ Dobrin, 2023]). Parfois évoquée dans le même temps que [https://chatgpt.com/ ChatGPT], [https://openai.com/index/dall-e-2/ DALL-E 2] ou [https://gemini.google.com/ Gemini], nous commençons déjà à voir l'impact de l'IA générative sur l'édition savante, malgré son introduction relativement récente. Compte tenu de l'intérêt croissant pour les implications de l'IA générative pour le libre accès et la communication savante en général, ce rapport s'articule autour des discussions récentes sur les risques et les opportunités potentiels pour le secteur. Vous êtes intéressé par d’autres rapports «&#8239;Insights and Signals&#8239;» consacrés à l’IA ? Vous les trouverez [[Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Les agences fédérales de financement de la recherche annoncent un projet de lignes directrices sur l’utilisation de l’intelligence artificielle générative|ici]] ou [[Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Réponses à l’intelligence artificielle|ici]]. Les points abordés dans ce rapport sont les suivants : * [https://sr.ithaka.org/blog/generative-ai-and-scholarly-publishing/ Une annonce récente] d'Ithaka S+R concernant un nouveau projet de recherche axé sur l'IA générative et l'édition savante. * [https://scholarlykitchen.sspnet.org/2024/06/06/guest-post-doajs-role-in-supporting-trust-in-scholarly-journals-current-challenges-and-future-solutions/ Un article invité de] Shen et Ball (DOAJ) sur le Scholarly Kitchen concernant l'augmentation du nombre d'articles rétractés et la crise de confiance envers les revues en libre accès dans un contexte d'innovations en matière d'IA générative. * Une [https://www.coalition-s.org/towards-responsible-publishing/ proposition de] la cOAlition S concernant l'édition responsable * Les applications potentielles des principes FAIR à l'élaboration de politiques en réponse à l'IA générative, ainsi que le chevauchement entre ces principes et ceux mentionnés dans un [https://research-and-innovation.ec.europa.eu/document/2b6cf7e5-36ac-41cb-aab5-0d32050143dc_en récent guide sur l'utilisation responsable de l'IA] dans la recherche publié par la direction générale de la recherche et de l'innovation de la Commission européenne. * Le [https://doi.org/10.1590/SciELOPreprints.6799 Publication Facts Label] (PFL - également : [https://pkp.sfu.ca/2024/05/06/pkp-publication-facts-label/ ici]), ainsi qu'une [https://pkp.sfu.ca/2024/09/06/announcing-publication-facts-label-for-ojs/ annonce récente du Public Knowledge Project] concernant l'essai du PFL pour les revues fonctionnant avec OJS (v 3.3 ou plus). '''''Remarque : Nous vous présentons nos excuses en avance, car la plupart des sources mentionnées dans ce rapport sont disponibles en anglais uniquement.''''' ==Le groupe de recherche sur l'édition savante annonce un nouveau projet explorant les implications de l'IA générative== Le groupe de recherche [https://sr.ithaka.org/about/ Ithaka S+R] a récemment annoncé son [https://sr.ithaka.org/blog/generative-ai-and-scholarly-publishing/ intention d'entreprendre un nouveau projet de recherche axé sur l'IA générative et l'édition savante :] «&#8239;L'évolution rapide des besoins et des attentes des utilisateurs, le potentiel de l'IA générative pour atténuer les défis systémiques tenaces dans le secteur de l'édition savante, et la prise de conscience des risques que l'IA générative fait peser sur les connaissances des experts exigent que nous trouvions le temps de réfléchir en profondeur à ce que l'IA générative ''signifie ''pour l'édition savante commesecteur et à sa valeur en tant que composante de l'infrastructure partagée qui soutient la recherche et les communications savantes et scientifiques&#8239;» (Ruediger et Bergstrom, 2024). Ce projet examinera les opportunités, les risques et les implications stratégiques que l'IA générative pourrait avoir pour l'édition savante. Il s'appuie sur l'étude d'Ithaka S+R de 2023, «&#8239;[https://sr.ithaka.org/publications/the-second-digital-transformation-of-scholarly-publishing/ The Second Digital Transformation of Scholarly Publishing]&#8239;», qui examinait les besoins partagés en matière d'infrastructures de communication savante à la lumière des transformations numériques (Bergstrom, Rieger et Schonfeld, 2024). Comme l'écrivent Shen et Ball (2024) [https://scholarlykitchen.sspnet.org/2024/06/06/guest-post-doajs-role-in-supporting-trust-in-scholarly-journals-current-challenges-and-future-solutions/ dans leur article invité pour The Scholarly Kitchen,] bien que les menaces à la confiance et à la crédibilité aient toujours été au centre des préoccupations d'organisations telles que le Directory of Open Access Journals (DOAJ), ces menaces sont devenues encore plus urgentes. Constatant une augmentation du nombre d'articles rétractés, qui a atteint le chiffre record de 10 000 en 2023, Shen et Ball (2024) expliquent qu'il est devenu nécessaire de prendre des mesures supplémentaires pour préserver la confiance et la crédibilité à l'ère de l'IA générative. Pour le DOAJ, l'une de ces mesures a consisté à former une équipe chargée d'enquêter sur les «&#8239;cas présumés de pratiques douteuses&#8239;». Ces pratiques douteuses sont signalées soit par des membres de la communauté du DOAJ au sens large, soit par ceux qui participent au processus d'évaluation de la demande d'inclusion d'une revue dans le DOAJ. Une fois le signalement effectué, les membres de l'équipe examinent de près les articles publiés par la revue, ainsi que la composition et la compétence de son comité de rédaction, ses pratiques d'évaluation par les pairs et d'autres facteurs. «&#8239;Comme les pratiques prédatrices continuent d'évoluer, nos enquêtes deviennent de plus en plus complexes&#8239;», écrivent Shen et Ball (2024). «&#8239;Nous consultons parfois des experts externes en la matière pour obtenir leurs conseils. Rien qu'en 2023, nous avons mené un total de 409 enquêtes sur des revues et des éditeurs, dont beaucoup ont abouti à des exclusions du DOAJ d'au moins un an&#8239;». Aider les éditeurs et le public à évaluer la crédibilité d'une publication est une chose à laquelle les membres du Public Knowledge Project (PKP) ont beaucoup réfléchi. Le Publication Facts Label, conceptualisé à l'origine par John Willinsky (fondateur du Public Knowledge Project et présenté plus en détail [https://pkp.sfu.ca/2024/05/06/pkp-publication-facts-label/ ici] et [https://doi.org/10.1590/SciELOPreprints.6799 ici]), en est un exemple. Basé sur le Nutrition Facts Label - ce tableau bien connu que l'on trouve sur les emballages alimentaires au Canada et aux États-Unis - le Publication Facts Label (ou PFL en abrégé) regroupe huit normes en un guide facile à consulter que les plateformes d'édition peuvent utiliser pour présenter l'intégrité d'une publication à un large public (Willinsky et Pimental). PKP [https://pkp.sfu.ca/2024/09/06/announcing-publication-facts-label-for-ojs/ a récemment annoncé] la mise à l'essai du Publication Facts Label pour les revues utilisant l'Open Journal Systems (v 3.3 ou plus). En installant un plug-in, comme expliqué [https://pkp.sfu.ca/2024/09/06/announcing-publication-facts-label-for-ojs/ ici], le PFL peut être affiché automatiquement sur la page d'accueil d'un article. ==La cOAlition S élabore une proposition de publication responsable== Alors qu'Ithaka S+R se prépare à avancer dans son projet, la [https://www.coalition-s.org/about/ cOAlition S] (associée au [https://www.coalition-s.org/why-plan-s/ Plan S)] a terminé la phase de consultation de sa proposition intitulée «&#8239;[https://www.coalition-s.org/towards-responsible-publishing/ Vers une édition responsable]&#8239;». «&#8239;Poussés par le même ‹ devoir de diligence pour le bon fonctionnement du système scientifique › qui a inspiré le Plan S, les bailleurs de fonds qui forment la cOAlition S explorent maintenant une nouvelle vision de la communication savante ; une vision qui promet d'être plus efficace, plus abordable et plus équitable, pour finalement bénéficier à la société dans son ensemble&#8239;», écrivent Bodo Stern (chef des initiatives stratégiques à l'Howard Hughes Medical Institute) et Johan Rooryck (directeur exécutif de la cOAlition S) dans un [https://www.coalition-s.org/blog/introducing-the-towards-responsible-publishing-proposal-from-coalition-s/ billet de blog annonçant la proposition.] La cOAlition S a révisé la proposition sur la base des commentaires reçus entre novembre 2023 et avril 2024, et a partagé la proposition révisée avec une réunion des bailleurs de fonds du cOAlition S en juin. Les réactions à la proposition ont été rendues publiques par cOAlitionS [https://zenodo.org/records/11243942 ici.] La proposition «&#8239;Vers une publication responsable&#8239;» met en avant un ensemble de principes qui peuvent être utilisés pour guider les décisions concernant la manière de soutenir «&#8239;la diffusion de la recherche de manière responsable, équitable et durable&#8239;» (Stern et al. 2023, 2) - une phrase qui évoque les priorités clés nommées dans l[https://eua.eu/downloads/publications/eua%20os%20agenda.pdf 'Agenda de la science ouverte 2025 de l'Association européenne des universités]. L'Open Science Agenda de l'Association, qui a été publié en février 2022 en prévision de la conférence et de l'assemblée générale qui se tiendront en 2025-2026, énonce plusieurs priorités et objectifs, dont celui de faire en sorte que toutes les universités européennes fassent partie d'un «&#8239;écosystème d'édition savante juste&#8239;» d'ici à 2025 ([https://www.scienceeurope.org/media/yg3ho4tp/doa-conf-vinciane-gaillard.pdf Gaillard, 2022]). Vinciane Gaillard (directrice adjointe pour la recherche et l'innovation, Association européenne des universités) décrit un écosystème d'édition savante juste comme étant «&#8239;transparent, diversifié, économiquement abordable et durable, techniquement interopérable et piloté par la communauté des chercheurs et ses institutions par le biais de politiques coordonnées&#8239;» ([https://www.scienceeurope.org/media/yg3ho4tp/doa-conf-vinciane-gaillard.pdf diapositive 4)]. ==Elsevier lance ScopusAI== Au début de l'année 2024, [https://www.elsevier.com/about/press-releases/launch-of-scopus-ai-to-help-researchers-navigate-the-world-of-research Elsevier a annoncé le lancement de ScopusAI], un outil d'intelligence artificielle proposé aux institutions sur une base d'abonnement. Selon le site web d'Elsevier, [https://www.elsevier.com/products/scopus/scopus-ai ScopusAI] sert de «&#8239;guide expert&#8239;» que les chercheurs peuvent utiliser pour naviguer dans «&#8239;la vaste étendue de la connaissance humaine dans Scopus&#8239;». En plus de résumer la littérature disponible dans Scopus, l'outil est apparemment aussi capable de «&#8239;repérer&#8239;» ce qu'Elsevier appelle «&#8239;l'espace blanc&#8239;» dans la littérature afin que les chercheurs puissent ostensiblement mieux identifier les types de contributions qu'ils peuvent apporter. Il est inquiétant de constater que les résumés générés par l'outil renvoient à ce qu'Elsevier et l'outil ScopusAI considèrent comme des documents «&#8239;fondamentaux&#8239;» pour un sujet donné - il s'agit «&#8239;d'articles à fort impact qui sont le plus souvent cités par les articles utilisés dans les résumés&#8239;». Outre les décisions algorithmiques concernant les articles considérés comme fondamentaux, l'outil offre également la possibilité de «&#8239;découvrir des experts&#8239;» dans un domaine. Cependant, l'outil ne prend en compte que les articles et les profils qui figurent déjà dans Scopus qui est déjà connu comme une base de données qui surreprésente les universitaires et les chercheurs d'Europe, d'Océanie et d'Amérique du Nord par rapport aux universitaires et aux chercheurs d'autres régions du monde (Asubiaro et al. 2024). ==Questions et considérations clés== [[Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024/Réponses à l’intelligence artificielle|Les idées et les signaux décrits ci-dessus et ailleurs indiquent que l'intégration de l'IA générative dans l'édition savante]] présente à la fois des opportunités et des défis, ainsi que des implications significatives pour la qualité, l'intégrité et l'accessibilité des résultats de l'édition savante. Plusieurs questions se posent pour l'élaboration des politiques, notamment * Quelle est la place éventuelle de l'IA générative dans l'édition en libre accès ? * Comment les éditeurs en libre accès peuvent-ils guider l'utilisation responsable, éthique et crédible de l'IA générative ? Par exemple, John Willinsky (fondateur du Public Knowledge Project) nous a fait savoir que le PKP étudie activement la manière dont l'IA basée sur de grands modèles linguistiques pourrait contribuer à la durabilité de l'édition en libre accès : L'objectif principal de ce travail est d'établir si les LLM peuvent être suffisamment adaptés pour automatiser de manière fiable le balisage HTML et JATS XML des manuscrits des auteurs (étant donné que ce balisage nécessite actuellement des compétences techniques ou des paiements qui dépassent la capacité de la plupart des revues Diamond OA). Ce travail a atteint le stade initial de la preuve de concept, et les travaux se poursuivent sur sa valeur comparative (par rapport à d'autres outils) et sur les moyens d'intégrer et de maintenir un tel service de balisage dans le flux de travail éditorial. (Lisez l'intégralité du commentaire de John Willinsky ci-dessous). En plus de ces questions, les lecteurs pourraient également se demander quelles leçons et perspectives clés du mouvement de l'accès libre, du discours, de la recherche et de la littérature pourraient être appliquées au paysage en évolution de l'IA générative, le cas échéant. Par exemple, les principes FAIR pour la gestion et l'intendance des données ([https://www.nature.com/articles/sdata201618 Wilkinson et al. 2016]) - envisagés à l'origine comme un moyen de soutenir la réutilisation des données savantes en veillant à ce qu'elles soient trouvables, accessibles, interopérables et réutilisables - pourraient servir d'exemple. Les principes FAIR ont été réinterprétés pour s'appliquer aux logiciels, aux flux de travail, aux outils, aux algorithmes et, de plus en plus, aux modèles d'IA ([https://www.nature.com/articles/s41597-023-02298-6 Huerta et al. 2023]). Dans le même ordre d'idées, la Direction générale de la recherche et de l'innovation de la Commission européenne a récemment [https://research-and-innovation.ec.europa.eu/document/2b6cf7e5-36ac-41cb-aab5-0d32050143dc_en publié un ensemble de principes visant à orienter l'utilisation responsable de l'IA générative dans la recherche]. On peut dire que ces principes recoupent les principes FAIR, ce qui offre d'autres possibilités de réflexion. (Pour mémoire, les quatre principes clés sont la fiabilité, l'honnêteté, le respect et la responsabilité). ==Commentaires du partenariat INKE== ''Réponse de John Willinsky (fondateur, Public Knowledge Project) :'' <blockquote> Bien qu'il y ait des raisons de s'inquiéter des récentes avancées de l'IA, les universitaires ont également la responsabilité d'explorer les contributions et les avancées potentielles de l'IA pour la recherche et l'érudition. Depuis un certain temps, le [https://pkp.sfu.ca/ Public Knowledge Project] se tourne vers l'IA pour résoudre les problèmes urgents liés à l'équité et à la qualité des ressources dans les communications savantes, avec un succès limité. Il mène actuellement des recherches sur la capacité des grands modèles de langage à relever le défi de longue date que représente le développement d'un moyen durable pour les revues Diamond OA de publier dans les formats standard HTML et PDF, ainsi que d'exporter des fichiers en JATS XML. L'objectif principal de ce travail est d'établir si les LLM peuvent être suffisamment adaptés pour automatiser de manière fiable le balisage HTML et JATS XML des manuscrits des auteurs (étant donné que ce balisage nécessite actuellement des compétences techniques ou des paiements qui dépassent la capacité de la plupart des revues Diamond OA). Ce travail a atteint le stade initial de la preuve de concept, et les travaux se poursuivent sur sa valeur comparative (par rapport à d'autres outils) et sur les moyens d'intégrer et de maintenir un tel service de balisage dans le flux de travail éditorial. </blockquote> ==Références== *Ahari, Juni. 2024. «&#8239;Generative AI and Scholarly Publishing&#8239;». ''Ithaka S+R ''(blog). 23 avril 2024. [https://sr.ithaka.org/blog/generative-ai-and-scholarly-publishing/ https://sr.ithaka.org/blog/generative-ai-and-scholarly-publishing/]. *Asubiaro, Toluwase, Sodiq Onaolapo et David Mills. 2024. «&#8239;Regional disparities in Web of Science and Scopus journal coverage&#8239;». ''Scientometrics ''129 (3) : 1469–91. [https://doi.org/10.1007/s11192-024-04948-x https://doi.org/10.1007/s11192-024-04948-x]. *Bergstrom, Tracy, Oya Y. Rieger et Roger C. Schonfeld. 2024. «&#8239;The Second Digital Transformation of Scholarly Publishing: Strategic Context and Shared Infrastructure&#8239;». Ithaka S+R. [https://doi.org/10.18665/sr.320210 https://doi.org/10.18665/sr.320210]. *Chiarelli, Andrea, Ellie Cox, Rob Johnson, Ludo Waltman, Wolfgang Kaltenbrunner, André Brasil, Andrea Reyes Elizondo et Stephen Pinfield. 2024. «&#8239;Towards Responsible Publishing&#8239;» : Findings from a global stakeholder consultation. cOAlition S. Zenodo. [https://doi.org/10.5281/zenodo.11243942 https://doi.org/10.5281/zenodo.11243942]. *Directorate-General for Research and Innovation. 2024. «&#8239;Living Guidelines on the Responsible Use of Generative AI in Research (Version 1)&#8239;». Brussels: European Commission. [https://research-and-innovation.ec.europa.eu/document/download/2b6cf7e5-36ac-41cb-aab5-0d32050143dc_en?filename=ec_rtd_ai-guidelines.pdf https://research-and-innovation.ec.europa.eu/document/download/2b6cf7e5-36ac-41cb-aab5-0d32050143dc_en?filename=ec_rtd_ai-guidelines.pdf]. *Dobrin, Sidney I. 2023. «&#8239;Talking about Generative AI: A Guide for Educators&#8239;». Version 1. Broadview Press. [https://sites.broadviewpress.com/ai/talking/ https://sites.broadviewpress.com/ai/talking/]. *Gaillard, Vinciane. 2022. «&#8239;Encouraging/Supporting Sustainability in the Diamond Action Plan Community&#8239;». Presented at the 2022 Diamond Open Access Conference, September. [https://www.scienceeurope.org/media/yg3ho4tp/doa-conf-vinciane-gaillard.pdf https://www.scienceeurope.org/media/yg3ho4tp/doa-conf-vinciane-gaillard.pdf] *Huerta, E. A., Ben Blaiszik, L. Catherine Brinson, Kristofer E. Bouchard, Daniel Diaz, Caterina Doglioni, Javier M. Duarte, et al. 2023. «&#8239;FAIR for AI: An Interdisciplinary and International Community Building Perspective&#8239;». ''Scientific Data'' 10 (1): 487. [https://doi.org/10.1038/s41597-023-02298-6 https://doi.org/10.1038/s41597-023-02298-6]. *Shen, Cenyu, and Joanna Ball. 2024. «&#8239;DOAJ’s Role in Supporting Trust in Scholarly Journals: Current Challenges and Future Solutions&#8239;». ''The Scholarly Kitchen'' (blog). June 6, 2024. [https://scholarlykitchen.sspnet.org/2024/06/06/guest-post-doajs-role-in-supporting-trust-in-scholarly-journals-current-challenges-and-future-solutions/ https://scholarlykitchen.sspnet.org/2024/06/06/guest-post-doajs-role-in-supporting-trust-in-scholarly-journals-current-challenges-and-future-solutions/]. *Stern, Bodo, et Johan Rooryck. 2023. «&#8239;Introducing the ‘Towards Responsible Publishing’ Proposal from cOAlition S | Plan S&#8239;». sOApbox : A Plan S Blog (blog). 31 octobre 2023. [https://www.coalition-s.org/blog/introducing-the-towards-responsible-publishing-proposal-from-coalition-s/ https://www.coalition-s.org/blog/introducing-the-towards-responsible-publishing-proposal-from-coalition-s/]. *Stern, Bodo, Zoé Ancion, Andreas Björke, Ashley Farley, Marte Qvenild, Katharina Rieck, Jeroen Sondervan, et al. 2023. «&#8239;Towards Responsible Publishing : Seeking Input from the Research Community to a Draft Proposal from cOAlition S&#8239;», octobre. [https://doi.org/10.5281/ZENODO.8398480 https://doi.org/10.5281/ZENODO.8398480]. *Wilkinson, Mark D., Michel Dumontier, IJsbrand Jan Aalbersberg, Gabrielle Appleton, Myles Axton, Arie Baak, Niklas Blomberg, et al. 2016. «&#8239;The FAIR Guiding Principles for Scientific Data Management and Stewardship&#8239;». ''Scientific Data'' 3 (1): 160018. [https://doi.org/10.1038/sdata.2016.18 https://doi.org/10.1038/sdata.2016.18]. [[Catégorie:Extension : Observatoire des politiques sur les savoirs ouverts, 2021-2024 (livre)]] mxhex7mfrejqcti82j03uzv68a90tfz Fonctionnement d'un ordinateur/Les architectures à accumulateur 0 82386 744132 743532 2025-06-05T00:29:02Z Mewtow 31375 /* Les registres des anciennes architectures à accumulateur */ 744132 wikitext text/x-wiki Les architectures que nous avons vu précédemment dans ce cours disposent de registres pour les données, en plus du pointeur de pile, d'un ''program counter'', et de quelques autres. Elles sont appelées des '''architectures à registres''', terme qui trahit bien le fait qu'elles ont des registres généraux ou spécialisés pour stocker temporairement des données. Et si on leur a donné un nom, c'est parce qu'il existe des architectures qui ne sont pas dans cette catégorie. Il en existe plusieurs types, mais ce chapitre va se concentrer sur les '''architectures à accumulateur'''. [[File:Isaccumulator.png|vignette|Architecture à accumulateur.]] Les architectures à accumulateur sont centrées autour d'un registre architectural appelé l''''accumulateur'''. Il est utilisé pour toutes les opérations arithmétiques dyadiques, où il sert à la fois de source et de destination. Toutes les instructions dyadiques sont de type ''load-op'' : une opérande est lue depuis l'accumulateur, le second opérande est lu depuis la mémoire RAM, le résultat de l'instruction est automatiquement mémorisé dans l'accumulateur. Les instructions monadiques peuvent utiliser un opérande dans l'accumulateur, ou dans la mémoire RAM, les deux sont théoriquement possibles. La conséquence est que le nombre d'accès mémoire est drastiquement diminué : de 3 par instructions sur une architecture mémoire-mémoire, on passe à seulement un avec un accumulateur. Les opérations dyadiques ont besoin d'un seul accès mémoire pour lire la seconde opérande, les opérations monadique en font aussi un seul pour lire leur unique opérande. {|class="wikitable" |- ! Classe d'architecture ! Nombre d'accès mémoire par opération dyadique |- |- ! Architecture à accumulateur | Un accès mémoire par instruction, pour lire la seconde opérande |- ! Architecture à registres | Zéro si les opérandes sont dans les registres, un pour les opérations ''load-op'', LOAD et STORE. |} ==Le jeu d'instruction des architectures à accumulateur sans registres d'indice== L'accumulateur est adressé grâce au mode d'adressage implicite, de même que le résultat de l'opération. Par contre, les autres opérandes sont localisés avec d'autres modes d'adressage, et lues en mémoire RAM. Le résultat ainsi qu'un des opérandes sont adressés de façon implicite car dans l'accumulateur, seule la seconde opérande étant adressée directement. Grâce à l'accumulateur, une instruction ne fait qu'un seul accès mémoire maximum, ce qui rend le processeur très facile à implémenter. ===Les registres des anciennes architectures à accumulateur=== [[File:IBM 701console.jpg|vignette|IBM 701, console extérieure.]] Les architectures à accumulateurs sont apparues dès les débuts de l'informatique, un peu après les architectures mémoire-mémoire. Les deux ont existé conjointement pendant un temps. A l'époque, les ordinateurs étaient gigantesques, ils prenaient une pièce de bâtiment entière dans le pire des cas, une armoire entière dans le meilleur. Les ordinateurs de l'époque étaient surtout utilisés pour du calcul scientifique ou des tâches d’ingénierie demandant beaucoup de calcul, rarement pour de la compatibilité. Les nombres flottants n'étaient pas encore apparus. A la place, les ordinateurs de l'époque géraient des nombres entiers de grande taille, de 30 bits ou plus. En conséquence, l'accumulateur faisait facilement 30 à 60 bits. Par exemple, les ordinateurs de la Série scientifique IBM 700/7000 géraient des entiers de 36 bits, l’accumulateur faisait 38 bits : 36 bits plus deux bits pour les débordements. Au passage, de tels processeurs utilisaient l'adressage par mot, et non par byte. [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] Pour donner un exemple, le ''Manchester Baby'', le tout premier ordinateur à programme enregistré en mémoire, était une architecture à accumulateur. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 adresses de 32 bits, fabriquée avec des tubes Williams (abordés dans une annexe à la fin du cours). Le programme devait tenir dans la RAM, avec une instruction par adresse maximum, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 servait à indiquer où se trouvent les opérandes en RAM, les 16 restants sont inutilisés. Le processeur avait un registre accumulateur de 32 bits, un ''program counter'' et un registre d'instruction. Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. Historiquement, les premières architectures à accumulateur ne contenaient aucun autre registre que l'accumulateur. Ce n'est que dans les années 60 que de nombreuses architectures à accumulateur ont ajouté un second '''registre pour les multiplication/divisions'''. Un exemple est celui de l'IBM 701, qui incorporait un registre accumulateur de 38 bits et un registre multiplieur de 36 bits. Le registre mémorise le multiplieur lors d'une opération de multiplication. Il mémorise donc un opérande, pas le résultat. Il peut aussi décaler le multiplieur vers la droite/gauche, ce qui est utile pour exécuter la multiplication. C'est ce qui est fait sur l'IBM 7094. Une autre possibilité est que ce registre mémorise une partie du résultat de l'opération. Pour rappel, le résultat d'une multiplication/division est codé sur deux fois de bits que ses opérandes. Par exemple, multipliez deux opérandes de 30 bits, vous obtiendrez un résultat de 60 bits. Les 30 bits de poids faible du résultat vont dans l'accumulateur, les 30 bits de poids fort vont dans ce second registre. Les architectures à accumulateur parfois un '''registre pour le pointeur de pile''', utilisé pour gérer les fonctions/procédures. Les architectures à accumulateurs supportaient une pile d'adresse de retour, souvent une pile d'appel. Mais pour cela, il fallait mémoriser le pointeur de pile dans le processeur, ce qui demandait un registre dédié. ===L'adressage indirect avec l'accumulateur=== Les instructions LOAD et STORE existent bel et bien sur les architectures à accumulateur, mais n'ont pas les mêmes modes d'adressages. L'instruction LOAD copie une donnée de la RAM vers l'accumulateur, l'instruction STORE copie l'accumulateur dans une adresse. Les deux instructions n'ont pas besoin d'adresser l'accumulateur, qui est adressé de manière implicite, juste de préciser l'adresse à lire/écrire. Les architectures à accumulateur supportaient souvent le mode d'adressage indirect mémoire. Un exemple est celui des ordinateurs Data General Nova, qui sont des architectures à accumulateur et qui supportaient ce mode d'adressage. Les deux instructions LOAD et STORE existaient en deux versions, distinguées par un bit d'indirection. Si ce bit est à 0 dans l'opcode, alors l'instruction utilise le mode d'adressage absolu normal : l'adresse intégrée dans l'instruction est celle de la donnée. Mais s'il est à 1, alors l'adresse intégrée dans l'instruction est celle du pointeur. Cependant, la présence de l'accumulateur permettait d'utiliser l'adressage indirect à registre, pour gérer les pointeurs. Pour rappel, avec le mode d'adressage indirect à registre, l'adresse à lire/écrire est dans un registre. Ici, l'adresse à lire/écrire est prise dans l'accumulateur, seul registre disponible pour. L'adressage indirect est plus simple à implémenter pour l'instruction LOAD, car elle prend un seul opérande : l'adresse à lire. L'adresse à lire est placée dans l'accumulateur, la donnée lue est elle aussi chargée dans l'accumulateur. Pour l'instruction STORE, il faut fournir deux opérandes, l'adresse et la donnée à écrire, ce qui peut poser problème. Mais au pire, il est toujours possible d'utiliser l'adressage absolu ou indirect mémoire : l'adresse est dans l'instruction, la donnée à écrire dans l'accumulateur. ===L'encodage des instructions=== Sur une architecture à accumulateur l'encodage d'une instruction dyadique est assez simple, vu que l'accumulateur est adressé implicitement. La seconde opérande est localisée soit par une adresse mémoire (adressage absolu), soit est une constante (adressage immédiat). L'adresse mémoire est généralement assez longue, plus que l'opcode. {|class="wikitable" |+ Encodage d'une instruction dyadique |- ! rowspan="2" | Opcode | Adresse mémoire (adressage absolu) |- | Constante (adressage immédiat) |} L'encodage d'une instruction monadique est similaire. Si l'opérande est lue depuis la mémoire RAM, alors l'instruction est encodée comme une instruction dyadique. Il en est de même pour les instructions qui copient une constante dans l'accumulateur. Par contre, si l'opérande est dans l'accumulateur, alors il y a juste besoin d'encoder l'opcode. La majorité des instructions a besoin de préciser une adresse, rares sont celles qui s'en passent. Au vu de cet encodage, les architectures à accumulateur sont qualifiées d''''architectures à une adresse''' par abus de langage. Il est intéressant de contraster leur encodage avec les architectures à registres. Les architectures à registre doivent encoder deux opérandes en plus de l'opcode, avec éventuellement où enregistrer le résultat sur les architectures 3-adresses. Par contre, les opérandes sont généralement des noms de registre, ce qui prend moins de place qu'une adresse mémoire. A la rigueur, les instructions avec une constante immédiate prennent un peu plus de place, car elles doivent encoder un nom de registre en plus de la constante et de l'opcode. Les instructions ''load-op'' des processeurs CISC sont un peu dans le même cas, sauf qu'il faut remplacer la constante par une adresse, qui a généralement la même taille. Les instructions sont donc en moyenne plus courte sur les processeurs à registre, du fait de la présence de registres. ==La micro-architecture des architectures à accumulateur sans registres d'indice== L'organisation interne d'une architecture à accumulateur est très différente de celle des processeurs à registre. Elle est plus ou moins la même pour tous ces processeurs, le point important étant que le chemin de données se résume à une ALU, un registre accumulateur et le bus de données. L'ALU est reliée au registre accumulateur, ainsi qu'au bus de données pour lire la seconde opérande, comme illustré ci-dessous. [[File:Accumulator.png|centre|vignette|upright=2|Accumulateur.]] ===L'unité de calcul et l'accumulateur=== Pour simplifier l'implémentation, le résultat est mémorisé dans un registre en sortie de l'unité de calcul. La raison est qu'on ne veut pas altérer l'accumulateur tant que le résultat final n'est pas totalement calculé. Rappelons que l'ALU ne fournit pas un résultat d'un seul bloc, mais que certains bits arrivent avant les autres, typiquement les bits de poids faible. Si le résultat était écrit dans l'accumulateur directement, il écraserait des bits de l’opérande en cours d'utilisation, ce qui fausserait le résultat. [[File:Accumulateur avec registre de sortie.png|centre|vignette|upright=2|Accumulateur avec registre de sortie]] Une autre solution utilisait un registre entre l'accumulateur et l'unité de calcul, appelé l’'''''accumulator latch'''''. Il remplace le registre en sortie de l'ALU, dans le sens où il permet d'écrire dans l'accumulateur sans effacer l'opérande, pendant que l’opération est en cours dans l'ALU. L'accumulateur est copié dans l’''accumulator latch'', avant que l'ALU démarre ses calculs. L'opérande est donc maintenue même si on commence à écrire le résultat dans l'accumulateur. Sur le 8085 d'Intel, l’''accumulator latch'' peut être initialisé avec une constante prédéfinie, ce qui permet d'implémenter certaines instructions très facilement. Par exemple, il peut être initialisé à 0, ce qui permet d'implémenter les instructions MOV et INC (incrémentation). Un MOV est équivalent à faire un OU entre le registre lu et 0. Une instruction INC initialise l'entrée de retenue de l'unité de calcul à 1, puis ajoute 0. La décrémentation est implémentée de la même manière, sauf que l’''accumulator latch'' est initialisé à -2 pour compenser l'entrée de retenue à 1. De plus, pour supporter les conversion de décimal à BCD, l’''accumulator latch'' peut être initialisé avec les constantes 0x00, 0x06, 0x60, or 0x66. L'''accumulator latch'' est relié à divers fils de commande provenant de l'unité de contrôle, qui décide quelle valeur d'initialisation utiliser en fonction de l'instruction décodée. [[File:Accumulator latch.png|centre|vignette|upright=2|Accumulator latch]] [[File:Chemin de données à un seul bus.png|vignette|Chemin de données à un seul bus]] De même, la seconde opérande, celle lue sur le bus de données, est mémorisée dans un registre en amont de l'ALU. C'était notamment très utile si le processeur utilisait une ALU plus courte que les opérandes, avec par exemple une ALU 4 bits pour un CPU 8 bits. Les anciens processeurs à accumulateur de type ''mainframe'' utilisaient des opérandes de grande taille, du genre 36 ou 48 bits, ce qui avait des conséquences sur l'unité de calcul utilisée, ainsi que sur la communication avec la mémoire. Il arrivait que de tels processeurs utilisaient des ALU sérielles, ou du moins octet-sérielles, plutôt qu'une véritable ALU 36 bits. Nous verrons aussi que c'est très utile sur les processeurs à accumulateur avec un bus interne unique, dans la suite du chapitre. ===La micro-architecture des architectures à accumulateur avec instructions LOAD/STORE=== Nous venons de voir comment est implémenté l'unité de calcul et l'accumulateur, et comment le tout est relié au bus de données. Mais cela ne permet que d'avoir un processeur à accumulateur rudimentaire, qui ne gére que des instructions arithmétiques et logiques. Il faut aussi gérer le cas des opérations LOAD/STORE et des modes d'adressages associés, mais c'est le séquenceur qui s'en occupe. Avec l'adressage absolu, les instructions LOAD et STORE ne font que connecter l'accumulateur au bus de données. L'instruction STORE nécessite de connecter l'accumulateur au bus de données, de manière à ce que le transfert des données se fasse de l'accumulateur vers le bus de données. L'instruction LOAD s'implémente de la même manière, sauf que le sens de transfert est inversé. Cependant, il existe une optimisation qui permet d'implémenter l'instruction LOAD sans ajouter de circuits. Pour cela, il suffit que l'unité de calcul gére les opérations ''pass through'', à savoir des opérations qui se contentent de recopier un opérande sur la sortie. Ici, l'idée est de recopier l'opérande provenant du bus de données. [[File:Architecture à accumulateur, microarchitecture.png|centre|vignette|upright=2|Architecture à accumulateur, microarchitecture]] Pour gérer nativement l'adressage indirect à registre, il suffit de connecter l'accumulateur au bus d'adresse. Le plus simple est d'ajouter un multiplexeur, comme illustré ci-dessous. La donnée lue est copiée dans l'accumulateur, ce qui fait qu'il vaut mieux utiliser un registre d’interfaçage, l'accumulateur n'étant pas utilisable à la fois pour le bus d'adresse et de données. [[File:Adressage indirect sur une architecture à accumulateur.png|centre|vignette|upright=2|Adressage indirect sur une architecture à accumulateur]] Pour finir, voyons comment le pointeur de pile et le ''program counter'' sont implémentés. Les architectures à accumulateur ont souvent des adresses de taille différente des données, ce qui fait qu'il vaut mieux utiliser un circuit incrémenteur dédié pour incrémenter le ''program counter'', plutôt que de l'incrémenter via l'unité de calcul. Les architectures à accumulateur ont parfois un pointeur de pile, qui gère une pile d'adresse de retour, pas une vraie pile d'appel. Aussi, le pointeur de pile est censé être incrémenté et décrémenté, pas plus. Pas d'addition ou de soustraction pour gérer des cadres de pile. Là encore, c'est la solution de l'incrémenteur séparé qui est retenue. Pour économiser des transistors, il n'y a qu'un seul incrémenteur partagé pour les deux. ==Les architectures à accumulateur à registres d'indice== Les architectures à accumulateur décrites dans la section précédente sont capables de faire de l'adressage indirect, mais n'incluent pas les modes d'adressage base + indice et absolus indicés, qui prennent une adresse et y ajoute un indice. Il s'agit des toutes premières architectures à accumulateur, comme les premiers ordinateurs IBM ou le fameux PDP-8. Mais par la suite, les processeurs à accumulateurs ont inclus un support des modes d'adressages indicés, grâce à des '''registres d'indice'''. ===Les registres d'indice=== Les registres d'indice stockent des indices de tableaux. Ils permettaient de supporter deux modes d'adressage : * Le '''mode d'adressage absolu indicé''' où une adresse fixe est additionnée à un indice variable. L'adresse fixe est intégrée dans l'instruction (adressage absolu), l'indice est dans un registre d'indice. * Le '''mode d'adressage base + indice''', où l'adresse est dans l'accumulateur et l'indice dans le registre d'indice. Les processeurs à accumulateur supportaient souvent des variantes des modes d'adressage précédents, où le registre d'indice était automatiquement incrémenté ou décrémenté à chaque utilisation. Au départ, ces processeurs n'utilisaient qu'un seul registre d'indice qui se comportait comme un second accumulateur spécialisé dans les calculs d'adresses mémoire. Le processeur supportait de nouvelles instructions qui utilisaient ce registre d'indice de façon implicite. Mais avec le temps, les processeurs finirent par incorporer plusieurs de ces registres. Les instructions de lecture ou d'écriture devaient alors préciser quel registre d'indice utiliser, en précisant un nom de registre d'indice, un numéro de registre d'indice. Il faut préciser que les registres d'indice ont une taille bien plus petite que l'accumulateur. Ils mémorisent des indices codés sur 16 bits ou moins, alors que l'accumulateur faisait typiquement 36 à 48 bits, parfois plus. La taille classique sur les anciens ''mainframes'' était de 15 bits, parfois moins. Il n'était pas rare de tomber sur des registres d'indice de 8 ou 9 bits. Leur petite taille rendait leur implémentation matérielle peu couteuse. Et c'est ce qui explique qu'ils étaient préférés à l'usage d'un second accumulateur. Un exemple est le cas du processeur Motorola 6809, un processeur à accumulateur qui contient deux registres d'indices nommés X et Y. L'accumulateur est noté D et fait 16 bits, il peut être parfois géré comme deux accumulateurs séparés A et B de 8 bits chacun. Il contenait aussi deux pointeurs de pile, l'un pour les programmes, l'autre pour le système d'exploitation, ainsi qu'un ''program counter''. Le registre de page était utilisé pour l'adressage absolu, comme vu dans le chapitre sur les modes d'adressage. [[File:6809 Internal Registers.svg|centre|vignette|upright=2|6809 Internal Registers]] Les processeurs IBM avaient autrefois plusieurs registres d'indice. Par exemple, l'IBM 704 avait trois registres d'indice de 15 bits. Leur contenu était soustrait de l'adresse absolue. Une instruction pouvait utiliser plusieurs registres d'indice pour adresser son opérande. Toute instruction utilisait trois bits pour sélectionner les registres d'indice utilisés. Fait assez original, lorsque plusieurs registres d'indice sont sélectionnés, le processeur n'additionne pas les trois registres à l'adresse de base. À la place, il fait un OU bit à bit entre les registres d'indice sélectionnés, et additionne le résultat à l'adresse. Les processeurs IBM à accumulateur ont fait ça sur toute la gamme IBM 700/7000, pour des raisons de compatibilité. Les processeurs suivants avaient 7 registres d'indices, mais conservaient les trois bits pour adresser les registres d'indices. Ils pouvaient fonctionner dans deux modes. Le premier mode est plus intuitif : les trois bits précisent un registre d'indice parmi les 7, qui est additionné avec l'adresse absolue. La valeur zéro indique qu'aucun registre d'indice n'est utilisé, ce qui explique qu'il y a 7 registres d'indice et non 8. Un second mode, compatible avec l'IBM 704, fait un OU logique entre les registres d'indice sélectionnés. Seuls les trois premiers registres d'indices peuvent être sélectionnés dans ce mode. Il y a deux instructions pour changer de mode : une pour passer en mode compatible, l'autre pour le quitter pour l'autre mode. Quelques rares processeurs à registres généraux ont utilisés des registres d'indice, en plus des registres généraux. Ce qui fait l'association que nous avons faite entre registres d'indice et architectures à accumulateur est imparfait, bien que solide sur le principe. Un exemple d'architecture de ce type sont les architectures de la série UNIVAC 1100/2200. Ils disposaient de 128 registres, qui étaient mappés en mémoire à partir de l'adresse mémoire 0, la majorité étant inaccessibles par le programmeur. Ils regroupaient 12 registres accumulateurs, 11 registres d'indice et 4 registres hybrides qui pouvaient servir soit de registre d'indice, soit de registres accumulateurs. ===La micro-architecture des architectures à accumulateur avec registres d'indice=== La présence de registres d'indice modifie grandement l'implémentation du processeur. En effet, il faut rajouter un banc de registre pour les registres d'indice. Le banc de registre est monoport, car on a besoin de lire ou d'écrire un indice à la fois. Et il faut aussi potentiellement rajouter de quoi faire les calculs d'adresse. Deux solutions sont possibles : une ALU dédiée aux calculs d'adresse, une seule ALU pour toutes les opérations. Dans le premier cas, il y a une ALU séparée associée aux registres d'indice. L'ALU et les registres d'indice sont placés en sortie du séquenceur, en-dehors du chemin de données, la sortie de l'ALU est directement connectée au bus d'adresse. L'unité de calcul d'adresse peut être utilisée pour incrémenter le ''program counter''. Un défaut de cette approche est qu'elle ne gère pas l'adresse indirect à registre. [[File:Chemin de données sans support des pointeurs, avec adressage absolu indicé.png|centre|vignette|upright=2|Chemin de données sans support des pointeurs, avec adressage absolu indicé]] Une autre option utilise un bus interne, qui interconnecte tout le chemin de données. Dans sa version la plus simple, il est relié à l'accumulateur, l'unité de calcul, le banc de registre d'indice et le bus de données. Avec cette solution, l'ALU est utilisé à la fois pour calculer les adresses et pour les instructions de calcul. En reliant le bus interne au bus d'adresse à travers un multiplexeur, on gère naturellement les adressages indirects. [[File:Architecture à accumulateur avec registres associés.png|centre|vignette|upright=2.5|Architecture à accumulateur avec registres associés]] Il faut noter que sur les architectures Von Neumann, le séquenceur est relié à ce bus interne. En effet, charger une instruction demande de passer par le bus mémoire, donc par l’intermédiaire de ce bus internet. Le ''program counter'' est envoyé sur ce bus pour lire l'instruction, puis l'instruction lue est recopiée dans le registre d'instruction. Le chargement d'une instruction est donc géré comme une lecture des plus classiques. De plus, cela permet d'incrémenter le ''program counter'' au niveau de l'unité de calcul entière. Le ''program counter'' est envoyé sur le bus interne, incrémenté par l'ALU, puis le résultat est recopié dans le ''program counter'' via le bus interne. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] ==Les processeurs bi-accumulateurs : le Motorola 6800== Le Motorola 6800 était un processeur 8 bits qui gérait des adresses de 16 bits. Il contenait deux accumulateurs nommés A et B, de 8 bits chacun. Il disposait aussi d'un registre d'indice, d'un pointeur de pile et d'un ''program counter'', tous les trois de 16 bits. Le registre d'état regroupait 6 bits, qu'on ne détaillera pas ici. [[File:MC6800 Processor Diagram.png|centre|vignette|upright=2|Interface et registres du MC6800.]] La présence des deux accumulateurs impactait surtout les instructions dyadiques. Les instructions monadiques avaient juste à préciser où se trouvait l'opérande : soit en RAM, soit dans le premier accumulateur, soit dans le second. Pour les opérations dyadiques, la gestion était totalement différente. En théorie, le premier opérande est dans un accumulateur, soit A, soit B. La seconde opérande vient soit de l'autre accumulateur, soit de la mémoire RAM. Et selon les instructions, tout variait. Pour l'addition, il y avait trois instructions. Les deux premières additionnaient un opérande provenant de la mémoire avec un accumulateur. L'instruction ADDA sélectionnait le premier accumulateur, l'instruction ADDB sélectionnait le second accumulateur. Mais une troisième instruction, l’instruction ABA, permettait d'additionner le contenu des deux accumulateurs. Pour les autres opérations, il n'était pas possible d'utiliser les deux accumulateurs en même temps. La seule possibilité était de faire une opération entre un accumulateur et un opérande venant de la mémoire. Toutes les instructions étaient en double, avec une copie par accumulateur. Par exemple, l'instruction ANDA faisait un ET entre l’accumulateur A et l'opérande mémoire, l'instruction ANDB faisait pareil avec l'accumulateur B. ==Les architectures hybrides registres-accumulateur== Il a existé quelques architectures qui étaient des hybrides entre architectures à accumulateur et architecture à registre. Elles ont servi de transition entre les deux, durant les années 80-90. Elles avaient un accumulateur unique couplé à un banc de registres généraux. Par exemple, les premiers processeurs Intel 8 bits étaient des processeurs hybrides-accumulateur. Lles CPU Intel 8 bits disposaient de 7 registres de 8 bits nommés A, B, C, D, E, F, H, L, SP. Ils correspondent respectivement à : * l'accumulateur A ; * six registres nommés B, C, D, E, H et L ; * le registre d'état F ; * le pointeur de pile SP. Sur ces processeurs, les instructions dyadiques devaient mettre leur premier opérande dans l'accumulateur, la seconde provenait soit des registres, soit de la RAM, soit d'une constante immédiate. Les opérations monadiques pouvaient lire leur opérande depuis l'accumulateur, les autres registres ou la RAM, tout était permis. Les registres d'indices disparaissaient sur ces architectures, en théorie. Les registres généraux pouvaient être utilisés comme registre d'indice ou pour stocker des opérandes, ils étaient assez versatiles pour servir de registres d'indices. La présence de registres a de nombreux avantages, comparé aux architectures à accumulateur pures. Les instructions arithmétiques sont plus rapide, lire un registre étant plus rapide qu'un accès RAM. Les performances sont donc augmentées. De plus, les instructions arithmétiques utilisant ces registres sont plus courtes : pas besoin d'encoder une adresse mémoire, un nom de registre suffit. Vu que les processeurs de l’époque avaient des instructions de taille variable, cela améliorait la densité de code. La microarchitecture de ces processeurs est très similaire à celle d'un processeur avec des registres d'indices. La seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Le banc de registre est systématiquement monoport, car il n'avait aucune raison d'être multiport. Pour les instructions dyadiques, seules à lire deux opérandes, il ne servait que pour la seconde opérande, la première était lue depuis l'accumulateur. Les processeurs hybrides registre-accumulateur se classent en deux types principaux : ceux qui ont un seul bus interne, et ceux qui en ont deux. Le premier cas est identique à celui vu précédemment pour les architectures à accumulateur avec registres d'indice, à la seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Afin de gérer l'adressage indirect à registre, le bus interne est connecté aux deux registres d’interfaçage mémoire. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] Notons que cela permet aussi d'implémenter facilement les branchements indirects, car le bus interne permet d'échanger des adresses entre ''program counter'' et banc de registre. De même, il est possible d'utiliser l'ALU pour gérer les branchements indirects., en plus de l'utiliser pour incrémenter le ''program counter''. [[File:Single bus organization.jpg|centre|vignette|upright=2|Single bus organization]] Une autre solution utilisait deux bus internes : un connecté au bus de données, un autre relié au bus d'adresse. Le bus de commande mémoire était lui commandé par le séquenceur, l'unité de contrôle. L'intermédiaire entre ces deux bus était le banc de registre, ainsi que les autres registres. Le banc de registre était connecté aux deux bus interne, avec un port de lecture relié au bus d'adresse, un port de lecture-écriture relié au bus de données. Le port de lecture était utilisé pour l'adressage indirect, l'autre l'était pour le reste. [[File:Proz1-e.png|centre|vignette|upright=2|Intérieur d'un processeur.]] L'organisation à deux bus simplifiait la gestion du ''program counter'' et le chargement des instructions. Le ''program counter'' était soit séparé du banc de registre, soit placé dans le banc de registre. Les deux solutions étaient utilisés, tout dépend du processeur. Il faut noter que si le ''program counter'' est intégré au banc de registres, alors la microarchitecture du processeur est bien plus simple. L'envoi du ''program counter'' sur le bus d'adresse utilise le port de lecture relié au bus d'adresse, qui sert aussi pour l'adressage indirect. L'économie de circuits, sans compter la simplicité d'implémentation que cela implique, explique sans doute que la technique a été utilisée sur quelques processeurs anciens. Le ''program counter'' était généralement incrémenté par l'ALU, ce qui explique qu'il soit connecté au bus interne pour les données. La connexion est aussi utile pour gérer les branchements indirects, qui copient un registre dans le ''program counter'', ainsi que les branchements relatifs (addition dans l'ALU), voire les branchements directs (l'adresse vers laquelle brancher est envoyée en entrée de l'ALU et propagée en sortie avec une opération ''pass through''). [[File:Connexion du program counter sur les bus avec PC dans le banc de registres.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC dans le banc de registres]] ===Les registres d'interruption avec un processeur hybride-accumulateur : l'exemple du Z80=== Un exemple de processeur registre-accumulateur à deux bus interne est le Z80, un processeur fortement inspiré des CPU Intel 8 bits. Il a un jeu d'instruction similaire, mais a diverses améliorations par rapport au design original. Notamment, le processeur a des registres séparés pour les interruptions. Sur le Z80, les registres généraux sont dupliqués avec 6 registres pour les interruptions et 6 registres pour les programmes autres. Leur copie pour les interruptions sont nommées B', C', D', E', H', L'. Les 12 registres sont placés dans le banc de registre, ce qui implique que le fenêtrage de registres est utilisé pour gérer la séparation entre registre d'interruption et normaux. Il faut noter que l'accumulateur et le registre d'état sont aussi dupliqués, leurs copies étant nommées A' et F'. Mais leur duplication se fait autrement que par fenêtrage de registre. En plus des registres précédents, le Z80 incorporait deux registres d'indice nommés X et Y, ainsi qu'un pointeur de pile SP et un ''program counter'' PC. Ils n'étaient pas dupliqués pour les interruptions. Les registres d'indice étaient reliés à une unité de calcul d'adresse. L'unité de calcul d'adresse prenait deux opérandes : un indice, et une adresse mémoire provenant soit du banc de registre, soit de l'accumulateur. En clair, l'unité de calcul d'adresse faisait le lien entre les deux bus internet : le bus de données interne en entrée, le bus d'adresse en sortie. À l'intérieur du processeur, tous les registres étaient regroupés dans un banc de registre unique, sauf les accumulateurs, les registres d'état et le ''program counter''. Bien que ce ne soit pas indiqué sur le schéma ci-dessous, le ''program counter'' est séparé du banc de registre, alors que le pointeur de pile est dedans. Le compteur IR est lui associé au ''program counter'', il est sortit du banc de registre. Le Z80 utilise lui aussi un incrémenteur séparé de l'ALU, qui est utilisé pour mettre à jour le ''program counter'', le pointeur de pile et un compteur de rafraichissement mémoire nommé IR sur le Z80 (pour rappel, le rafraichissement mémoire demande de balayer la mémoire d'adresse en adresse et été fait par le CPU à l'époque). De plus, il est utilisé pour les instructions INC et DEC qui incrémentent une opérande de 16 bits obtenue en combinant deux registres de 8 bits. En clair, l'incrémenteur du ''program counter'' a été réutilisé de beaucoup de manières originales. [[File:Z80 arch.svg|centre|vignette|upright=3|Microarchitecture du Z80.]] Le Z80 incorporait des instructions pour échanger le contenu des deux ensembles de registres, accumulateur inclus. Elles permettaient d'utiliser les registres d'interruption pour les programmes et réciproquement. En clair, cela doublait le nombre de registres si les interruptions n'étaient pas utilisées. * L'instruction EXX échangeait les deux fenêtres de registres généraux : les registres B, C, D, E, H et L devenaient les registres B', C', D', E', H' et L' et inversement. * L'instruction EX échangeait l'accumulateur et le registre d'état : les registres A,F devenait A',F' et inversement. Le fenêtrage de registre était modifié par l'instruction EXX, qui échangeait les deux fenêtres de registres. Pour l'implémenter, une bascule était ajouté au processeur, appelons-la la bascule INT. Elle était relié au bus d'adresse du banc de registre, dont elle mémorisait le bit de poids fort. L'instruction EXX inversait la valeur de la bascule INT. Il est aussi possible d'échanger le contenu des registres D,E et H,L avec une instruction dédiée, ce qui est là encore fait par deux bascules : une pour les registres D,E et une autre pour les registres H,L. Pour l'accumulateur et le registre d'état, le choix entre registre normal et registre d'interruption se faisait là encore par une seconde bascule appelée la bascule A. La bascule est reliée à un multiplexeur et un démultiplexeur, qui permet de choisir quel accumulateur relier à l'unité de calcul. L'instruction EX inverse le contenu de la bascule A. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=L'unité de contrôle | prevText=L'unité de contrôle | next=Les processeurs 8 bits et moins | nextText=Les processeurs 8 bits et moins }} </noinclude> klq0txs8rhwgaj87u5zrf9cgnh71g23 744133 744132 2025-06-05T00:30:23Z Mewtow 31375 /* Les registres des anciennes architectures à accumulateur */ 744133 wikitext text/x-wiki Les architectures que nous avons vu précédemment dans ce cours disposent de registres pour les données, en plus du pointeur de pile, d'un ''program counter'', et de quelques autres. Elles sont appelées des '''architectures à registres''', terme qui trahit bien le fait qu'elles ont des registres généraux ou spécialisés pour stocker temporairement des données. Et si on leur a donné un nom, c'est parce qu'il existe des architectures qui ne sont pas dans cette catégorie. Il en existe plusieurs types, mais ce chapitre va se concentrer sur les '''architectures à accumulateur'''. [[File:Isaccumulator.png|vignette|Architecture à accumulateur.]] Les architectures à accumulateur sont centrées autour d'un registre architectural appelé l''''accumulateur'''. Il est utilisé pour toutes les opérations arithmétiques dyadiques, où il sert à la fois de source et de destination. Toutes les instructions dyadiques sont de type ''load-op'' : une opérande est lue depuis l'accumulateur, le second opérande est lu depuis la mémoire RAM, le résultat de l'instruction est automatiquement mémorisé dans l'accumulateur. Les instructions monadiques peuvent utiliser un opérande dans l'accumulateur, ou dans la mémoire RAM, les deux sont théoriquement possibles. La conséquence est que le nombre d'accès mémoire est drastiquement diminué : de 3 par instructions sur une architecture mémoire-mémoire, on passe à seulement un avec un accumulateur. Les opérations dyadiques ont besoin d'un seul accès mémoire pour lire la seconde opérande, les opérations monadique en font aussi un seul pour lire leur unique opérande. {|class="wikitable" |- ! Classe d'architecture ! Nombre d'accès mémoire par opération dyadique |- |- ! Architecture à accumulateur | Un accès mémoire par instruction, pour lire la seconde opérande |- ! Architecture à registres | Zéro si les opérandes sont dans les registres, un pour les opérations ''load-op'', LOAD et STORE. |} ==Le jeu d'instruction des architectures à accumulateur sans registres d'indice== L'accumulateur est adressé grâce au mode d'adressage implicite, de même que le résultat de l'opération. Par contre, les autres opérandes sont localisés avec d'autres modes d'adressage, et lues en mémoire RAM. Le résultat ainsi qu'un des opérandes sont adressés de façon implicite car dans l'accumulateur, seule la seconde opérande étant adressée directement. Grâce à l'accumulateur, une instruction ne fait qu'un seul accès mémoire maximum, ce qui rend le processeur très facile à implémenter. ===Les registres des anciennes architectures à accumulateur=== [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] Les architectures à accumulateurs sont apparues dès les débuts de l'informatique. Le tout premier ordinateur à programme enregistré en mémoire, le ''Manchester Baby'', était une architecture à accumulateur. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 adresses de 32 bits, fabriquée avec des tubes Williams (abordés dans une annexe à la fin du cours). Le programme devait tenir dans la RAM, avec une instruction par adresse maximum, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 servait à indiquer où se trouvent les opérandes en RAM, les 16 restants sont inutilisés. Le processeur avait un registre accumulateur de 32 bits, un ''program counter'' et un registre d'instruction. Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. [[File:IBM 701console.jpg|vignette|IBM 701, console extérieure.]] Les architectures à accumulateur étaient communes dans les années 50-60. A l'époque, les ordinateurs étaient gigantesques, ils prenaient une pièce de bâtiment entière dans le pire des cas, une armoire entière dans le meilleur. Les ordinateurs de l'époque étaient surtout utilisés pour du calcul scientifique ou des tâches d’ingénierie demandant beaucoup de calcul, rarement pour de la compatibilité. Les nombres flottants n'étaient pas encore apparus. A la place, les ordinateurs de l'époque géraient des nombres entiers de grande taille, de 30 bits ou plus. En conséquence, l'accumulateur faisait facilement 30 à 60 bits. Par exemple, les ordinateurs de la Série scientifique IBM 700/7000 géraient des entiers de 36 bits, l’accumulateur faisait 38 bits : 36 bits plus deux bits pour les débordements. Au passage, de tels processeurs utilisaient l'adressage par mot, et non par byte. Historiquement, les premières architectures à accumulateur ne contenaient aucun autre registre que l'accumulateur. Ce n'est que dans les années 60 que de nombreuses architectures à accumulateur ont ajouté un second '''registre pour les multiplication/divisions'''. Un exemple est celui de l'IBM 701, qui incorporait un registre accumulateur de 38 bits et un registre multiplieur de 36 bits. Le registre mémorise le multiplieur lors d'une opération de multiplication. Il mémorise donc un opérande, pas le résultat. Il peut aussi décaler le multiplieur vers la droite/gauche, ce qui est utile pour exécuter la multiplication. C'est ce qui est fait sur l'IBM 7094. Une autre possibilité est que ce registre mémorise une partie du résultat de l'opération. Pour rappel, le résultat d'une multiplication/division est codé sur deux fois de bits que ses opérandes. Par exemple, multipliez deux opérandes de 30 bits, vous obtiendrez un résultat de 60 bits. Les 30 bits de poids faible du résultat vont dans l'accumulateur, les 30 bits de poids fort vont dans ce second registre. Les architectures à accumulateur parfois un '''registre pour le pointeur de pile''', utilisé pour gérer les fonctions/procédures. Les architectures à accumulateurs supportaient une pile d'adresse de retour, souvent une pile d'appel. Mais pour cela, il fallait mémoriser le pointeur de pile dans le processeur, ce qui demandait un registre dédié. ===L'adressage indirect avec l'accumulateur=== Les instructions LOAD et STORE existent bel et bien sur les architectures à accumulateur, mais n'ont pas les mêmes modes d'adressages. L'instruction LOAD copie une donnée de la RAM vers l'accumulateur, l'instruction STORE copie l'accumulateur dans une adresse. Les deux instructions n'ont pas besoin d'adresser l'accumulateur, qui est adressé de manière implicite, juste de préciser l'adresse à lire/écrire. Les architectures à accumulateur supportaient souvent le mode d'adressage indirect mémoire. Un exemple est celui des ordinateurs Data General Nova, qui sont des architectures à accumulateur et qui supportaient ce mode d'adressage. Les deux instructions LOAD et STORE existaient en deux versions, distinguées par un bit d'indirection. Si ce bit est à 0 dans l'opcode, alors l'instruction utilise le mode d'adressage absolu normal : l'adresse intégrée dans l'instruction est celle de la donnée. Mais s'il est à 1, alors l'adresse intégrée dans l'instruction est celle du pointeur. Cependant, la présence de l'accumulateur permettait d'utiliser l'adressage indirect à registre, pour gérer les pointeurs. Pour rappel, avec le mode d'adressage indirect à registre, l'adresse à lire/écrire est dans un registre. Ici, l'adresse à lire/écrire est prise dans l'accumulateur, seul registre disponible pour. L'adressage indirect est plus simple à implémenter pour l'instruction LOAD, car elle prend un seul opérande : l'adresse à lire. L'adresse à lire est placée dans l'accumulateur, la donnée lue est elle aussi chargée dans l'accumulateur. Pour l'instruction STORE, il faut fournir deux opérandes, l'adresse et la donnée à écrire, ce qui peut poser problème. Mais au pire, il est toujours possible d'utiliser l'adressage absolu ou indirect mémoire : l'adresse est dans l'instruction, la donnée à écrire dans l'accumulateur. ===L'encodage des instructions=== Sur une architecture à accumulateur l'encodage d'une instruction dyadique est assez simple, vu que l'accumulateur est adressé implicitement. La seconde opérande est localisée soit par une adresse mémoire (adressage absolu), soit est une constante (adressage immédiat). L'adresse mémoire est généralement assez longue, plus que l'opcode. {|class="wikitable" |+ Encodage d'une instruction dyadique |- ! rowspan="2" | Opcode | Adresse mémoire (adressage absolu) |- | Constante (adressage immédiat) |} L'encodage d'une instruction monadique est similaire. Si l'opérande est lue depuis la mémoire RAM, alors l'instruction est encodée comme une instruction dyadique. Il en est de même pour les instructions qui copient une constante dans l'accumulateur. Par contre, si l'opérande est dans l'accumulateur, alors il y a juste besoin d'encoder l'opcode. La majorité des instructions a besoin de préciser une adresse, rares sont celles qui s'en passent. Au vu de cet encodage, les architectures à accumulateur sont qualifiées d''''architectures à une adresse''' par abus de langage. Il est intéressant de contraster leur encodage avec les architectures à registres. Les architectures à registre doivent encoder deux opérandes en plus de l'opcode, avec éventuellement où enregistrer le résultat sur les architectures 3-adresses. Par contre, les opérandes sont généralement des noms de registre, ce qui prend moins de place qu'une adresse mémoire. A la rigueur, les instructions avec une constante immédiate prennent un peu plus de place, car elles doivent encoder un nom de registre en plus de la constante et de l'opcode. Les instructions ''load-op'' des processeurs CISC sont un peu dans le même cas, sauf qu'il faut remplacer la constante par une adresse, qui a généralement la même taille. Les instructions sont donc en moyenne plus courte sur les processeurs à registre, du fait de la présence de registres. ==La micro-architecture des architectures à accumulateur sans registres d'indice== L'organisation interne d'une architecture à accumulateur est très différente de celle des processeurs à registre. Elle est plus ou moins la même pour tous ces processeurs, le point important étant que le chemin de données se résume à une ALU, un registre accumulateur et le bus de données. L'ALU est reliée au registre accumulateur, ainsi qu'au bus de données pour lire la seconde opérande, comme illustré ci-dessous. [[File:Accumulator.png|centre|vignette|upright=2|Accumulateur.]] ===L'unité de calcul et l'accumulateur=== Pour simplifier l'implémentation, le résultat est mémorisé dans un registre en sortie de l'unité de calcul. La raison est qu'on ne veut pas altérer l'accumulateur tant que le résultat final n'est pas totalement calculé. Rappelons que l'ALU ne fournit pas un résultat d'un seul bloc, mais que certains bits arrivent avant les autres, typiquement les bits de poids faible. Si le résultat était écrit dans l'accumulateur directement, il écraserait des bits de l’opérande en cours d'utilisation, ce qui fausserait le résultat. [[File:Accumulateur avec registre de sortie.png|centre|vignette|upright=2|Accumulateur avec registre de sortie]] Une autre solution utilisait un registre entre l'accumulateur et l'unité de calcul, appelé l’'''''accumulator latch'''''. Il remplace le registre en sortie de l'ALU, dans le sens où il permet d'écrire dans l'accumulateur sans effacer l'opérande, pendant que l’opération est en cours dans l'ALU. L'accumulateur est copié dans l’''accumulator latch'', avant que l'ALU démarre ses calculs. L'opérande est donc maintenue même si on commence à écrire le résultat dans l'accumulateur. Sur le 8085 d'Intel, l’''accumulator latch'' peut être initialisé avec une constante prédéfinie, ce qui permet d'implémenter certaines instructions très facilement. Par exemple, il peut être initialisé à 0, ce qui permet d'implémenter les instructions MOV et INC (incrémentation). Un MOV est équivalent à faire un OU entre le registre lu et 0. Une instruction INC initialise l'entrée de retenue de l'unité de calcul à 1, puis ajoute 0. La décrémentation est implémentée de la même manière, sauf que l’''accumulator latch'' est initialisé à -2 pour compenser l'entrée de retenue à 1. De plus, pour supporter les conversion de décimal à BCD, l’''accumulator latch'' peut être initialisé avec les constantes 0x00, 0x06, 0x60, or 0x66. L'''accumulator latch'' est relié à divers fils de commande provenant de l'unité de contrôle, qui décide quelle valeur d'initialisation utiliser en fonction de l'instruction décodée. [[File:Accumulator latch.png|centre|vignette|upright=2|Accumulator latch]] [[File:Chemin de données à un seul bus.png|vignette|Chemin de données à un seul bus]] De même, la seconde opérande, celle lue sur le bus de données, est mémorisée dans un registre en amont de l'ALU. C'était notamment très utile si le processeur utilisait une ALU plus courte que les opérandes, avec par exemple une ALU 4 bits pour un CPU 8 bits. Les anciens processeurs à accumulateur de type ''mainframe'' utilisaient des opérandes de grande taille, du genre 36 ou 48 bits, ce qui avait des conséquences sur l'unité de calcul utilisée, ainsi que sur la communication avec la mémoire. Il arrivait que de tels processeurs utilisaient des ALU sérielles, ou du moins octet-sérielles, plutôt qu'une véritable ALU 36 bits. Nous verrons aussi que c'est très utile sur les processeurs à accumulateur avec un bus interne unique, dans la suite du chapitre. ===La micro-architecture des architectures à accumulateur avec instructions LOAD/STORE=== Nous venons de voir comment est implémenté l'unité de calcul et l'accumulateur, et comment le tout est relié au bus de données. Mais cela ne permet que d'avoir un processeur à accumulateur rudimentaire, qui ne gére que des instructions arithmétiques et logiques. Il faut aussi gérer le cas des opérations LOAD/STORE et des modes d'adressages associés, mais c'est le séquenceur qui s'en occupe. Avec l'adressage absolu, les instructions LOAD et STORE ne font que connecter l'accumulateur au bus de données. L'instruction STORE nécessite de connecter l'accumulateur au bus de données, de manière à ce que le transfert des données se fasse de l'accumulateur vers le bus de données. L'instruction LOAD s'implémente de la même manière, sauf que le sens de transfert est inversé. Cependant, il existe une optimisation qui permet d'implémenter l'instruction LOAD sans ajouter de circuits. Pour cela, il suffit que l'unité de calcul gére les opérations ''pass through'', à savoir des opérations qui se contentent de recopier un opérande sur la sortie. Ici, l'idée est de recopier l'opérande provenant du bus de données. [[File:Architecture à accumulateur, microarchitecture.png|centre|vignette|upright=2|Architecture à accumulateur, microarchitecture]] Pour gérer nativement l'adressage indirect à registre, il suffit de connecter l'accumulateur au bus d'adresse. Le plus simple est d'ajouter un multiplexeur, comme illustré ci-dessous. La donnée lue est copiée dans l'accumulateur, ce qui fait qu'il vaut mieux utiliser un registre d’interfaçage, l'accumulateur n'étant pas utilisable à la fois pour le bus d'adresse et de données. [[File:Adressage indirect sur une architecture à accumulateur.png|centre|vignette|upright=2|Adressage indirect sur une architecture à accumulateur]] Pour finir, voyons comment le pointeur de pile et le ''program counter'' sont implémentés. Les architectures à accumulateur ont souvent des adresses de taille différente des données, ce qui fait qu'il vaut mieux utiliser un circuit incrémenteur dédié pour incrémenter le ''program counter'', plutôt que de l'incrémenter via l'unité de calcul. Les architectures à accumulateur ont parfois un pointeur de pile, qui gère une pile d'adresse de retour, pas une vraie pile d'appel. Aussi, le pointeur de pile est censé être incrémenté et décrémenté, pas plus. Pas d'addition ou de soustraction pour gérer des cadres de pile. Là encore, c'est la solution de l'incrémenteur séparé qui est retenue. Pour économiser des transistors, il n'y a qu'un seul incrémenteur partagé pour les deux. ==Les architectures à accumulateur à registres d'indice== Les architectures à accumulateur décrites dans la section précédente sont capables de faire de l'adressage indirect, mais n'incluent pas les modes d'adressage base + indice et absolus indicés, qui prennent une adresse et y ajoute un indice. Il s'agit des toutes premières architectures à accumulateur, comme les premiers ordinateurs IBM ou le fameux PDP-8. Mais par la suite, les processeurs à accumulateurs ont inclus un support des modes d'adressages indicés, grâce à des '''registres d'indice'''. ===Les registres d'indice=== Les registres d'indice stockent des indices de tableaux. Ils permettaient de supporter deux modes d'adressage : * Le '''mode d'adressage absolu indicé''' où une adresse fixe est additionnée à un indice variable. L'adresse fixe est intégrée dans l'instruction (adressage absolu), l'indice est dans un registre d'indice. * Le '''mode d'adressage base + indice''', où l'adresse est dans l'accumulateur et l'indice dans le registre d'indice. Les processeurs à accumulateur supportaient souvent des variantes des modes d'adressage précédents, où le registre d'indice était automatiquement incrémenté ou décrémenté à chaque utilisation. Au départ, ces processeurs n'utilisaient qu'un seul registre d'indice qui se comportait comme un second accumulateur spécialisé dans les calculs d'adresses mémoire. Le processeur supportait de nouvelles instructions qui utilisaient ce registre d'indice de façon implicite. Mais avec le temps, les processeurs finirent par incorporer plusieurs de ces registres. Les instructions de lecture ou d'écriture devaient alors préciser quel registre d'indice utiliser, en précisant un nom de registre d'indice, un numéro de registre d'indice. Il faut préciser que les registres d'indice ont une taille bien plus petite que l'accumulateur. Ils mémorisent des indices codés sur 16 bits ou moins, alors que l'accumulateur faisait typiquement 36 à 48 bits, parfois plus. La taille classique sur les anciens ''mainframes'' était de 15 bits, parfois moins. Il n'était pas rare de tomber sur des registres d'indice de 8 ou 9 bits. Leur petite taille rendait leur implémentation matérielle peu couteuse. Et c'est ce qui explique qu'ils étaient préférés à l'usage d'un second accumulateur. Un exemple est le cas du processeur Motorola 6809, un processeur à accumulateur qui contient deux registres d'indices nommés X et Y. L'accumulateur est noté D et fait 16 bits, il peut être parfois géré comme deux accumulateurs séparés A et B de 8 bits chacun. Il contenait aussi deux pointeurs de pile, l'un pour les programmes, l'autre pour le système d'exploitation, ainsi qu'un ''program counter''. Le registre de page était utilisé pour l'adressage absolu, comme vu dans le chapitre sur les modes d'adressage. [[File:6809 Internal Registers.svg|centre|vignette|upright=2|6809 Internal Registers]] Les processeurs IBM avaient autrefois plusieurs registres d'indice. Par exemple, l'IBM 704 avait trois registres d'indice de 15 bits. Leur contenu était soustrait de l'adresse absolue. Une instruction pouvait utiliser plusieurs registres d'indice pour adresser son opérande. Toute instruction utilisait trois bits pour sélectionner les registres d'indice utilisés. Fait assez original, lorsque plusieurs registres d'indice sont sélectionnés, le processeur n'additionne pas les trois registres à l'adresse de base. À la place, il fait un OU bit à bit entre les registres d'indice sélectionnés, et additionne le résultat à l'adresse. Les processeurs IBM à accumulateur ont fait ça sur toute la gamme IBM 700/7000, pour des raisons de compatibilité. Les processeurs suivants avaient 7 registres d'indices, mais conservaient les trois bits pour adresser les registres d'indices. Ils pouvaient fonctionner dans deux modes. Le premier mode est plus intuitif : les trois bits précisent un registre d'indice parmi les 7, qui est additionné avec l'adresse absolue. La valeur zéro indique qu'aucun registre d'indice n'est utilisé, ce qui explique qu'il y a 7 registres d'indice et non 8. Un second mode, compatible avec l'IBM 704, fait un OU logique entre les registres d'indice sélectionnés. Seuls les trois premiers registres d'indices peuvent être sélectionnés dans ce mode. Il y a deux instructions pour changer de mode : une pour passer en mode compatible, l'autre pour le quitter pour l'autre mode. Quelques rares processeurs à registres généraux ont utilisés des registres d'indice, en plus des registres généraux. Ce qui fait l'association que nous avons faite entre registres d'indice et architectures à accumulateur est imparfait, bien que solide sur le principe. Un exemple d'architecture de ce type sont les architectures de la série UNIVAC 1100/2200. Ils disposaient de 128 registres, qui étaient mappés en mémoire à partir de l'adresse mémoire 0, la majorité étant inaccessibles par le programmeur. Ils regroupaient 12 registres accumulateurs, 11 registres d'indice et 4 registres hybrides qui pouvaient servir soit de registre d'indice, soit de registres accumulateurs. ===La micro-architecture des architectures à accumulateur avec registres d'indice=== La présence de registres d'indice modifie grandement l'implémentation du processeur. En effet, il faut rajouter un banc de registre pour les registres d'indice. Le banc de registre est monoport, car on a besoin de lire ou d'écrire un indice à la fois. Et il faut aussi potentiellement rajouter de quoi faire les calculs d'adresse. Deux solutions sont possibles : une ALU dédiée aux calculs d'adresse, une seule ALU pour toutes les opérations. Dans le premier cas, il y a une ALU séparée associée aux registres d'indice. L'ALU et les registres d'indice sont placés en sortie du séquenceur, en-dehors du chemin de données, la sortie de l'ALU est directement connectée au bus d'adresse. L'unité de calcul d'adresse peut être utilisée pour incrémenter le ''program counter''. Un défaut de cette approche est qu'elle ne gère pas l'adresse indirect à registre. [[File:Chemin de données sans support des pointeurs, avec adressage absolu indicé.png|centre|vignette|upright=2|Chemin de données sans support des pointeurs, avec adressage absolu indicé]] Une autre option utilise un bus interne, qui interconnecte tout le chemin de données. Dans sa version la plus simple, il est relié à l'accumulateur, l'unité de calcul, le banc de registre d'indice et le bus de données. Avec cette solution, l'ALU est utilisé à la fois pour calculer les adresses et pour les instructions de calcul. En reliant le bus interne au bus d'adresse à travers un multiplexeur, on gère naturellement les adressages indirects. [[File:Architecture à accumulateur avec registres associés.png|centre|vignette|upright=2.5|Architecture à accumulateur avec registres associés]] Il faut noter que sur les architectures Von Neumann, le séquenceur est relié à ce bus interne. En effet, charger une instruction demande de passer par le bus mémoire, donc par l’intermédiaire de ce bus internet. Le ''program counter'' est envoyé sur ce bus pour lire l'instruction, puis l'instruction lue est recopiée dans le registre d'instruction. Le chargement d'une instruction est donc géré comme une lecture des plus classiques. De plus, cela permet d'incrémenter le ''program counter'' au niveau de l'unité de calcul entière. Le ''program counter'' est envoyé sur le bus interne, incrémenté par l'ALU, puis le résultat est recopié dans le ''program counter'' via le bus interne. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] ==Les processeurs bi-accumulateurs : le Motorola 6800== Le Motorola 6800 était un processeur 8 bits qui gérait des adresses de 16 bits. Il contenait deux accumulateurs nommés A et B, de 8 bits chacun. Il disposait aussi d'un registre d'indice, d'un pointeur de pile et d'un ''program counter'', tous les trois de 16 bits. Le registre d'état regroupait 6 bits, qu'on ne détaillera pas ici. [[File:MC6800 Processor Diagram.png|centre|vignette|upright=2|Interface et registres du MC6800.]] La présence des deux accumulateurs impactait surtout les instructions dyadiques. Les instructions monadiques avaient juste à préciser où se trouvait l'opérande : soit en RAM, soit dans le premier accumulateur, soit dans le second. Pour les opérations dyadiques, la gestion était totalement différente. En théorie, le premier opérande est dans un accumulateur, soit A, soit B. La seconde opérande vient soit de l'autre accumulateur, soit de la mémoire RAM. Et selon les instructions, tout variait. Pour l'addition, il y avait trois instructions. Les deux premières additionnaient un opérande provenant de la mémoire avec un accumulateur. L'instruction ADDA sélectionnait le premier accumulateur, l'instruction ADDB sélectionnait le second accumulateur. Mais une troisième instruction, l’instruction ABA, permettait d'additionner le contenu des deux accumulateurs. Pour les autres opérations, il n'était pas possible d'utiliser les deux accumulateurs en même temps. La seule possibilité était de faire une opération entre un accumulateur et un opérande venant de la mémoire. Toutes les instructions étaient en double, avec une copie par accumulateur. Par exemple, l'instruction ANDA faisait un ET entre l’accumulateur A et l'opérande mémoire, l'instruction ANDB faisait pareil avec l'accumulateur B. ==Les architectures hybrides registres-accumulateur== Il a existé quelques architectures qui étaient des hybrides entre architectures à accumulateur et architecture à registre. Elles ont servi de transition entre les deux, durant les années 80-90. Elles avaient un accumulateur unique couplé à un banc de registres généraux. Par exemple, les premiers processeurs Intel 8 bits étaient des processeurs hybrides-accumulateur. Lles CPU Intel 8 bits disposaient de 7 registres de 8 bits nommés A, B, C, D, E, F, H, L, SP. Ils correspondent respectivement à : * l'accumulateur A ; * six registres nommés B, C, D, E, H et L ; * le registre d'état F ; * le pointeur de pile SP. Sur ces processeurs, les instructions dyadiques devaient mettre leur premier opérande dans l'accumulateur, la seconde provenait soit des registres, soit de la RAM, soit d'une constante immédiate. Les opérations monadiques pouvaient lire leur opérande depuis l'accumulateur, les autres registres ou la RAM, tout était permis. Les registres d'indices disparaissaient sur ces architectures, en théorie. Les registres généraux pouvaient être utilisés comme registre d'indice ou pour stocker des opérandes, ils étaient assez versatiles pour servir de registres d'indices. La présence de registres a de nombreux avantages, comparé aux architectures à accumulateur pures. Les instructions arithmétiques sont plus rapide, lire un registre étant plus rapide qu'un accès RAM. Les performances sont donc augmentées. De plus, les instructions arithmétiques utilisant ces registres sont plus courtes : pas besoin d'encoder une adresse mémoire, un nom de registre suffit. Vu que les processeurs de l’époque avaient des instructions de taille variable, cela améliorait la densité de code. La microarchitecture de ces processeurs est très similaire à celle d'un processeur avec des registres d'indices. La seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Le banc de registre est systématiquement monoport, car il n'avait aucune raison d'être multiport. Pour les instructions dyadiques, seules à lire deux opérandes, il ne servait que pour la seconde opérande, la première était lue depuis l'accumulateur. Les processeurs hybrides registre-accumulateur se classent en deux types principaux : ceux qui ont un seul bus interne, et ceux qui en ont deux. Le premier cas est identique à celui vu précédemment pour les architectures à accumulateur avec registres d'indice, à la seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Afin de gérer l'adressage indirect à registre, le bus interne est connecté aux deux registres d’interfaçage mémoire. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] Notons que cela permet aussi d'implémenter facilement les branchements indirects, car le bus interne permet d'échanger des adresses entre ''program counter'' et banc de registre. De même, il est possible d'utiliser l'ALU pour gérer les branchements indirects., en plus de l'utiliser pour incrémenter le ''program counter''. [[File:Single bus organization.jpg|centre|vignette|upright=2|Single bus organization]] Une autre solution utilisait deux bus internes : un connecté au bus de données, un autre relié au bus d'adresse. Le bus de commande mémoire était lui commandé par le séquenceur, l'unité de contrôle. L'intermédiaire entre ces deux bus était le banc de registre, ainsi que les autres registres. Le banc de registre était connecté aux deux bus interne, avec un port de lecture relié au bus d'adresse, un port de lecture-écriture relié au bus de données. Le port de lecture était utilisé pour l'adressage indirect, l'autre l'était pour le reste. [[File:Proz1-e.png|centre|vignette|upright=2|Intérieur d'un processeur.]] L'organisation à deux bus simplifiait la gestion du ''program counter'' et le chargement des instructions. Le ''program counter'' était soit séparé du banc de registre, soit placé dans le banc de registre. Les deux solutions étaient utilisés, tout dépend du processeur. Il faut noter que si le ''program counter'' est intégré au banc de registres, alors la microarchitecture du processeur est bien plus simple. L'envoi du ''program counter'' sur le bus d'adresse utilise le port de lecture relié au bus d'adresse, qui sert aussi pour l'adressage indirect. L'économie de circuits, sans compter la simplicité d'implémentation que cela implique, explique sans doute que la technique a été utilisée sur quelques processeurs anciens. Le ''program counter'' était généralement incrémenté par l'ALU, ce qui explique qu'il soit connecté au bus interne pour les données. La connexion est aussi utile pour gérer les branchements indirects, qui copient un registre dans le ''program counter'', ainsi que les branchements relatifs (addition dans l'ALU), voire les branchements directs (l'adresse vers laquelle brancher est envoyée en entrée de l'ALU et propagée en sortie avec une opération ''pass through''). [[File:Connexion du program counter sur les bus avec PC dans le banc de registres.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC dans le banc de registres]] ===Les registres d'interruption avec un processeur hybride-accumulateur : l'exemple du Z80=== Un exemple de processeur registre-accumulateur à deux bus interne est le Z80, un processeur fortement inspiré des CPU Intel 8 bits. Il a un jeu d'instruction similaire, mais a diverses améliorations par rapport au design original. Notamment, le processeur a des registres séparés pour les interruptions. Sur le Z80, les registres généraux sont dupliqués avec 6 registres pour les interruptions et 6 registres pour les programmes autres. Leur copie pour les interruptions sont nommées B', C', D', E', H', L'. Les 12 registres sont placés dans le banc de registre, ce qui implique que le fenêtrage de registres est utilisé pour gérer la séparation entre registre d'interruption et normaux. Il faut noter que l'accumulateur et le registre d'état sont aussi dupliqués, leurs copies étant nommées A' et F'. Mais leur duplication se fait autrement que par fenêtrage de registre. En plus des registres précédents, le Z80 incorporait deux registres d'indice nommés X et Y, ainsi qu'un pointeur de pile SP et un ''program counter'' PC. Ils n'étaient pas dupliqués pour les interruptions. Les registres d'indice étaient reliés à une unité de calcul d'adresse. L'unité de calcul d'adresse prenait deux opérandes : un indice, et une adresse mémoire provenant soit du banc de registre, soit de l'accumulateur. En clair, l'unité de calcul d'adresse faisait le lien entre les deux bus internet : le bus de données interne en entrée, le bus d'adresse en sortie. À l'intérieur du processeur, tous les registres étaient regroupés dans un banc de registre unique, sauf les accumulateurs, les registres d'état et le ''program counter''. Bien que ce ne soit pas indiqué sur le schéma ci-dessous, le ''program counter'' est séparé du banc de registre, alors que le pointeur de pile est dedans. Le compteur IR est lui associé au ''program counter'', il est sortit du banc de registre. Le Z80 utilise lui aussi un incrémenteur séparé de l'ALU, qui est utilisé pour mettre à jour le ''program counter'', le pointeur de pile et un compteur de rafraichissement mémoire nommé IR sur le Z80 (pour rappel, le rafraichissement mémoire demande de balayer la mémoire d'adresse en adresse et été fait par le CPU à l'époque). De plus, il est utilisé pour les instructions INC et DEC qui incrémentent une opérande de 16 bits obtenue en combinant deux registres de 8 bits. En clair, l'incrémenteur du ''program counter'' a été réutilisé de beaucoup de manières originales. [[File:Z80 arch.svg|centre|vignette|upright=3|Microarchitecture du Z80.]] Le Z80 incorporait des instructions pour échanger le contenu des deux ensembles de registres, accumulateur inclus. Elles permettaient d'utiliser les registres d'interruption pour les programmes et réciproquement. En clair, cela doublait le nombre de registres si les interruptions n'étaient pas utilisées. * L'instruction EXX échangeait les deux fenêtres de registres généraux : les registres B, C, D, E, H et L devenaient les registres B', C', D', E', H' et L' et inversement. * L'instruction EX échangeait l'accumulateur et le registre d'état : les registres A,F devenait A',F' et inversement. Le fenêtrage de registre était modifié par l'instruction EXX, qui échangeait les deux fenêtres de registres. Pour l'implémenter, une bascule était ajouté au processeur, appelons-la la bascule INT. Elle était relié au bus d'adresse du banc de registre, dont elle mémorisait le bit de poids fort. L'instruction EXX inversait la valeur de la bascule INT. Il est aussi possible d'échanger le contenu des registres D,E et H,L avec une instruction dédiée, ce qui est là encore fait par deux bascules : une pour les registres D,E et une autre pour les registres H,L. Pour l'accumulateur et le registre d'état, le choix entre registre normal et registre d'interruption se faisait là encore par une seconde bascule appelée la bascule A. La bascule est reliée à un multiplexeur et un démultiplexeur, qui permet de choisir quel accumulateur relier à l'unité de calcul. L'instruction EX inverse le contenu de la bascule A. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=L'unité de contrôle | prevText=L'unité de contrôle | next=Les processeurs 8 bits et moins | nextText=Les processeurs 8 bits et moins }} </noinclude> 2odvhhyeh8t9l81rfo0n5r1jfacl500 744134 744133 2025-06-05T00:30:48Z Mewtow 31375 /* Les registres des anciennes architectures à accumulateur */ 744134 wikitext text/x-wiki Les architectures que nous avons vu précédemment dans ce cours disposent de registres pour les données, en plus du pointeur de pile, d'un ''program counter'', et de quelques autres. Elles sont appelées des '''architectures à registres''', terme qui trahit bien le fait qu'elles ont des registres généraux ou spécialisés pour stocker temporairement des données. Et si on leur a donné un nom, c'est parce qu'il existe des architectures qui ne sont pas dans cette catégorie. Il en existe plusieurs types, mais ce chapitre va se concentrer sur les '''architectures à accumulateur'''. [[File:Isaccumulator.png|vignette|Architecture à accumulateur.]] Les architectures à accumulateur sont centrées autour d'un registre architectural appelé l''''accumulateur'''. Il est utilisé pour toutes les opérations arithmétiques dyadiques, où il sert à la fois de source et de destination. Toutes les instructions dyadiques sont de type ''load-op'' : une opérande est lue depuis l'accumulateur, le second opérande est lu depuis la mémoire RAM, le résultat de l'instruction est automatiquement mémorisé dans l'accumulateur. Les instructions monadiques peuvent utiliser un opérande dans l'accumulateur, ou dans la mémoire RAM, les deux sont théoriquement possibles. La conséquence est que le nombre d'accès mémoire est drastiquement diminué : de 3 par instructions sur une architecture mémoire-mémoire, on passe à seulement un avec un accumulateur. Les opérations dyadiques ont besoin d'un seul accès mémoire pour lire la seconde opérande, les opérations monadique en font aussi un seul pour lire leur unique opérande. {|class="wikitable" |- ! Classe d'architecture ! Nombre d'accès mémoire par opération dyadique |- |- ! Architecture à accumulateur | Un accès mémoire par instruction, pour lire la seconde opérande |- ! Architecture à registres | Zéro si les opérandes sont dans les registres, un pour les opérations ''load-op'', LOAD et STORE. |} ==Le jeu d'instruction des architectures à accumulateur sans registres d'indice== L'accumulateur est adressé grâce au mode d'adressage implicite, de même que le résultat de l'opération. Par contre, les autres opérandes sont localisés avec d'autres modes d'adressage, et lues en mémoire RAM. Le résultat ainsi qu'un des opérandes sont adressés de façon implicite car dans l'accumulateur, seule la seconde opérande étant adressée directement. Grâce à l'accumulateur, une instruction ne fait qu'un seul accès mémoire maximum, ce qui rend le processeur très facile à implémenter. ===La toute première architecture à accumulateur : le Manchester Baby=== [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] Les architectures à accumulateurs sont apparues dès les débuts de l'informatique. Le tout premier ordinateur à programme enregistré en mémoire, le ''Manchester Baby'', était une architecture à accumulateur. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 adresses de 32 bits, fabriquée avec des tubes Williams (abordés dans une annexe à la fin du cours). Le programme devait tenir dans la RAM, avec une instruction par adresse maximum, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 servait à indiquer où se trouvent les opérandes en RAM, les 16 restants sont inutilisés. Le processeur avait un registre accumulateur de 32 bits, un ''program counter'' et un registre d'instruction. Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. ===Les registres des anciennes architectures à accumulateur=== [[File:IBM 701console.jpg|vignette|IBM 701, console extérieure.]] Les architectures à accumulateur étaient communes dans les années 50-60. A l'époque, les ordinateurs étaient gigantesques, ils prenaient une pièce de bâtiment entière dans le pire des cas, une armoire entière dans le meilleur. Les ordinateurs de l'époque étaient surtout utilisés pour du calcul scientifique ou des tâches d’ingénierie demandant beaucoup de calcul, rarement pour de la compatibilité. Les nombres flottants n'étaient pas encore apparus. A la place, les ordinateurs de l'époque géraient des nombres entiers de grande taille, de 30 bits ou plus. En conséquence, l'accumulateur faisait facilement 30 à 60 bits. Par exemple, les ordinateurs de la Série scientifique IBM 700/7000 géraient des entiers de 36 bits, l’accumulateur faisait 38 bits : 36 bits plus deux bits pour les débordements. Au passage, de tels processeurs utilisaient l'adressage par mot, et non par byte. Historiquement, les premières architectures à accumulateur ne contenaient aucun autre registre que l'accumulateur. Ce n'est que dans les années 60 que de nombreuses architectures à accumulateur ont ajouté un second '''registre pour les multiplication/divisions'''. Un exemple est celui de l'IBM 701, qui incorporait un registre accumulateur de 38 bits et un registre multiplieur de 36 bits. Le registre mémorise le multiplieur lors d'une opération de multiplication. Il mémorise donc un opérande, pas le résultat. Il peut aussi décaler le multiplieur vers la droite/gauche, ce qui est utile pour exécuter la multiplication. C'est ce qui est fait sur l'IBM 7094. Une autre possibilité est que ce registre mémorise une partie du résultat de l'opération. Pour rappel, le résultat d'une multiplication/division est codé sur deux fois de bits que ses opérandes. Par exemple, multipliez deux opérandes de 30 bits, vous obtiendrez un résultat de 60 bits. Les 30 bits de poids faible du résultat vont dans l'accumulateur, les 30 bits de poids fort vont dans ce second registre. Les architectures à accumulateur parfois un '''registre pour le pointeur de pile''', utilisé pour gérer les fonctions/procédures. Les architectures à accumulateurs supportaient une pile d'adresse de retour, souvent une pile d'appel. Mais pour cela, il fallait mémoriser le pointeur de pile dans le processeur, ce qui demandait un registre dédié. ===L'adressage indirect avec l'accumulateur=== Les instructions LOAD et STORE existent bel et bien sur les architectures à accumulateur, mais n'ont pas les mêmes modes d'adressages. L'instruction LOAD copie une donnée de la RAM vers l'accumulateur, l'instruction STORE copie l'accumulateur dans une adresse. Les deux instructions n'ont pas besoin d'adresser l'accumulateur, qui est adressé de manière implicite, juste de préciser l'adresse à lire/écrire. Les architectures à accumulateur supportaient souvent le mode d'adressage indirect mémoire. Un exemple est celui des ordinateurs Data General Nova, qui sont des architectures à accumulateur et qui supportaient ce mode d'adressage. Les deux instructions LOAD et STORE existaient en deux versions, distinguées par un bit d'indirection. Si ce bit est à 0 dans l'opcode, alors l'instruction utilise le mode d'adressage absolu normal : l'adresse intégrée dans l'instruction est celle de la donnée. Mais s'il est à 1, alors l'adresse intégrée dans l'instruction est celle du pointeur. Cependant, la présence de l'accumulateur permettait d'utiliser l'adressage indirect à registre, pour gérer les pointeurs. Pour rappel, avec le mode d'adressage indirect à registre, l'adresse à lire/écrire est dans un registre. Ici, l'adresse à lire/écrire est prise dans l'accumulateur, seul registre disponible pour. L'adressage indirect est plus simple à implémenter pour l'instruction LOAD, car elle prend un seul opérande : l'adresse à lire. L'adresse à lire est placée dans l'accumulateur, la donnée lue est elle aussi chargée dans l'accumulateur. Pour l'instruction STORE, il faut fournir deux opérandes, l'adresse et la donnée à écrire, ce qui peut poser problème. Mais au pire, il est toujours possible d'utiliser l'adressage absolu ou indirect mémoire : l'adresse est dans l'instruction, la donnée à écrire dans l'accumulateur. ===L'encodage des instructions=== Sur une architecture à accumulateur l'encodage d'une instruction dyadique est assez simple, vu que l'accumulateur est adressé implicitement. La seconde opérande est localisée soit par une adresse mémoire (adressage absolu), soit est une constante (adressage immédiat). L'adresse mémoire est généralement assez longue, plus que l'opcode. {|class="wikitable" |+ Encodage d'une instruction dyadique |- ! rowspan="2" | Opcode | Adresse mémoire (adressage absolu) |- | Constante (adressage immédiat) |} L'encodage d'une instruction monadique est similaire. Si l'opérande est lue depuis la mémoire RAM, alors l'instruction est encodée comme une instruction dyadique. Il en est de même pour les instructions qui copient une constante dans l'accumulateur. Par contre, si l'opérande est dans l'accumulateur, alors il y a juste besoin d'encoder l'opcode. La majorité des instructions a besoin de préciser une adresse, rares sont celles qui s'en passent. Au vu de cet encodage, les architectures à accumulateur sont qualifiées d''''architectures à une adresse''' par abus de langage. Il est intéressant de contraster leur encodage avec les architectures à registres. Les architectures à registre doivent encoder deux opérandes en plus de l'opcode, avec éventuellement où enregistrer le résultat sur les architectures 3-adresses. Par contre, les opérandes sont généralement des noms de registre, ce qui prend moins de place qu'une adresse mémoire. A la rigueur, les instructions avec une constante immédiate prennent un peu plus de place, car elles doivent encoder un nom de registre en plus de la constante et de l'opcode. Les instructions ''load-op'' des processeurs CISC sont un peu dans le même cas, sauf qu'il faut remplacer la constante par une adresse, qui a généralement la même taille. Les instructions sont donc en moyenne plus courte sur les processeurs à registre, du fait de la présence de registres. ==La micro-architecture des architectures à accumulateur sans registres d'indice== L'organisation interne d'une architecture à accumulateur est très différente de celle des processeurs à registre. Elle est plus ou moins la même pour tous ces processeurs, le point important étant que le chemin de données se résume à une ALU, un registre accumulateur et le bus de données. L'ALU est reliée au registre accumulateur, ainsi qu'au bus de données pour lire la seconde opérande, comme illustré ci-dessous. [[File:Accumulator.png|centre|vignette|upright=2|Accumulateur.]] ===L'unité de calcul et l'accumulateur=== Pour simplifier l'implémentation, le résultat est mémorisé dans un registre en sortie de l'unité de calcul. La raison est qu'on ne veut pas altérer l'accumulateur tant que le résultat final n'est pas totalement calculé. Rappelons que l'ALU ne fournit pas un résultat d'un seul bloc, mais que certains bits arrivent avant les autres, typiquement les bits de poids faible. Si le résultat était écrit dans l'accumulateur directement, il écraserait des bits de l’opérande en cours d'utilisation, ce qui fausserait le résultat. [[File:Accumulateur avec registre de sortie.png|centre|vignette|upright=2|Accumulateur avec registre de sortie]] Une autre solution utilisait un registre entre l'accumulateur et l'unité de calcul, appelé l’'''''accumulator latch'''''. Il remplace le registre en sortie de l'ALU, dans le sens où il permet d'écrire dans l'accumulateur sans effacer l'opérande, pendant que l’opération est en cours dans l'ALU. L'accumulateur est copié dans l’''accumulator latch'', avant que l'ALU démarre ses calculs. L'opérande est donc maintenue même si on commence à écrire le résultat dans l'accumulateur. Sur le 8085 d'Intel, l’''accumulator latch'' peut être initialisé avec une constante prédéfinie, ce qui permet d'implémenter certaines instructions très facilement. Par exemple, il peut être initialisé à 0, ce qui permet d'implémenter les instructions MOV et INC (incrémentation). Un MOV est équivalent à faire un OU entre le registre lu et 0. Une instruction INC initialise l'entrée de retenue de l'unité de calcul à 1, puis ajoute 0. La décrémentation est implémentée de la même manière, sauf que l’''accumulator latch'' est initialisé à -2 pour compenser l'entrée de retenue à 1. De plus, pour supporter les conversion de décimal à BCD, l’''accumulator latch'' peut être initialisé avec les constantes 0x00, 0x06, 0x60, or 0x66. L'''accumulator latch'' est relié à divers fils de commande provenant de l'unité de contrôle, qui décide quelle valeur d'initialisation utiliser en fonction de l'instruction décodée. [[File:Accumulator latch.png|centre|vignette|upright=2|Accumulator latch]] [[File:Chemin de données à un seul bus.png|vignette|Chemin de données à un seul bus]] De même, la seconde opérande, celle lue sur le bus de données, est mémorisée dans un registre en amont de l'ALU. C'était notamment très utile si le processeur utilisait une ALU plus courte que les opérandes, avec par exemple une ALU 4 bits pour un CPU 8 bits. Les anciens processeurs à accumulateur de type ''mainframe'' utilisaient des opérandes de grande taille, du genre 36 ou 48 bits, ce qui avait des conséquences sur l'unité de calcul utilisée, ainsi que sur la communication avec la mémoire. Il arrivait que de tels processeurs utilisaient des ALU sérielles, ou du moins octet-sérielles, plutôt qu'une véritable ALU 36 bits. Nous verrons aussi que c'est très utile sur les processeurs à accumulateur avec un bus interne unique, dans la suite du chapitre. ===La micro-architecture des architectures à accumulateur avec instructions LOAD/STORE=== Nous venons de voir comment est implémenté l'unité de calcul et l'accumulateur, et comment le tout est relié au bus de données. Mais cela ne permet que d'avoir un processeur à accumulateur rudimentaire, qui ne gére que des instructions arithmétiques et logiques. Il faut aussi gérer le cas des opérations LOAD/STORE et des modes d'adressages associés, mais c'est le séquenceur qui s'en occupe. Avec l'adressage absolu, les instructions LOAD et STORE ne font que connecter l'accumulateur au bus de données. L'instruction STORE nécessite de connecter l'accumulateur au bus de données, de manière à ce que le transfert des données se fasse de l'accumulateur vers le bus de données. L'instruction LOAD s'implémente de la même manière, sauf que le sens de transfert est inversé. Cependant, il existe une optimisation qui permet d'implémenter l'instruction LOAD sans ajouter de circuits. Pour cela, il suffit que l'unité de calcul gére les opérations ''pass through'', à savoir des opérations qui se contentent de recopier un opérande sur la sortie. Ici, l'idée est de recopier l'opérande provenant du bus de données. [[File:Architecture à accumulateur, microarchitecture.png|centre|vignette|upright=2|Architecture à accumulateur, microarchitecture]] Pour gérer nativement l'adressage indirect à registre, il suffit de connecter l'accumulateur au bus d'adresse. Le plus simple est d'ajouter un multiplexeur, comme illustré ci-dessous. La donnée lue est copiée dans l'accumulateur, ce qui fait qu'il vaut mieux utiliser un registre d’interfaçage, l'accumulateur n'étant pas utilisable à la fois pour le bus d'adresse et de données. [[File:Adressage indirect sur une architecture à accumulateur.png|centre|vignette|upright=2|Adressage indirect sur une architecture à accumulateur]] Pour finir, voyons comment le pointeur de pile et le ''program counter'' sont implémentés. Les architectures à accumulateur ont souvent des adresses de taille différente des données, ce qui fait qu'il vaut mieux utiliser un circuit incrémenteur dédié pour incrémenter le ''program counter'', plutôt que de l'incrémenter via l'unité de calcul. Les architectures à accumulateur ont parfois un pointeur de pile, qui gère une pile d'adresse de retour, pas une vraie pile d'appel. Aussi, le pointeur de pile est censé être incrémenté et décrémenté, pas plus. Pas d'addition ou de soustraction pour gérer des cadres de pile. Là encore, c'est la solution de l'incrémenteur séparé qui est retenue. Pour économiser des transistors, il n'y a qu'un seul incrémenteur partagé pour les deux. ==Les architectures à accumulateur à registres d'indice== Les architectures à accumulateur décrites dans la section précédente sont capables de faire de l'adressage indirect, mais n'incluent pas les modes d'adressage base + indice et absolus indicés, qui prennent une adresse et y ajoute un indice. Il s'agit des toutes premières architectures à accumulateur, comme les premiers ordinateurs IBM ou le fameux PDP-8. Mais par la suite, les processeurs à accumulateurs ont inclus un support des modes d'adressages indicés, grâce à des '''registres d'indice'''. ===Les registres d'indice=== Les registres d'indice stockent des indices de tableaux. Ils permettaient de supporter deux modes d'adressage : * Le '''mode d'adressage absolu indicé''' où une adresse fixe est additionnée à un indice variable. L'adresse fixe est intégrée dans l'instruction (adressage absolu), l'indice est dans un registre d'indice. * Le '''mode d'adressage base + indice''', où l'adresse est dans l'accumulateur et l'indice dans le registre d'indice. Les processeurs à accumulateur supportaient souvent des variantes des modes d'adressage précédents, où le registre d'indice était automatiquement incrémenté ou décrémenté à chaque utilisation. Au départ, ces processeurs n'utilisaient qu'un seul registre d'indice qui se comportait comme un second accumulateur spécialisé dans les calculs d'adresses mémoire. Le processeur supportait de nouvelles instructions qui utilisaient ce registre d'indice de façon implicite. Mais avec le temps, les processeurs finirent par incorporer plusieurs de ces registres. Les instructions de lecture ou d'écriture devaient alors préciser quel registre d'indice utiliser, en précisant un nom de registre d'indice, un numéro de registre d'indice. Il faut préciser que les registres d'indice ont une taille bien plus petite que l'accumulateur. Ils mémorisent des indices codés sur 16 bits ou moins, alors que l'accumulateur faisait typiquement 36 à 48 bits, parfois plus. La taille classique sur les anciens ''mainframes'' était de 15 bits, parfois moins. Il n'était pas rare de tomber sur des registres d'indice de 8 ou 9 bits. Leur petite taille rendait leur implémentation matérielle peu couteuse. Et c'est ce qui explique qu'ils étaient préférés à l'usage d'un second accumulateur. Un exemple est le cas du processeur Motorola 6809, un processeur à accumulateur qui contient deux registres d'indices nommés X et Y. L'accumulateur est noté D et fait 16 bits, il peut être parfois géré comme deux accumulateurs séparés A et B de 8 bits chacun. Il contenait aussi deux pointeurs de pile, l'un pour les programmes, l'autre pour le système d'exploitation, ainsi qu'un ''program counter''. Le registre de page était utilisé pour l'adressage absolu, comme vu dans le chapitre sur les modes d'adressage. [[File:6809 Internal Registers.svg|centre|vignette|upright=2|6809 Internal Registers]] Les processeurs IBM avaient autrefois plusieurs registres d'indice. Par exemple, l'IBM 704 avait trois registres d'indice de 15 bits. Leur contenu était soustrait de l'adresse absolue. Une instruction pouvait utiliser plusieurs registres d'indice pour adresser son opérande. Toute instruction utilisait trois bits pour sélectionner les registres d'indice utilisés. Fait assez original, lorsque plusieurs registres d'indice sont sélectionnés, le processeur n'additionne pas les trois registres à l'adresse de base. À la place, il fait un OU bit à bit entre les registres d'indice sélectionnés, et additionne le résultat à l'adresse. Les processeurs IBM à accumulateur ont fait ça sur toute la gamme IBM 700/7000, pour des raisons de compatibilité. Les processeurs suivants avaient 7 registres d'indices, mais conservaient les trois bits pour adresser les registres d'indices. Ils pouvaient fonctionner dans deux modes. Le premier mode est plus intuitif : les trois bits précisent un registre d'indice parmi les 7, qui est additionné avec l'adresse absolue. La valeur zéro indique qu'aucun registre d'indice n'est utilisé, ce qui explique qu'il y a 7 registres d'indice et non 8. Un second mode, compatible avec l'IBM 704, fait un OU logique entre les registres d'indice sélectionnés. Seuls les trois premiers registres d'indices peuvent être sélectionnés dans ce mode. Il y a deux instructions pour changer de mode : une pour passer en mode compatible, l'autre pour le quitter pour l'autre mode. Quelques rares processeurs à registres généraux ont utilisés des registres d'indice, en plus des registres généraux. Ce qui fait l'association que nous avons faite entre registres d'indice et architectures à accumulateur est imparfait, bien que solide sur le principe. Un exemple d'architecture de ce type sont les architectures de la série UNIVAC 1100/2200. Ils disposaient de 128 registres, qui étaient mappés en mémoire à partir de l'adresse mémoire 0, la majorité étant inaccessibles par le programmeur. Ils regroupaient 12 registres accumulateurs, 11 registres d'indice et 4 registres hybrides qui pouvaient servir soit de registre d'indice, soit de registres accumulateurs. ===La micro-architecture des architectures à accumulateur avec registres d'indice=== La présence de registres d'indice modifie grandement l'implémentation du processeur. En effet, il faut rajouter un banc de registre pour les registres d'indice. Le banc de registre est monoport, car on a besoin de lire ou d'écrire un indice à la fois. Et il faut aussi potentiellement rajouter de quoi faire les calculs d'adresse. Deux solutions sont possibles : une ALU dédiée aux calculs d'adresse, une seule ALU pour toutes les opérations. Dans le premier cas, il y a une ALU séparée associée aux registres d'indice. L'ALU et les registres d'indice sont placés en sortie du séquenceur, en-dehors du chemin de données, la sortie de l'ALU est directement connectée au bus d'adresse. L'unité de calcul d'adresse peut être utilisée pour incrémenter le ''program counter''. Un défaut de cette approche est qu'elle ne gère pas l'adresse indirect à registre. [[File:Chemin de données sans support des pointeurs, avec adressage absolu indicé.png|centre|vignette|upright=2|Chemin de données sans support des pointeurs, avec adressage absolu indicé]] Une autre option utilise un bus interne, qui interconnecte tout le chemin de données. Dans sa version la plus simple, il est relié à l'accumulateur, l'unité de calcul, le banc de registre d'indice et le bus de données. Avec cette solution, l'ALU est utilisé à la fois pour calculer les adresses et pour les instructions de calcul. En reliant le bus interne au bus d'adresse à travers un multiplexeur, on gère naturellement les adressages indirects. [[File:Architecture à accumulateur avec registres associés.png|centre|vignette|upright=2.5|Architecture à accumulateur avec registres associés]] Il faut noter que sur les architectures Von Neumann, le séquenceur est relié à ce bus interne. En effet, charger une instruction demande de passer par le bus mémoire, donc par l’intermédiaire de ce bus internet. Le ''program counter'' est envoyé sur ce bus pour lire l'instruction, puis l'instruction lue est recopiée dans le registre d'instruction. Le chargement d'une instruction est donc géré comme une lecture des plus classiques. De plus, cela permet d'incrémenter le ''program counter'' au niveau de l'unité de calcul entière. Le ''program counter'' est envoyé sur le bus interne, incrémenté par l'ALU, puis le résultat est recopié dans le ''program counter'' via le bus interne. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] ==Les processeurs bi-accumulateurs : le Motorola 6800== Le Motorola 6800 était un processeur 8 bits qui gérait des adresses de 16 bits. Il contenait deux accumulateurs nommés A et B, de 8 bits chacun. Il disposait aussi d'un registre d'indice, d'un pointeur de pile et d'un ''program counter'', tous les trois de 16 bits. Le registre d'état regroupait 6 bits, qu'on ne détaillera pas ici. [[File:MC6800 Processor Diagram.png|centre|vignette|upright=2|Interface et registres du MC6800.]] La présence des deux accumulateurs impactait surtout les instructions dyadiques. Les instructions monadiques avaient juste à préciser où se trouvait l'opérande : soit en RAM, soit dans le premier accumulateur, soit dans le second. Pour les opérations dyadiques, la gestion était totalement différente. En théorie, le premier opérande est dans un accumulateur, soit A, soit B. La seconde opérande vient soit de l'autre accumulateur, soit de la mémoire RAM. Et selon les instructions, tout variait. Pour l'addition, il y avait trois instructions. Les deux premières additionnaient un opérande provenant de la mémoire avec un accumulateur. L'instruction ADDA sélectionnait le premier accumulateur, l'instruction ADDB sélectionnait le second accumulateur. Mais une troisième instruction, l’instruction ABA, permettait d'additionner le contenu des deux accumulateurs. Pour les autres opérations, il n'était pas possible d'utiliser les deux accumulateurs en même temps. La seule possibilité était de faire une opération entre un accumulateur et un opérande venant de la mémoire. Toutes les instructions étaient en double, avec une copie par accumulateur. Par exemple, l'instruction ANDA faisait un ET entre l’accumulateur A et l'opérande mémoire, l'instruction ANDB faisait pareil avec l'accumulateur B. ==Les architectures hybrides registres-accumulateur== Il a existé quelques architectures qui étaient des hybrides entre architectures à accumulateur et architecture à registre. Elles ont servi de transition entre les deux, durant les années 80-90. Elles avaient un accumulateur unique couplé à un banc de registres généraux. Par exemple, les premiers processeurs Intel 8 bits étaient des processeurs hybrides-accumulateur. Lles CPU Intel 8 bits disposaient de 7 registres de 8 bits nommés A, B, C, D, E, F, H, L, SP. Ils correspondent respectivement à : * l'accumulateur A ; * six registres nommés B, C, D, E, H et L ; * le registre d'état F ; * le pointeur de pile SP. Sur ces processeurs, les instructions dyadiques devaient mettre leur premier opérande dans l'accumulateur, la seconde provenait soit des registres, soit de la RAM, soit d'une constante immédiate. Les opérations monadiques pouvaient lire leur opérande depuis l'accumulateur, les autres registres ou la RAM, tout était permis. Les registres d'indices disparaissaient sur ces architectures, en théorie. Les registres généraux pouvaient être utilisés comme registre d'indice ou pour stocker des opérandes, ils étaient assez versatiles pour servir de registres d'indices. La présence de registres a de nombreux avantages, comparé aux architectures à accumulateur pures. Les instructions arithmétiques sont plus rapide, lire un registre étant plus rapide qu'un accès RAM. Les performances sont donc augmentées. De plus, les instructions arithmétiques utilisant ces registres sont plus courtes : pas besoin d'encoder une adresse mémoire, un nom de registre suffit. Vu que les processeurs de l’époque avaient des instructions de taille variable, cela améliorait la densité de code. La microarchitecture de ces processeurs est très similaire à celle d'un processeur avec des registres d'indices. La seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Le banc de registre est systématiquement monoport, car il n'avait aucune raison d'être multiport. Pour les instructions dyadiques, seules à lire deux opérandes, il ne servait que pour la seconde opérande, la première était lue depuis l'accumulateur. Les processeurs hybrides registre-accumulateur se classent en deux types principaux : ceux qui ont un seul bus interne, et ceux qui en ont deux. Le premier cas est identique à celui vu précédemment pour les architectures à accumulateur avec registres d'indice, à la seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Afin de gérer l'adressage indirect à registre, le bus interne est connecté aux deux registres d’interfaçage mémoire. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] Notons que cela permet aussi d'implémenter facilement les branchements indirects, car le bus interne permet d'échanger des adresses entre ''program counter'' et banc de registre. De même, il est possible d'utiliser l'ALU pour gérer les branchements indirects., en plus de l'utiliser pour incrémenter le ''program counter''. [[File:Single bus organization.jpg|centre|vignette|upright=2|Single bus organization]] Une autre solution utilisait deux bus internes : un connecté au bus de données, un autre relié au bus d'adresse. Le bus de commande mémoire était lui commandé par le séquenceur, l'unité de contrôle. L'intermédiaire entre ces deux bus était le banc de registre, ainsi que les autres registres. Le banc de registre était connecté aux deux bus interne, avec un port de lecture relié au bus d'adresse, un port de lecture-écriture relié au bus de données. Le port de lecture était utilisé pour l'adressage indirect, l'autre l'était pour le reste. [[File:Proz1-e.png|centre|vignette|upright=2|Intérieur d'un processeur.]] L'organisation à deux bus simplifiait la gestion du ''program counter'' et le chargement des instructions. Le ''program counter'' était soit séparé du banc de registre, soit placé dans le banc de registre. Les deux solutions étaient utilisés, tout dépend du processeur. Il faut noter que si le ''program counter'' est intégré au banc de registres, alors la microarchitecture du processeur est bien plus simple. L'envoi du ''program counter'' sur le bus d'adresse utilise le port de lecture relié au bus d'adresse, qui sert aussi pour l'adressage indirect. L'économie de circuits, sans compter la simplicité d'implémentation que cela implique, explique sans doute que la technique a été utilisée sur quelques processeurs anciens. Le ''program counter'' était généralement incrémenté par l'ALU, ce qui explique qu'il soit connecté au bus interne pour les données. La connexion est aussi utile pour gérer les branchements indirects, qui copient un registre dans le ''program counter'', ainsi que les branchements relatifs (addition dans l'ALU), voire les branchements directs (l'adresse vers laquelle brancher est envoyée en entrée de l'ALU et propagée en sortie avec une opération ''pass through''). [[File:Connexion du program counter sur les bus avec PC dans le banc de registres.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC dans le banc de registres]] ===Les registres d'interruption avec un processeur hybride-accumulateur : l'exemple du Z80=== Un exemple de processeur registre-accumulateur à deux bus interne est le Z80, un processeur fortement inspiré des CPU Intel 8 bits. Il a un jeu d'instruction similaire, mais a diverses améliorations par rapport au design original. Notamment, le processeur a des registres séparés pour les interruptions. Sur le Z80, les registres généraux sont dupliqués avec 6 registres pour les interruptions et 6 registres pour les programmes autres. Leur copie pour les interruptions sont nommées B', C', D', E', H', L'. Les 12 registres sont placés dans le banc de registre, ce qui implique que le fenêtrage de registres est utilisé pour gérer la séparation entre registre d'interruption et normaux. Il faut noter que l'accumulateur et le registre d'état sont aussi dupliqués, leurs copies étant nommées A' et F'. Mais leur duplication se fait autrement que par fenêtrage de registre. En plus des registres précédents, le Z80 incorporait deux registres d'indice nommés X et Y, ainsi qu'un pointeur de pile SP et un ''program counter'' PC. Ils n'étaient pas dupliqués pour les interruptions. Les registres d'indice étaient reliés à une unité de calcul d'adresse. L'unité de calcul d'adresse prenait deux opérandes : un indice, et une adresse mémoire provenant soit du banc de registre, soit de l'accumulateur. En clair, l'unité de calcul d'adresse faisait le lien entre les deux bus internet : le bus de données interne en entrée, le bus d'adresse en sortie. À l'intérieur du processeur, tous les registres étaient regroupés dans un banc de registre unique, sauf les accumulateurs, les registres d'état et le ''program counter''. Bien que ce ne soit pas indiqué sur le schéma ci-dessous, le ''program counter'' est séparé du banc de registre, alors que le pointeur de pile est dedans. Le compteur IR est lui associé au ''program counter'', il est sortit du banc de registre. Le Z80 utilise lui aussi un incrémenteur séparé de l'ALU, qui est utilisé pour mettre à jour le ''program counter'', le pointeur de pile et un compteur de rafraichissement mémoire nommé IR sur le Z80 (pour rappel, le rafraichissement mémoire demande de balayer la mémoire d'adresse en adresse et été fait par le CPU à l'époque). De plus, il est utilisé pour les instructions INC et DEC qui incrémentent une opérande de 16 bits obtenue en combinant deux registres de 8 bits. En clair, l'incrémenteur du ''program counter'' a été réutilisé de beaucoup de manières originales. [[File:Z80 arch.svg|centre|vignette|upright=3|Microarchitecture du Z80.]] Le Z80 incorporait des instructions pour échanger le contenu des deux ensembles de registres, accumulateur inclus. Elles permettaient d'utiliser les registres d'interruption pour les programmes et réciproquement. En clair, cela doublait le nombre de registres si les interruptions n'étaient pas utilisées. * L'instruction EXX échangeait les deux fenêtres de registres généraux : les registres B, C, D, E, H et L devenaient les registres B', C', D', E', H' et L' et inversement. * L'instruction EX échangeait l'accumulateur et le registre d'état : les registres A,F devenait A',F' et inversement. Le fenêtrage de registre était modifié par l'instruction EXX, qui échangeait les deux fenêtres de registres. Pour l'implémenter, une bascule était ajouté au processeur, appelons-la la bascule INT. Elle était relié au bus d'adresse du banc de registre, dont elle mémorisait le bit de poids fort. L'instruction EXX inversait la valeur de la bascule INT. Il est aussi possible d'échanger le contenu des registres D,E et H,L avec une instruction dédiée, ce qui est là encore fait par deux bascules : une pour les registres D,E et une autre pour les registres H,L. Pour l'accumulateur et le registre d'état, le choix entre registre normal et registre d'interruption se faisait là encore par une seconde bascule appelée la bascule A. La bascule est reliée à un multiplexeur et un démultiplexeur, qui permet de choisir quel accumulateur relier à l'unité de calcul. L'instruction EX inverse le contenu de la bascule A. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=L'unité de contrôle | prevText=L'unité de contrôle | next=Les processeurs 8 bits et moins | nextText=Les processeurs 8 bits et moins }} </noinclude> 3bbm88yatht8pg1r442bxm8xdmfngq3 744136 744134 2025-06-05T00:33:47Z Mewtow 31375 /* La toute première architecture à accumulateur : le Manchester Baby */ 744136 wikitext text/x-wiki Les architectures que nous avons vu précédemment dans ce cours disposent de registres pour les données, en plus du pointeur de pile, d'un ''program counter'', et de quelques autres. Elles sont appelées des '''architectures à registres''', terme qui trahit bien le fait qu'elles ont des registres généraux ou spécialisés pour stocker temporairement des données. Et si on leur a donné un nom, c'est parce qu'il existe des architectures qui ne sont pas dans cette catégorie. Il en existe plusieurs types, mais ce chapitre va se concentrer sur les '''architectures à accumulateur'''. [[File:Isaccumulator.png|vignette|Architecture à accumulateur.]] Les architectures à accumulateur sont centrées autour d'un registre architectural appelé l''''accumulateur'''. Il est utilisé pour toutes les opérations arithmétiques dyadiques, où il sert à la fois de source et de destination. Toutes les instructions dyadiques sont de type ''load-op'' : une opérande est lue depuis l'accumulateur, le second opérande est lu depuis la mémoire RAM, le résultat de l'instruction est automatiquement mémorisé dans l'accumulateur. Les instructions monadiques peuvent utiliser un opérande dans l'accumulateur, ou dans la mémoire RAM, les deux sont théoriquement possibles. La conséquence est que le nombre d'accès mémoire est drastiquement diminué : de 3 par instructions sur une architecture mémoire-mémoire, on passe à seulement un avec un accumulateur. Les opérations dyadiques ont besoin d'un seul accès mémoire pour lire la seconde opérande, les opérations monadique en font aussi un seul pour lire leur unique opérande. {|class="wikitable" |- ! Classe d'architecture ! Nombre d'accès mémoire par opération dyadique |- |- ! Architecture à accumulateur | Un accès mémoire par instruction, pour lire la seconde opérande |- ! Architecture à registres | Zéro si les opérandes sont dans les registres, un pour les opérations ''load-op'', LOAD et STORE. |} ==Le jeu d'instruction des architectures à accumulateur sans registres d'indice== L'accumulateur est adressé grâce au mode d'adressage implicite, de même que le résultat de l'opération. Par contre, les autres opérandes sont localisés avec d'autres modes d'adressage, et lues en mémoire RAM. Le résultat ainsi qu'un des opérandes sont adressés de façon implicite car dans l'accumulateur, seule la seconde opérande étant adressée directement. Grâce à l'accumulateur, une instruction ne fait qu'un seul accès mémoire maximum, ce qui rend le processeur très facile à implémenter. ===La toute première architecture à accumulateur : le Manchester Baby=== [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] Les architectures à accumulateurs sont apparues dès les débuts de l'informatique. Le tout premier ordinateur à programme enregistré en mémoire, le ''Manchester Baby'', était une architecture à accumulateur. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 adresses de 32 bits, fabriquée avec des tubes Williams (abordés dans une annexe à la fin du cours). Le programme devait tenir dans la RAM, avec une instruction par adresse maximum, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 servait à indiquer où se trouvent les opérandes en RAM, les 16 restants sont inutilisés. Le processeur avait un registre accumulateur de 32 bits, un ''program counter'' et un registre d'instruction. Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. C'était là encore une architecture à accumulateur, sauf qu'elle intégrait aussi des registres d'indice. Et surtout : son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. ===Les registres des anciennes architectures à accumulateur=== [[File:IBM 701console.jpg|vignette|IBM 701, console extérieure.]] Les architectures à accumulateur étaient communes dans les années 50-60. A l'époque, les ordinateurs étaient gigantesques, ils prenaient une pièce de bâtiment entière dans le pire des cas, une armoire entière dans le meilleur. Les ordinateurs de l'époque étaient surtout utilisés pour du calcul scientifique ou des tâches d’ingénierie demandant beaucoup de calcul, rarement pour de la compatibilité. Les nombres flottants n'étaient pas encore apparus. A la place, les ordinateurs de l'époque géraient des nombres entiers de grande taille, de 30 bits ou plus. En conséquence, l'accumulateur faisait facilement 30 à 60 bits. Par exemple, les ordinateurs de la Série scientifique IBM 700/7000 géraient des entiers de 36 bits, l’accumulateur faisait 38 bits : 36 bits plus deux bits pour les débordements. Au passage, de tels processeurs utilisaient l'adressage par mot, et non par byte. Historiquement, les premières architectures à accumulateur ne contenaient aucun autre registre que l'accumulateur. Ce n'est que dans les années 60 que de nombreuses architectures à accumulateur ont ajouté un second '''registre pour les multiplication/divisions'''. Un exemple est celui de l'IBM 701, qui incorporait un registre accumulateur de 38 bits et un registre multiplieur de 36 bits. Le registre mémorise le multiplieur lors d'une opération de multiplication. Il mémorise donc un opérande, pas le résultat. Il peut aussi décaler le multiplieur vers la droite/gauche, ce qui est utile pour exécuter la multiplication. C'est ce qui est fait sur l'IBM 7094. Une autre possibilité est que ce registre mémorise une partie du résultat de l'opération. Pour rappel, le résultat d'une multiplication/division est codé sur deux fois de bits que ses opérandes. Par exemple, multipliez deux opérandes de 30 bits, vous obtiendrez un résultat de 60 bits. Les 30 bits de poids faible du résultat vont dans l'accumulateur, les 30 bits de poids fort vont dans ce second registre. Les architectures à accumulateur parfois un '''registre pour le pointeur de pile''', utilisé pour gérer les fonctions/procédures. Les architectures à accumulateurs supportaient une pile d'adresse de retour, souvent une pile d'appel. Mais pour cela, il fallait mémoriser le pointeur de pile dans le processeur, ce qui demandait un registre dédié. ===L'adressage indirect avec l'accumulateur=== Les instructions LOAD et STORE existent bel et bien sur les architectures à accumulateur, mais n'ont pas les mêmes modes d'adressages. L'instruction LOAD copie une donnée de la RAM vers l'accumulateur, l'instruction STORE copie l'accumulateur dans une adresse. Les deux instructions n'ont pas besoin d'adresser l'accumulateur, qui est adressé de manière implicite, juste de préciser l'adresse à lire/écrire. Les architectures à accumulateur supportaient souvent le mode d'adressage indirect mémoire. Un exemple est celui des ordinateurs Data General Nova, qui sont des architectures à accumulateur et qui supportaient ce mode d'adressage. Les deux instructions LOAD et STORE existaient en deux versions, distinguées par un bit d'indirection. Si ce bit est à 0 dans l'opcode, alors l'instruction utilise le mode d'adressage absolu normal : l'adresse intégrée dans l'instruction est celle de la donnée. Mais s'il est à 1, alors l'adresse intégrée dans l'instruction est celle du pointeur. Cependant, la présence de l'accumulateur permettait d'utiliser l'adressage indirect à registre, pour gérer les pointeurs. Pour rappel, avec le mode d'adressage indirect à registre, l'adresse à lire/écrire est dans un registre. Ici, l'adresse à lire/écrire est prise dans l'accumulateur, seul registre disponible pour. L'adressage indirect est plus simple à implémenter pour l'instruction LOAD, car elle prend un seul opérande : l'adresse à lire. L'adresse à lire est placée dans l'accumulateur, la donnée lue est elle aussi chargée dans l'accumulateur. Pour l'instruction STORE, il faut fournir deux opérandes, l'adresse et la donnée à écrire, ce qui peut poser problème. Mais au pire, il est toujours possible d'utiliser l'adressage absolu ou indirect mémoire : l'adresse est dans l'instruction, la donnée à écrire dans l'accumulateur. ===L'encodage des instructions=== Sur une architecture à accumulateur l'encodage d'une instruction dyadique est assez simple, vu que l'accumulateur est adressé implicitement. La seconde opérande est localisée soit par une adresse mémoire (adressage absolu), soit est une constante (adressage immédiat). L'adresse mémoire est généralement assez longue, plus que l'opcode. {|class="wikitable" |+ Encodage d'une instruction dyadique |- ! rowspan="2" | Opcode | Adresse mémoire (adressage absolu) |- | Constante (adressage immédiat) |} L'encodage d'une instruction monadique est similaire. Si l'opérande est lue depuis la mémoire RAM, alors l'instruction est encodée comme une instruction dyadique. Il en est de même pour les instructions qui copient une constante dans l'accumulateur. Par contre, si l'opérande est dans l'accumulateur, alors il y a juste besoin d'encoder l'opcode. La majorité des instructions a besoin de préciser une adresse, rares sont celles qui s'en passent. Au vu de cet encodage, les architectures à accumulateur sont qualifiées d''''architectures à une adresse''' par abus de langage. Il est intéressant de contraster leur encodage avec les architectures à registres. Les architectures à registre doivent encoder deux opérandes en plus de l'opcode, avec éventuellement où enregistrer le résultat sur les architectures 3-adresses. Par contre, les opérandes sont généralement des noms de registre, ce qui prend moins de place qu'une adresse mémoire. A la rigueur, les instructions avec une constante immédiate prennent un peu plus de place, car elles doivent encoder un nom de registre en plus de la constante et de l'opcode. Les instructions ''load-op'' des processeurs CISC sont un peu dans le même cas, sauf qu'il faut remplacer la constante par une adresse, qui a généralement la même taille. Les instructions sont donc en moyenne plus courte sur les processeurs à registre, du fait de la présence de registres. ==La micro-architecture des architectures à accumulateur sans registres d'indice== L'organisation interne d'une architecture à accumulateur est très différente de celle des processeurs à registre. Elle est plus ou moins la même pour tous ces processeurs, le point important étant que le chemin de données se résume à une ALU, un registre accumulateur et le bus de données. L'ALU est reliée au registre accumulateur, ainsi qu'au bus de données pour lire la seconde opérande, comme illustré ci-dessous. [[File:Accumulator.png|centre|vignette|upright=2|Accumulateur.]] ===L'unité de calcul et l'accumulateur=== Pour simplifier l'implémentation, le résultat est mémorisé dans un registre en sortie de l'unité de calcul. La raison est qu'on ne veut pas altérer l'accumulateur tant que le résultat final n'est pas totalement calculé. Rappelons que l'ALU ne fournit pas un résultat d'un seul bloc, mais que certains bits arrivent avant les autres, typiquement les bits de poids faible. Si le résultat était écrit dans l'accumulateur directement, il écraserait des bits de l’opérande en cours d'utilisation, ce qui fausserait le résultat. [[File:Accumulateur avec registre de sortie.png|centre|vignette|upright=2|Accumulateur avec registre de sortie]] Une autre solution utilisait un registre entre l'accumulateur et l'unité de calcul, appelé l’'''''accumulator latch'''''. Il remplace le registre en sortie de l'ALU, dans le sens où il permet d'écrire dans l'accumulateur sans effacer l'opérande, pendant que l’opération est en cours dans l'ALU. L'accumulateur est copié dans l’''accumulator latch'', avant que l'ALU démarre ses calculs. L'opérande est donc maintenue même si on commence à écrire le résultat dans l'accumulateur. Sur le 8085 d'Intel, l’''accumulator latch'' peut être initialisé avec une constante prédéfinie, ce qui permet d'implémenter certaines instructions très facilement. Par exemple, il peut être initialisé à 0, ce qui permet d'implémenter les instructions MOV et INC (incrémentation). Un MOV est équivalent à faire un OU entre le registre lu et 0. Une instruction INC initialise l'entrée de retenue de l'unité de calcul à 1, puis ajoute 0. La décrémentation est implémentée de la même manière, sauf que l’''accumulator latch'' est initialisé à -2 pour compenser l'entrée de retenue à 1. De plus, pour supporter les conversion de décimal à BCD, l’''accumulator latch'' peut être initialisé avec les constantes 0x00, 0x06, 0x60, or 0x66. L'''accumulator latch'' est relié à divers fils de commande provenant de l'unité de contrôle, qui décide quelle valeur d'initialisation utiliser en fonction de l'instruction décodée. [[File:Accumulator latch.png|centre|vignette|upright=2|Accumulator latch]] [[File:Chemin de données à un seul bus.png|vignette|Chemin de données à un seul bus]] De même, la seconde opérande, celle lue sur le bus de données, est mémorisée dans un registre en amont de l'ALU. C'était notamment très utile si le processeur utilisait une ALU plus courte que les opérandes, avec par exemple une ALU 4 bits pour un CPU 8 bits. Les anciens processeurs à accumulateur de type ''mainframe'' utilisaient des opérandes de grande taille, du genre 36 ou 48 bits, ce qui avait des conséquences sur l'unité de calcul utilisée, ainsi que sur la communication avec la mémoire. Il arrivait que de tels processeurs utilisaient des ALU sérielles, ou du moins octet-sérielles, plutôt qu'une véritable ALU 36 bits. Nous verrons aussi que c'est très utile sur les processeurs à accumulateur avec un bus interne unique, dans la suite du chapitre. ===La micro-architecture des architectures à accumulateur avec instructions LOAD/STORE=== Nous venons de voir comment est implémenté l'unité de calcul et l'accumulateur, et comment le tout est relié au bus de données. Mais cela ne permet que d'avoir un processeur à accumulateur rudimentaire, qui ne gére que des instructions arithmétiques et logiques. Il faut aussi gérer le cas des opérations LOAD/STORE et des modes d'adressages associés, mais c'est le séquenceur qui s'en occupe. Avec l'adressage absolu, les instructions LOAD et STORE ne font que connecter l'accumulateur au bus de données. L'instruction STORE nécessite de connecter l'accumulateur au bus de données, de manière à ce que le transfert des données se fasse de l'accumulateur vers le bus de données. L'instruction LOAD s'implémente de la même manière, sauf que le sens de transfert est inversé. Cependant, il existe une optimisation qui permet d'implémenter l'instruction LOAD sans ajouter de circuits. Pour cela, il suffit que l'unité de calcul gére les opérations ''pass through'', à savoir des opérations qui se contentent de recopier un opérande sur la sortie. Ici, l'idée est de recopier l'opérande provenant du bus de données. [[File:Architecture à accumulateur, microarchitecture.png|centre|vignette|upright=2|Architecture à accumulateur, microarchitecture]] Pour gérer nativement l'adressage indirect à registre, il suffit de connecter l'accumulateur au bus d'adresse. Le plus simple est d'ajouter un multiplexeur, comme illustré ci-dessous. La donnée lue est copiée dans l'accumulateur, ce qui fait qu'il vaut mieux utiliser un registre d’interfaçage, l'accumulateur n'étant pas utilisable à la fois pour le bus d'adresse et de données. [[File:Adressage indirect sur une architecture à accumulateur.png|centre|vignette|upright=2|Adressage indirect sur une architecture à accumulateur]] Pour finir, voyons comment le pointeur de pile et le ''program counter'' sont implémentés. Les architectures à accumulateur ont souvent des adresses de taille différente des données, ce qui fait qu'il vaut mieux utiliser un circuit incrémenteur dédié pour incrémenter le ''program counter'', plutôt que de l'incrémenter via l'unité de calcul. Les architectures à accumulateur ont parfois un pointeur de pile, qui gère une pile d'adresse de retour, pas une vraie pile d'appel. Aussi, le pointeur de pile est censé être incrémenté et décrémenté, pas plus. Pas d'addition ou de soustraction pour gérer des cadres de pile. Là encore, c'est la solution de l'incrémenteur séparé qui est retenue. Pour économiser des transistors, il n'y a qu'un seul incrémenteur partagé pour les deux. ==Les architectures à accumulateur à registres d'indice== Les architectures à accumulateur décrites dans la section précédente sont capables de faire de l'adressage indirect, mais n'incluent pas les modes d'adressage base + indice et absolus indicés, qui prennent une adresse et y ajoute un indice. Il s'agit des toutes premières architectures à accumulateur, comme les premiers ordinateurs IBM ou le fameux PDP-8. Mais par la suite, les processeurs à accumulateurs ont inclus un support des modes d'adressages indicés, grâce à des '''registres d'indice'''. ===Les registres d'indice=== Les registres d'indice stockent des indices de tableaux. Ils permettaient de supporter deux modes d'adressage : * Le '''mode d'adressage absolu indicé''' où une adresse fixe est additionnée à un indice variable. L'adresse fixe est intégrée dans l'instruction (adressage absolu), l'indice est dans un registre d'indice. * Le '''mode d'adressage base + indice''', où l'adresse est dans l'accumulateur et l'indice dans le registre d'indice. Les processeurs à accumulateur supportaient souvent des variantes des modes d'adressage précédents, où le registre d'indice était automatiquement incrémenté ou décrémenté à chaque utilisation. Au départ, ces processeurs n'utilisaient qu'un seul registre d'indice qui se comportait comme un second accumulateur spécialisé dans les calculs d'adresses mémoire. Le processeur supportait de nouvelles instructions qui utilisaient ce registre d'indice de façon implicite. Mais avec le temps, les processeurs finirent par incorporer plusieurs de ces registres. Les instructions de lecture ou d'écriture devaient alors préciser quel registre d'indice utiliser, en précisant un nom de registre d'indice, un numéro de registre d'indice. Il faut préciser que les registres d'indice ont une taille bien plus petite que l'accumulateur. Ils mémorisent des indices codés sur 16 bits ou moins, alors que l'accumulateur faisait typiquement 36 à 48 bits, parfois plus. La taille classique sur les anciens ''mainframes'' était de 15 bits, parfois moins. Il n'était pas rare de tomber sur des registres d'indice de 8 ou 9 bits. Leur petite taille rendait leur implémentation matérielle peu couteuse. Et c'est ce qui explique qu'ils étaient préférés à l'usage d'un second accumulateur. Un exemple est le cas du processeur Motorola 6809, un processeur à accumulateur qui contient deux registres d'indices nommés X et Y. L'accumulateur est noté D et fait 16 bits, il peut être parfois géré comme deux accumulateurs séparés A et B de 8 bits chacun. Il contenait aussi deux pointeurs de pile, l'un pour les programmes, l'autre pour le système d'exploitation, ainsi qu'un ''program counter''. Le registre de page était utilisé pour l'adressage absolu, comme vu dans le chapitre sur les modes d'adressage. [[File:6809 Internal Registers.svg|centre|vignette|upright=2|6809 Internal Registers]] Les processeurs IBM avaient autrefois plusieurs registres d'indice. Par exemple, l'IBM 704 avait trois registres d'indice de 15 bits. Leur contenu était soustrait de l'adresse absolue. Une instruction pouvait utiliser plusieurs registres d'indice pour adresser son opérande. Toute instruction utilisait trois bits pour sélectionner les registres d'indice utilisés. Fait assez original, lorsque plusieurs registres d'indice sont sélectionnés, le processeur n'additionne pas les trois registres à l'adresse de base. À la place, il fait un OU bit à bit entre les registres d'indice sélectionnés, et additionne le résultat à l'adresse. Les processeurs IBM à accumulateur ont fait ça sur toute la gamme IBM 700/7000, pour des raisons de compatibilité. Les processeurs suivants avaient 7 registres d'indices, mais conservaient les trois bits pour adresser les registres d'indices. Ils pouvaient fonctionner dans deux modes. Le premier mode est plus intuitif : les trois bits précisent un registre d'indice parmi les 7, qui est additionné avec l'adresse absolue. La valeur zéro indique qu'aucun registre d'indice n'est utilisé, ce qui explique qu'il y a 7 registres d'indice et non 8. Un second mode, compatible avec l'IBM 704, fait un OU logique entre les registres d'indice sélectionnés. Seuls les trois premiers registres d'indices peuvent être sélectionnés dans ce mode. Il y a deux instructions pour changer de mode : une pour passer en mode compatible, l'autre pour le quitter pour l'autre mode. Quelques rares processeurs à registres généraux ont utilisés des registres d'indice, en plus des registres généraux. Ce qui fait l'association que nous avons faite entre registres d'indice et architectures à accumulateur est imparfait, bien que solide sur le principe. Un exemple d'architecture de ce type sont les architectures de la série UNIVAC 1100/2200. Ils disposaient de 128 registres, qui étaient mappés en mémoire à partir de l'adresse mémoire 0, la majorité étant inaccessibles par le programmeur. Ils regroupaient 12 registres accumulateurs, 11 registres d'indice et 4 registres hybrides qui pouvaient servir soit de registre d'indice, soit de registres accumulateurs. ===La micro-architecture des architectures à accumulateur avec registres d'indice=== La présence de registres d'indice modifie grandement l'implémentation du processeur. En effet, il faut rajouter un banc de registre pour les registres d'indice. Le banc de registre est monoport, car on a besoin de lire ou d'écrire un indice à la fois. Et il faut aussi potentiellement rajouter de quoi faire les calculs d'adresse. Deux solutions sont possibles : une ALU dédiée aux calculs d'adresse, une seule ALU pour toutes les opérations. Dans le premier cas, il y a une ALU séparée associée aux registres d'indice. L'ALU et les registres d'indice sont placés en sortie du séquenceur, en-dehors du chemin de données, la sortie de l'ALU est directement connectée au bus d'adresse. L'unité de calcul d'adresse peut être utilisée pour incrémenter le ''program counter''. Un défaut de cette approche est qu'elle ne gère pas l'adresse indirect à registre. [[File:Chemin de données sans support des pointeurs, avec adressage absolu indicé.png|centre|vignette|upright=2|Chemin de données sans support des pointeurs, avec adressage absolu indicé]] Une autre option utilise un bus interne, qui interconnecte tout le chemin de données. Dans sa version la plus simple, il est relié à l'accumulateur, l'unité de calcul, le banc de registre d'indice et le bus de données. Avec cette solution, l'ALU est utilisé à la fois pour calculer les adresses et pour les instructions de calcul. En reliant le bus interne au bus d'adresse à travers un multiplexeur, on gère naturellement les adressages indirects. [[File:Architecture à accumulateur avec registres associés.png|centre|vignette|upright=2.5|Architecture à accumulateur avec registres associés]] Il faut noter que sur les architectures Von Neumann, le séquenceur est relié à ce bus interne. En effet, charger une instruction demande de passer par le bus mémoire, donc par l’intermédiaire de ce bus internet. Le ''program counter'' est envoyé sur ce bus pour lire l'instruction, puis l'instruction lue est recopiée dans le registre d'instruction. Le chargement d'une instruction est donc géré comme une lecture des plus classiques. De plus, cela permet d'incrémenter le ''program counter'' au niveau de l'unité de calcul entière. Le ''program counter'' est envoyé sur le bus interne, incrémenté par l'ALU, puis le résultat est recopié dans le ''program counter'' via le bus interne. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] ==Les processeurs bi-accumulateurs : le Motorola 6800== Le Motorola 6800 était un processeur 8 bits qui gérait des adresses de 16 bits. Il contenait deux accumulateurs nommés A et B, de 8 bits chacun. Il disposait aussi d'un registre d'indice, d'un pointeur de pile et d'un ''program counter'', tous les trois de 16 bits. Le registre d'état regroupait 6 bits, qu'on ne détaillera pas ici. [[File:MC6800 Processor Diagram.png|centre|vignette|upright=2|Interface et registres du MC6800.]] La présence des deux accumulateurs impactait surtout les instructions dyadiques. Les instructions monadiques avaient juste à préciser où se trouvait l'opérande : soit en RAM, soit dans le premier accumulateur, soit dans le second. Pour les opérations dyadiques, la gestion était totalement différente. En théorie, le premier opérande est dans un accumulateur, soit A, soit B. La seconde opérande vient soit de l'autre accumulateur, soit de la mémoire RAM. Et selon les instructions, tout variait. Pour l'addition, il y avait trois instructions. Les deux premières additionnaient un opérande provenant de la mémoire avec un accumulateur. L'instruction ADDA sélectionnait le premier accumulateur, l'instruction ADDB sélectionnait le second accumulateur. Mais une troisième instruction, l’instruction ABA, permettait d'additionner le contenu des deux accumulateurs. Pour les autres opérations, il n'était pas possible d'utiliser les deux accumulateurs en même temps. La seule possibilité était de faire une opération entre un accumulateur et un opérande venant de la mémoire. Toutes les instructions étaient en double, avec une copie par accumulateur. Par exemple, l'instruction ANDA faisait un ET entre l’accumulateur A et l'opérande mémoire, l'instruction ANDB faisait pareil avec l'accumulateur B. ==Les architectures hybrides registres-accumulateur== Il a existé quelques architectures qui étaient des hybrides entre architectures à accumulateur et architecture à registre. Elles ont servi de transition entre les deux, durant les années 80-90. Elles avaient un accumulateur unique couplé à un banc de registres généraux. Par exemple, les premiers processeurs Intel 8 bits étaient des processeurs hybrides-accumulateur. Lles CPU Intel 8 bits disposaient de 7 registres de 8 bits nommés A, B, C, D, E, F, H, L, SP. Ils correspondent respectivement à : * l'accumulateur A ; * six registres nommés B, C, D, E, H et L ; * le registre d'état F ; * le pointeur de pile SP. Sur ces processeurs, les instructions dyadiques devaient mettre leur premier opérande dans l'accumulateur, la seconde provenait soit des registres, soit de la RAM, soit d'une constante immédiate. Les opérations monadiques pouvaient lire leur opérande depuis l'accumulateur, les autres registres ou la RAM, tout était permis. Les registres d'indices disparaissaient sur ces architectures, en théorie. Les registres généraux pouvaient être utilisés comme registre d'indice ou pour stocker des opérandes, ils étaient assez versatiles pour servir de registres d'indices. La présence de registres a de nombreux avantages, comparé aux architectures à accumulateur pures. Les instructions arithmétiques sont plus rapide, lire un registre étant plus rapide qu'un accès RAM. Les performances sont donc augmentées. De plus, les instructions arithmétiques utilisant ces registres sont plus courtes : pas besoin d'encoder une adresse mémoire, un nom de registre suffit. Vu que les processeurs de l’époque avaient des instructions de taille variable, cela améliorait la densité de code. La microarchitecture de ces processeurs est très similaire à celle d'un processeur avec des registres d'indices. La seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Le banc de registre est systématiquement monoport, car il n'avait aucune raison d'être multiport. Pour les instructions dyadiques, seules à lire deux opérandes, il ne servait que pour la seconde opérande, la première était lue depuis l'accumulateur. Les processeurs hybrides registre-accumulateur se classent en deux types principaux : ceux qui ont un seul bus interne, et ceux qui en ont deux. Le premier cas est identique à celui vu précédemment pour les architectures à accumulateur avec registres d'indice, à la seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Afin de gérer l'adressage indirect à registre, le bus interne est connecté aux deux registres d’interfaçage mémoire. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] Notons que cela permet aussi d'implémenter facilement les branchements indirects, car le bus interne permet d'échanger des adresses entre ''program counter'' et banc de registre. De même, il est possible d'utiliser l'ALU pour gérer les branchements indirects., en plus de l'utiliser pour incrémenter le ''program counter''. [[File:Single bus organization.jpg|centre|vignette|upright=2|Single bus organization]] Une autre solution utilisait deux bus internes : un connecté au bus de données, un autre relié au bus d'adresse. Le bus de commande mémoire était lui commandé par le séquenceur, l'unité de contrôle. L'intermédiaire entre ces deux bus était le banc de registre, ainsi que les autres registres. Le banc de registre était connecté aux deux bus interne, avec un port de lecture relié au bus d'adresse, un port de lecture-écriture relié au bus de données. Le port de lecture était utilisé pour l'adressage indirect, l'autre l'était pour le reste. [[File:Proz1-e.png|centre|vignette|upright=2|Intérieur d'un processeur.]] L'organisation à deux bus simplifiait la gestion du ''program counter'' et le chargement des instructions. Le ''program counter'' était soit séparé du banc de registre, soit placé dans le banc de registre. Les deux solutions étaient utilisés, tout dépend du processeur. Il faut noter que si le ''program counter'' est intégré au banc de registres, alors la microarchitecture du processeur est bien plus simple. L'envoi du ''program counter'' sur le bus d'adresse utilise le port de lecture relié au bus d'adresse, qui sert aussi pour l'adressage indirect. L'économie de circuits, sans compter la simplicité d'implémentation que cela implique, explique sans doute que la technique a été utilisée sur quelques processeurs anciens. Le ''program counter'' était généralement incrémenté par l'ALU, ce qui explique qu'il soit connecté au bus interne pour les données. La connexion est aussi utile pour gérer les branchements indirects, qui copient un registre dans le ''program counter'', ainsi que les branchements relatifs (addition dans l'ALU), voire les branchements directs (l'adresse vers laquelle brancher est envoyée en entrée de l'ALU et propagée en sortie avec une opération ''pass through''). [[File:Connexion du program counter sur les bus avec PC dans le banc de registres.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC dans le banc de registres]] ===Les registres d'interruption avec un processeur hybride-accumulateur : l'exemple du Z80=== Un exemple de processeur registre-accumulateur à deux bus interne est le Z80, un processeur fortement inspiré des CPU Intel 8 bits. Il a un jeu d'instruction similaire, mais a diverses améliorations par rapport au design original. Notamment, le processeur a des registres séparés pour les interruptions. Sur le Z80, les registres généraux sont dupliqués avec 6 registres pour les interruptions et 6 registres pour les programmes autres. Leur copie pour les interruptions sont nommées B', C', D', E', H', L'. Les 12 registres sont placés dans le banc de registre, ce qui implique que le fenêtrage de registres est utilisé pour gérer la séparation entre registre d'interruption et normaux. Il faut noter que l'accumulateur et le registre d'état sont aussi dupliqués, leurs copies étant nommées A' et F'. Mais leur duplication se fait autrement que par fenêtrage de registre. En plus des registres précédents, le Z80 incorporait deux registres d'indice nommés X et Y, ainsi qu'un pointeur de pile SP et un ''program counter'' PC. Ils n'étaient pas dupliqués pour les interruptions. Les registres d'indice étaient reliés à une unité de calcul d'adresse. L'unité de calcul d'adresse prenait deux opérandes : un indice, et une adresse mémoire provenant soit du banc de registre, soit de l'accumulateur. En clair, l'unité de calcul d'adresse faisait le lien entre les deux bus internet : le bus de données interne en entrée, le bus d'adresse en sortie. À l'intérieur du processeur, tous les registres étaient regroupés dans un banc de registre unique, sauf les accumulateurs, les registres d'état et le ''program counter''. Bien que ce ne soit pas indiqué sur le schéma ci-dessous, le ''program counter'' est séparé du banc de registre, alors que le pointeur de pile est dedans. Le compteur IR est lui associé au ''program counter'', il est sortit du banc de registre. Le Z80 utilise lui aussi un incrémenteur séparé de l'ALU, qui est utilisé pour mettre à jour le ''program counter'', le pointeur de pile et un compteur de rafraichissement mémoire nommé IR sur le Z80 (pour rappel, le rafraichissement mémoire demande de balayer la mémoire d'adresse en adresse et été fait par le CPU à l'époque). De plus, il est utilisé pour les instructions INC et DEC qui incrémentent une opérande de 16 bits obtenue en combinant deux registres de 8 bits. En clair, l'incrémenteur du ''program counter'' a été réutilisé de beaucoup de manières originales. [[File:Z80 arch.svg|centre|vignette|upright=3|Microarchitecture du Z80.]] Le Z80 incorporait des instructions pour échanger le contenu des deux ensembles de registres, accumulateur inclus. Elles permettaient d'utiliser les registres d'interruption pour les programmes et réciproquement. En clair, cela doublait le nombre de registres si les interruptions n'étaient pas utilisées. * L'instruction EXX échangeait les deux fenêtres de registres généraux : les registres B, C, D, E, H et L devenaient les registres B', C', D', E', H' et L' et inversement. * L'instruction EX échangeait l'accumulateur et le registre d'état : les registres A,F devenait A',F' et inversement. Le fenêtrage de registre était modifié par l'instruction EXX, qui échangeait les deux fenêtres de registres. Pour l'implémenter, une bascule était ajouté au processeur, appelons-la la bascule INT. Elle était relié au bus d'adresse du banc de registre, dont elle mémorisait le bit de poids fort. L'instruction EXX inversait la valeur de la bascule INT. Il est aussi possible d'échanger le contenu des registres D,E et H,L avec une instruction dédiée, ce qui est là encore fait par deux bascules : une pour les registres D,E et une autre pour les registres H,L. Pour l'accumulateur et le registre d'état, le choix entre registre normal et registre d'interruption se faisait là encore par une seconde bascule appelée la bascule A. La bascule est reliée à un multiplexeur et un démultiplexeur, qui permet de choisir quel accumulateur relier à l'unité de calcul. L'instruction EX inverse le contenu de la bascule A. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=L'unité de contrôle | prevText=L'unité de contrôle | next=Les processeurs 8 bits et moins | nextText=Les processeurs 8 bits et moins }} </noinclude> sxm2bb0icutnps8nsdu9lehlb63k9jj 744137 744136 2025-06-05T00:34:09Z Mewtow 31375 /* Le jeu d'instruction des architectures à accumulateur sans registres d'indice */ 744137 wikitext text/x-wiki Les architectures que nous avons vu précédemment dans ce cours disposent de registres pour les données, en plus du pointeur de pile, d'un ''program counter'', et de quelques autres. Elles sont appelées des '''architectures à registres''', terme qui trahit bien le fait qu'elles ont des registres généraux ou spécialisés pour stocker temporairement des données. Et si on leur a donné un nom, c'est parce qu'il existe des architectures qui ne sont pas dans cette catégorie. Il en existe plusieurs types, mais ce chapitre va se concentrer sur les '''architectures à accumulateur'''. [[File:Isaccumulator.png|vignette|Architecture à accumulateur.]] Les architectures à accumulateur sont centrées autour d'un registre architectural appelé l''''accumulateur'''. Il est utilisé pour toutes les opérations arithmétiques dyadiques, où il sert à la fois de source et de destination. Toutes les instructions dyadiques sont de type ''load-op'' : une opérande est lue depuis l'accumulateur, le second opérande est lu depuis la mémoire RAM, le résultat de l'instruction est automatiquement mémorisé dans l'accumulateur. Les instructions monadiques peuvent utiliser un opérande dans l'accumulateur, ou dans la mémoire RAM, les deux sont théoriquement possibles. La conséquence est que le nombre d'accès mémoire est drastiquement diminué : de 3 par instructions sur une architecture mémoire-mémoire, on passe à seulement un avec un accumulateur. Les opérations dyadiques ont besoin d'un seul accès mémoire pour lire la seconde opérande, les opérations monadique en font aussi un seul pour lire leur unique opérande. {|class="wikitable" |- ! Classe d'architecture ! Nombre d'accès mémoire par opération dyadique |- |- ! Architecture à accumulateur | Un accès mémoire par instruction, pour lire la seconde opérande |- ! Architecture à registres | Zéro si les opérandes sont dans les registres, un pour les opérations ''load-op'', LOAD et STORE. |} ==Le jeu d'instruction des architectures à accumulateur sans registres d'indice== L'accumulateur est adressé grâce au mode d'adressage implicite, de même que le résultat de l'opération. Par contre, les autres opérandes sont localisés avec d'autres modes d'adressage, et lues en mémoire RAM. Le résultat ainsi qu'un des opérandes sont adressés de façon implicite car dans l'accumulateur, seule la seconde opérande étant adressée directement. Grâce à l'accumulateur, une instruction ne fait qu'un seul accès mémoire maximum, ce qui rend le processeur très facile à implémenter. ===Les registres des anciennes architectures à accumulateur=== [[File:IBM 701console.jpg|vignette|IBM 701, console extérieure.]] Les architectures à accumulateur étaient communes dans les années 50-60. A l'époque, les ordinateurs étaient gigantesques, ils prenaient une pièce de bâtiment entière dans le pire des cas, une armoire entière dans le meilleur. Les ordinateurs de l'époque étaient surtout utilisés pour du calcul scientifique ou des tâches d’ingénierie demandant beaucoup de calcul, rarement pour de la compatibilité. Les nombres flottants n'étaient pas encore apparus. A la place, les ordinateurs de l'époque géraient des nombres entiers de grande taille, de 30 bits ou plus. En conséquence, l'accumulateur faisait facilement 30 à 60 bits. Par exemple, les ordinateurs de la Série scientifique IBM 700/7000 géraient des entiers de 36 bits, l’accumulateur faisait 38 bits : 36 bits plus deux bits pour les débordements. Au passage, de tels processeurs utilisaient l'adressage par mot, et non par byte. Historiquement, les premières architectures à accumulateur ne contenaient aucun autre registre que l'accumulateur. Ce n'est que dans les années 60 que de nombreuses architectures à accumulateur ont ajouté un second '''registre pour les multiplication/divisions'''. Un exemple est celui de l'IBM 701, qui incorporait un registre accumulateur de 38 bits et un registre multiplieur de 36 bits. Le registre mémorise le multiplieur lors d'une opération de multiplication. Il mémorise donc un opérande, pas le résultat. Il peut aussi décaler le multiplieur vers la droite/gauche, ce qui est utile pour exécuter la multiplication. C'est ce qui est fait sur l'IBM 7094. Une autre possibilité est que ce registre mémorise une partie du résultat de l'opération. Pour rappel, le résultat d'une multiplication/division est codé sur deux fois de bits que ses opérandes. Par exemple, multipliez deux opérandes de 30 bits, vous obtiendrez un résultat de 60 bits. Les 30 bits de poids faible du résultat vont dans l'accumulateur, les 30 bits de poids fort vont dans ce second registre. Les architectures à accumulateur parfois un '''registre pour le pointeur de pile''', utilisé pour gérer les fonctions/procédures. Les architectures à accumulateurs supportaient une pile d'adresse de retour, souvent une pile d'appel. Mais pour cela, il fallait mémoriser le pointeur de pile dans le processeur, ce qui demandait un registre dédié. ===L'adressage indirect avec l'accumulateur=== Les instructions LOAD et STORE existent bel et bien sur les architectures à accumulateur, mais n'ont pas les mêmes modes d'adressages. L'instruction LOAD copie une donnée de la RAM vers l'accumulateur, l'instruction STORE copie l'accumulateur dans une adresse. Les deux instructions n'ont pas besoin d'adresser l'accumulateur, qui est adressé de manière implicite, juste de préciser l'adresse à lire/écrire. Les architectures à accumulateur supportaient souvent le mode d'adressage indirect mémoire. Un exemple est celui des ordinateurs Data General Nova, qui sont des architectures à accumulateur et qui supportaient ce mode d'adressage. Les deux instructions LOAD et STORE existaient en deux versions, distinguées par un bit d'indirection. Si ce bit est à 0 dans l'opcode, alors l'instruction utilise le mode d'adressage absolu normal : l'adresse intégrée dans l'instruction est celle de la donnée. Mais s'il est à 1, alors l'adresse intégrée dans l'instruction est celle du pointeur. Cependant, la présence de l'accumulateur permettait d'utiliser l'adressage indirect à registre, pour gérer les pointeurs. Pour rappel, avec le mode d'adressage indirect à registre, l'adresse à lire/écrire est dans un registre. Ici, l'adresse à lire/écrire est prise dans l'accumulateur, seul registre disponible pour. L'adressage indirect est plus simple à implémenter pour l'instruction LOAD, car elle prend un seul opérande : l'adresse à lire. L'adresse à lire est placée dans l'accumulateur, la donnée lue est elle aussi chargée dans l'accumulateur. Pour l'instruction STORE, il faut fournir deux opérandes, l'adresse et la donnée à écrire, ce qui peut poser problème. Mais au pire, il est toujours possible d'utiliser l'adressage absolu ou indirect mémoire : l'adresse est dans l'instruction, la donnée à écrire dans l'accumulateur. ===L'encodage des instructions=== Sur une architecture à accumulateur l'encodage d'une instruction dyadique est assez simple, vu que l'accumulateur est adressé implicitement. La seconde opérande est localisée soit par une adresse mémoire (adressage absolu), soit est une constante (adressage immédiat). L'adresse mémoire est généralement assez longue, plus que l'opcode. {|class="wikitable" |+ Encodage d'une instruction dyadique |- ! rowspan="2" | Opcode | Adresse mémoire (adressage absolu) |- | Constante (adressage immédiat) |} L'encodage d'une instruction monadique est similaire. Si l'opérande est lue depuis la mémoire RAM, alors l'instruction est encodée comme une instruction dyadique. Il en est de même pour les instructions qui copient une constante dans l'accumulateur. Par contre, si l'opérande est dans l'accumulateur, alors il y a juste besoin d'encoder l'opcode. La majorité des instructions a besoin de préciser une adresse, rares sont celles qui s'en passent. Au vu de cet encodage, les architectures à accumulateur sont qualifiées d''''architectures à une adresse''' par abus de langage. Il est intéressant de contraster leur encodage avec les architectures à registres. Les architectures à registre doivent encoder deux opérandes en plus de l'opcode, avec éventuellement où enregistrer le résultat sur les architectures 3-adresses. Par contre, les opérandes sont généralement des noms de registre, ce qui prend moins de place qu'une adresse mémoire. A la rigueur, les instructions avec une constante immédiate prennent un peu plus de place, car elles doivent encoder un nom de registre en plus de la constante et de l'opcode. Les instructions ''load-op'' des processeurs CISC sont un peu dans le même cas, sauf qu'il faut remplacer la constante par une adresse, qui a généralement la même taille. Les instructions sont donc en moyenne plus courte sur les processeurs à registre, du fait de la présence de registres. ===Annexe : les toutes premières architectures à accumulateur : le Manchester Baby=== [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] Les architectures à accumulateurs sont apparues dès les débuts de l'informatique. Le tout premier ordinateur à programme enregistré en mémoire, le ''Manchester Baby'', était une architecture à accumulateur. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 adresses de 32 bits, fabriquée avec des tubes Williams (abordés dans une annexe à la fin du cours). Le programme devait tenir dans la RAM, avec une instruction par adresse maximum, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 servait à indiquer où se trouvent les opérandes en RAM, les 16 restants sont inutilisés. Le processeur avait un registre accumulateur de 32 bits, un ''program counter'' et un registre d'instruction. Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. C'était là encore une architecture à accumulateur, sauf qu'elle intégrait aussi des registres d'indice. Et surtout : son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. ==La micro-architecture des architectures à accumulateur sans registres d'indice== L'organisation interne d'une architecture à accumulateur est très différente de celle des processeurs à registre. Elle est plus ou moins la même pour tous ces processeurs, le point important étant que le chemin de données se résume à une ALU, un registre accumulateur et le bus de données. L'ALU est reliée au registre accumulateur, ainsi qu'au bus de données pour lire la seconde opérande, comme illustré ci-dessous. [[File:Accumulator.png|centre|vignette|upright=2|Accumulateur.]] ===L'unité de calcul et l'accumulateur=== Pour simplifier l'implémentation, le résultat est mémorisé dans un registre en sortie de l'unité de calcul. La raison est qu'on ne veut pas altérer l'accumulateur tant que le résultat final n'est pas totalement calculé. Rappelons que l'ALU ne fournit pas un résultat d'un seul bloc, mais que certains bits arrivent avant les autres, typiquement les bits de poids faible. Si le résultat était écrit dans l'accumulateur directement, il écraserait des bits de l’opérande en cours d'utilisation, ce qui fausserait le résultat. [[File:Accumulateur avec registre de sortie.png|centre|vignette|upright=2|Accumulateur avec registre de sortie]] Une autre solution utilisait un registre entre l'accumulateur et l'unité de calcul, appelé l’'''''accumulator latch'''''. Il remplace le registre en sortie de l'ALU, dans le sens où il permet d'écrire dans l'accumulateur sans effacer l'opérande, pendant que l’opération est en cours dans l'ALU. L'accumulateur est copié dans l’''accumulator latch'', avant que l'ALU démarre ses calculs. L'opérande est donc maintenue même si on commence à écrire le résultat dans l'accumulateur. Sur le 8085 d'Intel, l’''accumulator latch'' peut être initialisé avec une constante prédéfinie, ce qui permet d'implémenter certaines instructions très facilement. Par exemple, il peut être initialisé à 0, ce qui permet d'implémenter les instructions MOV et INC (incrémentation). Un MOV est équivalent à faire un OU entre le registre lu et 0. Une instruction INC initialise l'entrée de retenue de l'unité de calcul à 1, puis ajoute 0. La décrémentation est implémentée de la même manière, sauf que l’''accumulator latch'' est initialisé à -2 pour compenser l'entrée de retenue à 1. De plus, pour supporter les conversion de décimal à BCD, l’''accumulator latch'' peut être initialisé avec les constantes 0x00, 0x06, 0x60, or 0x66. L'''accumulator latch'' est relié à divers fils de commande provenant de l'unité de contrôle, qui décide quelle valeur d'initialisation utiliser en fonction de l'instruction décodée. [[File:Accumulator latch.png|centre|vignette|upright=2|Accumulator latch]] [[File:Chemin de données à un seul bus.png|vignette|Chemin de données à un seul bus]] De même, la seconde opérande, celle lue sur le bus de données, est mémorisée dans un registre en amont de l'ALU. C'était notamment très utile si le processeur utilisait une ALU plus courte que les opérandes, avec par exemple une ALU 4 bits pour un CPU 8 bits. Les anciens processeurs à accumulateur de type ''mainframe'' utilisaient des opérandes de grande taille, du genre 36 ou 48 bits, ce qui avait des conséquences sur l'unité de calcul utilisée, ainsi que sur la communication avec la mémoire. Il arrivait que de tels processeurs utilisaient des ALU sérielles, ou du moins octet-sérielles, plutôt qu'une véritable ALU 36 bits. Nous verrons aussi que c'est très utile sur les processeurs à accumulateur avec un bus interne unique, dans la suite du chapitre. ===La micro-architecture des architectures à accumulateur avec instructions LOAD/STORE=== Nous venons de voir comment est implémenté l'unité de calcul et l'accumulateur, et comment le tout est relié au bus de données. Mais cela ne permet que d'avoir un processeur à accumulateur rudimentaire, qui ne gére que des instructions arithmétiques et logiques. Il faut aussi gérer le cas des opérations LOAD/STORE et des modes d'adressages associés, mais c'est le séquenceur qui s'en occupe. Avec l'adressage absolu, les instructions LOAD et STORE ne font que connecter l'accumulateur au bus de données. L'instruction STORE nécessite de connecter l'accumulateur au bus de données, de manière à ce que le transfert des données se fasse de l'accumulateur vers le bus de données. L'instruction LOAD s'implémente de la même manière, sauf que le sens de transfert est inversé. Cependant, il existe une optimisation qui permet d'implémenter l'instruction LOAD sans ajouter de circuits. Pour cela, il suffit que l'unité de calcul gére les opérations ''pass through'', à savoir des opérations qui se contentent de recopier un opérande sur la sortie. Ici, l'idée est de recopier l'opérande provenant du bus de données. [[File:Architecture à accumulateur, microarchitecture.png|centre|vignette|upright=2|Architecture à accumulateur, microarchitecture]] Pour gérer nativement l'adressage indirect à registre, il suffit de connecter l'accumulateur au bus d'adresse. Le plus simple est d'ajouter un multiplexeur, comme illustré ci-dessous. La donnée lue est copiée dans l'accumulateur, ce qui fait qu'il vaut mieux utiliser un registre d’interfaçage, l'accumulateur n'étant pas utilisable à la fois pour le bus d'adresse et de données. [[File:Adressage indirect sur une architecture à accumulateur.png|centre|vignette|upright=2|Adressage indirect sur une architecture à accumulateur]] Pour finir, voyons comment le pointeur de pile et le ''program counter'' sont implémentés. Les architectures à accumulateur ont souvent des adresses de taille différente des données, ce qui fait qu'il vaut mieux utiliser un circuit incrémenteur dédié pour incrémenter le ''program counter'', plutôt que de l'incrémenter via l'unité de calcul. Les architectures à accumulateur ont parfois un pointeur de pile, qui gère une pile d'adresse de retour, pas une vraie pile d'appel. Aussi, le pointeur de pile est censé être incrémenté et décrémenté, pas plus. Pas d'addition ou de soustraction pour gérer des cadres de pile. Là encore, c'est la solution de l'incrémenteur séparé qui est retenue. Pour économiser des transistors, il n'y a qu'un seul incrémenteur partagé pour les deux. ==Les architectures à accumulateur à registres d'indice== Les architectures à accumulateur décrites dans la section précédente sont capables de faire de l'adressage indirect, mais n'incluent pas les modes d'adressage base + indice et absolus indicés, qui prennent une adresse et y ajoute un indice. Il s'agit des toutes premières architectures à accumulateur, comme les premiers ordinateurs IBM ou le fameux PDP-8. Mais par la suite, les processeurs à accumulateurs ont inclus un support des modes d'adressages indicés, grâce à des '''registres d'indice'''. ===Les registres d'indice=== Les registres d'indice stockent des indices de tableaux. Ils permettaient de supporter deux modes d'adressage : * Le '''mode d'adressage absolu indicé''' où une adresse fixe est additionnée à un indice variable. L'adresse fixe est intégrée dans l'instruction (adressage absolu), l'indice est dans un registre d'indice. * Le '''mode d'adressage base + indice''', où l'adresse est dans l'accumulateur et l'indice dans le registre d'indice. Les processeurs à accumulateur supportaient souvent des variantes des modes d'adressage précédents, où le registre d'indice était automatiquement incrémenté ou décrémenté à chaque utilisation. Au départ, ces processeurs n'utilisaient qu'un seul registre d'indice qui se comportait comme un second accumulateur spécialisé dans les calculs d'adresses mémoire. Le processeur supportait de nouvelles instructions qui utilisaient ce registre d'indice de façon implicite. Mais avec le temps, les processeurs finirent par incorporer plusieurs de ces registres. Les instructions de lecture ou d'écriture devaient alors préciser quel registre d'indice utiliser, en précisant un nom de registre d'indice, un numéro de registre d'indice. Il faut préciser que les registres d'indice ont une taille bien plus petite que l'accumulateur. Ils mémorisent des indices codés sur 16 bits ou moins, alors que l'accumulateur faisait typiquement 36 à 48 bits, parfois plus. La taille classique sur les anciens ''mainframes'' était de 15 bits, parfois moins. Il n'était pas rare de tomber sur des registres d'indice de 8 ou 9 bits. Leur petite taille rendait leur implémentation matérielle peu couteuse. Et c'est ce qui explique qu'ils étaient préférés à l'usage d'un second accumulateur. Un exemple est le cas du processeur Motorola 6809, un processeur à accumulateur qui contient deux registres d'indices nommés X et Y. L'accumulateur est noté D et fait 16 bits, il peut être parfois géré comme deux accumulateurs séparés A et B de 8 bits chacun. Il contenait aussi deux pointeurs de pile, l'un pour les programmes, l'autre pour le système d'exploitation, ainsi qu'un ''program counter''. Le registre de page était utilisé pour l'adressage absolu, comme vu dans le chapitre sur les modes d'adressage. [[File:6809 Internal Registers.svg|centre|vignette|upright=2|6809 Internal Registers]] Les processeurs IBM avaient autrefois plusieurs registres d'indice. Par exemple, l'IBM 704 avait trois registres d'indice de 15 bits. Leur contenu était soustrait de l'adresse absolue. Une instruction pouvait utiliser plusieurs registres d'indice pour adresser son opérande. Toute instruction utilisait trois bits pour sélectionner les registres d'indice utilisés. Fait assez original, lorsque plusieurs registres d'indice sont sélectionnés, le processeur n'additionne pas les trois registres à l'adresse de base. À la place, il fait un OU bit à bit entre les registres d'indice sélectionnés, et additionne le résultat à l'adresse. Les processeurs IBM à accumulateur ont fait ça sur toute la gamme IBM 700/7000, pour des raisons de compatibilité. Les processeurs suivants avaient 7 registres d'indices, mais conservaient les trois bits pour adresser les registres d'indices. Ils pouvaient fonctionner dans deux modes. Le premier mode est plus intuitif : les trois bits précisent un registre d'indice parmi les 7, qui est additionné avec l'adresse absolue. La valeur zéro indique qu'aucun registre d'indice n'est utilisé, ce qui explique qu'il y a 7 registres d'indice et non 8. Un second mode, compatible avec l'IBM 704, fait un OU logique entre les registres d'indice sélectionnés. Seuls les trois premiers registres d'indices peuvent être sélectionnés dans ce mode. Il y a deux instructions pour changer de mode : une pour passer en mode compatible, l'autre pour le quitter pour l'autre mode. Quelques rares processeurs à registres généraux ont utilisés des registres d'indice, en plus des registres généraux. Ce qui fait l'association que nous avons faite entre registres d'indice et architectures à accumulateur est imparfait, bien que solide sur le principe. Un exemple d'architecture de ce type sont les architectures de la série UNIVAC 1100/2200. Ils disposaient de 128 registres, qui étaient mappés en mémoire à partir de l'adresse mémoire 0, la majorité étant inaccessibles par le programmeur. Ils regroupaient 12 registres accumulateurs, 11 registres d'indice et 4 registres hybrides qui pouvaient servir soit de registre d'indice, soit de registres accumulateurs. ===La micro-architecture des architectures à accumulateur avec registres d'indice=== La présence de registres d'indice modifie grandement l'implémentation du processeur. En effet, il faut rajouter un banc de registre pour les registres d'indice. Le banc de registre est monoport, car on a besoin de lire ou d'écrire un indice à la fois. Et il faut aussi potentiellement rajouter de quoi faire les calculs d'adresse. Deux solutions sont possibles : une ALU dédiée aux calculs d'adresse, une seule ALU pour toutes les opérations. Dans le premier cas, il y a une ALU séparée associée aux registres d'indice. L'ALU et les registres d'indice sont placés en sortie du séquenceur, en-dehors du chemin de données, la sortie de l'ALU est directement connectée au bus d'adresse. L'unité de calcul d'adresse peut être utilisée pour incrémenter le ''program counter''. Un défaut de cette approche est qu'elle ne gère pas l'adresse indirect à registre. [[File:Chemin de données sans support des pointeurs, avec adressage absolu indicé.png|centre|vignette|upright=2|Chemin de données sans support des pointeurs, avec adressage absolu indicé]] Une autre option utilise un bus interne, qui interconnecte tout le chemin de données. Dans sa version la plus simple, il est relié à l'accumulateur, l'unité de calcul, le banc de registre d'indice et le bus de données. Avec cette solution, l'ALU est utilisé à la fois pour calculer les adresses et pour les instructions de calcul. En reliant le bus interne au bus d'adresse à travers un multiplexeur, on gère naturellement les adressages indirects. [[File:Architecture à accumulateur avec registres associés.png|centre|vignette|upright=2.5|Architecture à accumulateur avec registres associés]] Il faut noter que sur les architectures Von Neumann, le séquenceur est relié à ce bus interne. En effet, charger une instruction demande de passer par le bus mémoire, donc par l’intermédiaire de ce bus internet. Le ''program counter'' est envoyé sur ce bus pour lire l'instruction, puis l'instruction lue est recopiée dans le registre d'instruction. Le chargement d'une instruction est donc géré comme une lecture des plus classiques. De plus, cela permet d'incrémenter le ''program counter'' au niveau de l'unité de calcul entière. Le ''program counter'' est envoyé sur le bus interne, incrémenté par l'ALU, puis le résultat est recopié dans le ''program counter'' via le bus interne. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] ==Les processeurs bi-accumulateurs : le Motorola 6800== Le Motorola 6800 était un processeur 8 bits qui gérait des adresses de 16 bits. Il contenait deux accumulateurs nommés A et B, de 8 bits chacun. Il disposait aussi d'un registre d'indice, d'un pointeur de pile et d'un ''program counter'', tous les trois de 16 bits. Le registre d'état regroupait 6 bits, qu'on ne détaillera pas ici. [[File:MC6800 Processor Diagram.png|centre|vignette|upright=2|Interface et registres du MC6800.]] La présence des deux accumulateurs impactait surtout les instructions dyadiques. Les instructions monadiques avaient juste à préciser où se trouvait l'opérande : soit en RAM, soit dans le premier accumulateur, soit dans le second. Pour les opérations dyadiques, la gestion était totalement différente. En théorie, le premier opérande est dans un accumulateur, soit A, soit B. La seconde opérande vient soit de l'autre accumulateur, soit de la mémoire RAM. Et selon les instructions, tout variait. Pour l'addition, il y avait trois instructions. Les deux premières additionnaient un opérande provenant de la mémoire avec un accumulateur. L'instruction ADDA sélectionnait le premier accumulateur, l'instruction ADDB sélectionnait le second accumulateur. Mais une troisième instruction, l’instruction ABA, permettait d'additionner le contenu des deux accumulateurs. Pour les autres opérations, il n'était pas possible d'utiliser les deux accumulateurs en même temps. La seule possibilité était de faire une opération entre un accumulateur et un opérande venant de la mémoire. Toutes les instructions étaient en double, avec une copie par accumulateur. Par exemple, l'instruction ANDA faisait un ET entre l’accumulateur A et l'opérande mémoire, l'instruction ANDB faisait pareil avec l'accumulateur B. ==Les architectures hybrides registres-accumulateur== Il a existé quelques architectures qui étaient des hybrides entre architectures à accumulateur et architecture à registre. Elles ont servi de transition entre les deux, durant les années 80-90. Elles avaient un accumulateur unique couplé à un banc de registres généraux. Par exemple, les premiers processeurs Intel 8 bits étaient des processeurs hybrides-accumulateur. Lles CPU Intel 8 bits disposaient de 7 registres de 8 bits nommés A, B, C, D, E, F, H, L, SP. Ils correspondent respectivement à : * l'accumulateur A ; * six registres nommés B, C, D, E, H et L ; * le registre d'état F ; * le pointeur de pile SP. Sur ces processeurs, les instructions dyadiques devaient mettre leur premier opérande dans l'accumulateur, la seconde provenait soit des registres, soit de la RAM, soit d'une constante immédiate. Les opérations monadiques pouvaient lire leur opérande depuis l'accumulateur, les autres registres ou la RAM, tout était permis. Les registres d'indices disparaissaient sur ces architectures, en théorie. Les registres généraux pouvaient être utilisés comme registre d'indice ou pour stocker des opérandes, ils étaient assez versatiles pour servir de registres d'indices. La présence de registres a de nombreux avantages, comparé aux architectures à accumulateur pures. Les instructions arithmétiques sont plus rapide, lire un registre étant plus rapide qu'un accès RAM. Les performances sont donc augmentées. De plus, les instructions arithmétiques utilisant ces registres sont plus courtes : pas besoin d'encoder une adresse mémoire, un nom de registre suffit. Vu que les processeurs de l’époque avaient des instructions de taille variable, cela améliorait la densité de code. La microarchitecture de ces processeurs est très similaire à celle d'un processeur avec des registres d'indices. La seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Le banc de registre est systématiquement monoport, car il n'avait aucune raison d'être multiport. Pour les instructions dyadiques, seules à lire deux opérandes, il ne servait que pour la seconde opérande, la première était lue depuis l'accumulateur. Les processeurs hybrides registre-accumulateur se classent en deux types principaux : ceux qui ont un seul bus interne, et ceux qui en ont deux. Le premier cas est identique à celui vu précédemment pour les architectures à accumulateur avec registres d'indice, à la seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Afin de gérer l'adressage indirect à registre, le bus interne est connecté aux deux registres d’interfaçage mémoire. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] Notons que cela permet aussi d'implémenter facilement les branchements indirects, car le bus interne permet d'échanger des adresses entre ''program counter'' et banc de registre. De même, il est possible d'utiliser l'ALU pour gérer les branchements indirects., en plus de l'utiliser pour incrémenter le ''program counter''. [[File:Single bus organization.jpg|centre|vignette|upright=2|Single bus organization]] Une autre solution utilisait deux bus internes : un connecté au bus de données, un autre relié au bus d'adresse. Le bus de commande mémoire était lui commandé par le séquenceur, l'unité de contrôle. L'intermédiaire entre ces deux bus était le banc de registre, ainsi que les autres registres. Le banc de registre était connecté aux deux bus interne, avec un port de lecture relié au bus d'adresse, un port de lecture-écriture relié au bus de données. Le port de lecture était utilisé pour l'adressage indirect, l'autre l'était pour le reste. [[File:Proz1-e.png|centre|vignette|upright=2|Intérieur d'un processeur.]] L'organisation à deux bus simplifiait la gestion du ''program counter'' et le chargement des instructions. Le ''program counter'' était soit séparé du banc de registre, soit placé dans le banc de registre. Les deux solutions étaient utilisés, tout dépend du processeur. Il faut noter que si le ''program counter'' est intégré au banc de registres, alors la microarchitecture du processeur est bien plus simple. L'envoi du ''program counter'' sur le bus d'adresse utilise le port de lecture relié au bus d'adresse, qui sert aussi pour l'adressage indirect. L'économie de circuits, sans compter la simplicité d'implémentation que cela implique, explique sans doute que la technique a été utilisée sur quelques processeurs anciens. Le ''program counter'' était généralement incrémenté par l'ALU, ce qui explique qu'il soit connecté au bus interne pour les données. La connexion est aussi utile pour gérer les branchements indirects, qui copient un registre dans le ''program counter'', ainsi que les branchements relatifs (addition dans l'ALU), voire les branchements directs (l'adresse vers laquelle brancher est envoyée en entrée de l'ALU et propagée en sortie avec une opération ''pass through''). [[File:Connexion du program counter sur les bus avec PC dans le banc de registres.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC dans le banc de registres]] ===Les registres d'interruption avec un processeur hybride-accumulateur : l'exemple du Z80=== Un exemple de processeur registre-accumulateur à deux bus interne est le Z80, un processeur fortement inspiré des CPU Intel 8 bits. Il a un jeu d'instruction similaire, mais a diverses améliorations par rapport au design original. Notamment, le processeur a des registres séparés pour les interruptions. Sur le Z80, les registres généraux sont dupliqués avec 6 registres pour les interruptions et 6 registres pour les programmes autres. Leur copie pour les interruptions sont nommées B', C', D', E', H', L'. Les 12 registres sont placés dans le banc de registre, ce qui implique que le fenêtrage de registres est utilisé pour gérer la séparation entre registre d'interruption et normaux. Il faut noter que l'accumulateur et le registre d'état sont aussi dupliqués, leurs copies étant nommées A' et F'. Mais leur duplication se fait autrement que par fenêtrage de registre. En plus des registres précédents, le Z80 incorporait deux registres d'indice nommés X et Y, ainsi qu'un pointeur de pile SP et un ''program counter'' PC. Ils n'étaient pas dupliqués pour les interruptions. Les registres d'indice étaient reliés à une unité de calcul d'adresse. L'unité de calcul d'adresse prenait deux opérandes : un indice, et une adresse mémoire provenant soit du banc de registre, soit de l'accumulateur. En clair, l'unité de calcul d'adresse faisait le lien entre les deux bus internet : le bus de données interne en entrée, le bus d'adresse en sortie. À l'intérieur du processeur, tous les registres étaient regroupés dans un banc de registre unique, sauf les accumulateurs, les registres d'état et le ''program counter''. Bien que ce ne soit pas indiqué sur le schéma ci-dessous, le ''program counter'' est séparé du banc de registre, alors que le pointeur de pile est dedans. Le compteur IR est lui associé au ''program counter'', il est sortit du banc de registre. Le Z80 utilise lui aussi un incrémenteur séparé de l'ALU, qui est utilisé pour mettre à jour le ''program counter'', le pointeur de pile et un compteur de rafraichissement mémoire nommé IR sur le Z80 (pour rappel, le rafraichissement mémoire demande de balayer la mémoire d'adresse en adresse et été fait par le CPU à l'époque). De plus, il est utilisé pour les instructions INC et DEC qui incrémentent une opérande de 16 bits obtenue en combinant deux registres de 8 bits. En clair, l'incrémenteur du ''program counter'' a été réutilisé de beaucoup de manières originales. [[File:Z80 arch.svg|centre|vignette|upright=3|Microarchitecture du Z80.]] Le Z80 incorporait des instructions pour échanger le contenu des deux ensembles de registres, accumulateur inclus. Elles permettaient d'utiliser les registres d'interruption pour les programmes et réciproquement. En clair, cela doublait le nombre de registres si les interruptions n'étaient pas utilisées. * L'instruction EXX échangeait les deux fenêtres de registres généraux : les registres B, C, D, E, H et L devenaient les registres B', C', D', E', H' et L' et inversement. * L'instruction EX échangeait l'accumulateur et le registre d'état : les registres A,F devenait A',F' et inversement. Le fenêtrage de registre était modifié par l'instruction EXX, qui échangeait les deux fenêtres de registres. Pour l'implémenter, une bascule était ajouté au processeur, appelons-la la bascule INT. Elle était relié au bus d'adresse du banc de registre, dont elle mémorisait le bit de poids fort. L'instruction EXX inversait la valeur de la bascule INT. Il est aussi possible d'échanger le contenu des registres D,E et H,L avec une instruction dédiée, ce qui est là encore fait par deux bascules : une pour les registres D,E et une autre pour les registres H,L. Pour l'accumulateur et le registre d'état, le choix entre registre normal et registre d'interruption se faisait là encore par une seconde bascule appelée la bascule A. La bascule est reliée à un multiplexeur et un démultiplexeur, qui permet de choisir quel accumulateur relier à l'unité de calcul. L'instruction EX inverse le contenu de la bascule A. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=L'unité de contrôle | prevText=L'unité de contrôle | next=Les processeurs 8 bits et moins | nextText=Les processeurs 8 bits et moins }} </noinclude> kqnefcjy1a2i92ec6iisa6ryw66pb6y 744139 744137 2025-06-05T00:34:32Z Mewtow 31375 /* Annexe : les toutes premières architectures à accumulateur : le Manchester Baby */ 744139 wikitext text/x-wiki Les architectures que nous avons vu précédemment dans ce cours disposent de registres pour les données, en plus du pointeur de pile, d'un ''program counter'', et de quelques autres. Elles sont appelées des '''architectures à registres''', terme qui trahit bien le fait qu'elles ont des registres généraux ou spécialisés pour stocker temporairement des données. Et si on leur a donné un nom, c'est parce qu'il existe des architectures qui ne sont pas dans cette catégorie. Il en existe plusieurs types, mais ce chapitre va se concentrer sur les '''architectures à accumulateur'''. [[File:Isaccumulator.png|vignette|Architecture à accumulateur.]] Les architectures à accumulateur sont centrées autour d'un registre architectural appelé l''''accumulateur'''. Il est utilisé pour toutes les opérations arithmétiques dyadiques, où il sert à la fois de source et de destination. Toutes les instructions dyadiques sont de type ''load-op'' : une opérande est lue depuis l'accumulateur, le second opérande est lu depuis la mémoire RAM, le résultat de l'instruction est automatiquement mémorisé dans l'accumulateur. Les instructions monadiques peuvent utiliser un opérande dans l'accumulateur, ou dans la mémoire RAM, les deux sont théoriquement possibles. La conséquence est que le nombre d'accès mémoire est drastiquement diminué : de 3 par instructions sur une architecture mémoire-mémoire, on passe à seulement un avec un accumulateur. Les opérations dyadiques ont besoin d'un seul accès mémoire pour lire la seconde opérande, les opérations monadique en font aussi un seul pour lire leur unique opérande. {|class="wikitable" |- ! Classe d'architecture ! Nombre d'accès mémoire par opération dyadique |- |- ! Architecture à accumulateur | Un accès mémoire par instruction, pour lire la seconde opérande |- ! Architecture à registres | Zéro si les opérandes sont dans les registres, un pour les opérations ''load-op'', LOAD et STORE. |} ==Le jeu d'instruction des architectures à accumulateur sans registres d'indice== L'accumulateur est adressé grâce au mode d'adressage implicite, de même que le résultat de l'opération. Par contre, les autres opérandes sont localisés avec d'autres modes d'adressage, et lues en mémoire RAM. Le résultat ainsi qu'un des opérandes sont adressés de façon implicite car dans l'accumulateur, seule la seconde opérande étant adressée directement. Grâce à l'accumulateur, une instruction ne fait qu'un seul accès mémoire maximum, ce qui rend le processeur très facile à implémenter. ===Les registres des anciennes architectures à accumulateur=== [[File:IBM 701console.jpg|vignette|IBM 701, console extérieure.]] Les architectures à accumulateur étaient communes dans les années 50-60. A l'époque, les ordinateurs étaient gigantesques, ils prenaient une pièce de bâtiment entière dans le pire des cas, une armoire entière dans le meilleur. Les ordinateurs de l'époque étaient surtout utilisés pour du calcul scientifique ou des tâches d’ingénierie demandant beaucoup de calcul, rarement pour de la compatibilité. Les nombres flottants n'étaient pas encore apparus. A la place, les ordinateurs de l'époque géraient des nombres entiers de grande taille, de 30 bits ou plus. En conséquence, l'accumulateur faisait facilement 30 à 60 bits. Par exemple, les ordinateurs de la Série scientifique IBM 700/7000 géraient des entiers de 36 bits, l’accumulateur faisait 38 bits : 36 bits plus deux bits pour les débordements. Au passage, de tels processeurs utilisaient l'adressage par mot, et non par byte. Historiquement, les premières architectures à accumulateur ne contenaient aucun autre registre que l'accumulateur. Ce n'est que dans les années 60 que de nombreuses architectures à accumulateur ont ajouté un second '''registre pour les multiplication/divisions'''. Un exemple est celui de l'IBM 701, qui incorporait un registre accumulateur de 38 bits et un registre multiplieur de 36 bits. Le registre mémorise le multiplieur lors d'une opération de multiplication. Il mémorise donc un opérande, pas le résultat. Il peut aussi décaler le multiplieur vers la droite/gauche, ce qui est utile pour exécuter la multiplication. C'est ce qui est fait sur l'IBM 7094. Une autre possibilité est que ce registre mémorise une partie du résultat de l'opération. Pour rappel, le résultat d'une multiplication/division est codé sur deux fois de bits que ses opérandes. Par exemple, multipliez deux opérandes de 30 bits, vous obtiendrez un résultat de 60 bits. Les 30 bits de poids faible du résultat vont dans l'accumulateur, les 30 bits de poids fort vont dans ce second registre. Les architectures à accumulateur parfois un '''registre pour le pointeur de pile''', utilisé pour gérer les fonctions/procédures. Les architectures à accumulateurs supportaient une pile d'adresse de retour, souvent une pile d'appel. Mais pour cela, il fallait mémoriser le pointeur de pile dans le processeur, ce qui demandait un registre dédié. ===L'adressage indirect avec l'accumulateur=== Les instructions LOAD et STORE existent bel et bien sur les architectures à accumulateur, mais n'ont pas les mêmes modes d'adressages. L'instruction LOAD copie une donnée de la RAM vers l'accumulateur, l'instruction STORE copie l'accumulateur dans une adresse. Les deux instructions n'ont pas besoin d'adresser l'accumulateur, qui est adressé de manière implicite, juste de préciser l'adresse à lire/écrire. Les architectures à accumulateur supportaient souvent le mode d'adressage indirect mémoire. Un exemple est celui des ordinateurs Data General Nova, qui sont des architectures à accumulateur et qui supportaient ce mode d'adressage. Les deux instructions LOAD et STORE existaient en deux versions, distinguées par un bit d'indirection. Si ce bit est à 0 dans l'opcode, alors l'instruction utilise le mode d'adressage absolu normal : l'adresse intégrée dans l'instruction est celle de la donnée. Mais s'il est à 1, alors l'adresse intégrée dans l'instruction est celle du pointeur. Cependant, la présence de l'accumulateur permettait d'utiliser l'adressage indirect à registre, pour gérer les pointeurs. Pour rappel, avec le mode d'adressage indirect à registre, l'adresse à lire/écrire est dans un registre. Ici, l'adresse à lire/écrire est prise dans l'accumulateur, seul registre disponible pour. L'adressage indirect est plus simple à implémenter pour l'instruction LOAD, car elle prend un seul opérande : l'adresse à lire. L'adresse à lire est placée dans l'accumulateur, la donnée lue est elle aussi chargée dans l'accumulateur. Pour l'instruction STORE, il faut fournir deux opérandes, l'adresse et la donnée à écrire, ce qui peut poser problème. Mais au pire, il est toujours possible d'utiliser l'adressage absolu ou indirect mémoire : l'adresse est dans l'instruction, la donnée à écrire dans l'accumulateur. ===L'encodage des instructions=== Sur une architecture à accumulateur l'encodage d'une instruction dyadique est assez simple, vu que l'accumulateur est adressé implicitement. La seconde opérande est localisée soit par une adresse mémoire (adressage absolu), soit est une constante (adressage immédiat). L'adresse mémoire est généralement assez longue, plus que l'opcode. {|class="wikitable" |+ Encodage d'une instruction dyadique |- ! rowspan="2" | Opcode | Adresse mémoire (adressage absolu) |- | Constante (adressage immédiat) |} L'encodage d'une instruction monadique est similaire. Si l'opérande est lue depuis la mémoire RAM, alors l'instruction est encodée comme une instruction dyadique. Il en est de même pour les instructions qui copient une constante dans l'accumulateur. Par contre, si l'opérande est dans l'accumulateur, alors il y a juste besoin d'encoder l'opcode. La majorité des instructions a besoin de préciser une adresse, rares sont celles qui s'en passent. Au vu de cet encodage, les architectures à accumulateur sont qualifiées d''''architectures à une adresse''' par abus de langage. Il est intéressant de contraster leur encodage avec les architectures à registres. Les architectures à registre doivent encoder deux opérandes en plus de l'opcode, avec éventuellement où enregistrer le résultat sur les architectures 3-adresses. Par contre, les opérandes sont généralement des noms de registre, ce qui prend moins de place qu'une adresse mémoire. A la rigueur, les instructions avec une constante immédiate prennent un peu plus de place, car elles doivent encoder un nom de registre en plus de la constante et de l'opcode. Les instructions ''load-op'' des processeurs CISC sont un peu dans le même cas, sauf qu'il faut remplacer la constante par une adresse, qui a généralement la même taille. Les instructions sont donc en moyenne plus courte sur les processeurs à registre, du fait de la présence de registres. ===Annexe : les toutes premières architectures à accumulateur : le Manchester Baby=== [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] Les architectures à accumulateurs sont apparues dès les débuts de l'informatique. Le tout premier ordinateur à programme enregistré en mémoire, le ''Manchester Baby'', était une architecture à accumulateur. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 adresses de 32 bits, fabriquée avec des tubes Williams (abordés dans une annexe à la fin du cours). Le programme devait tenir dans la RAM, avec une instruction par adresse maximum, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 servait à indiquer où se trouvent les opérandes en RAM, les 16 restants sont inutilisés. Le processeur avait un registre accumulateur de 32 bits, un ''program counter'' et un registre d'instruction. Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. C'était là encore une architecture à accumulateur, sauf qu'elle intégrait aussi des registres d'indice. Et surtout : son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. [[File:MM1Schematic French.svg|centre|vignette|upright=2.5|Architecture de la Manchester Mark 1.]] ==La micro-architecture des architectures à accumulateur sans registres d'indice== L'organisation interne d'une architecture à accumulateur est très différente de celle des processeurs à registre. Elle est plus ou moins la même pour tous ces processeurs, le point important étant que le chemin de données se résume à une ALU, un registre accumulateur et le bus de données. L'ALU est reliée au registre accumulateur, ainsi qu'au bus de données pour lire la seconde opérande, comme illustré ci-dessous. [[File:Accumulator.png|centre|vignette|upright=2|Accumulateur.]] ===L'unité de calcul et l'accumulateur=== Pour simplifier l'implémentation, le résultat est mémorisé dans un registre en sortie de l'unité de calcul. La raison est qu'on ne veut pas altérer l'accumulateur tant que le résultat final n'est pas totalement calculé. Rappelons que l'ALU ne fournit pas un résultat d'un seul bloc, mais que certains bits arrivent avant les autres, typiquement les bits de poids faible. Si le résultat était écrit dans l'accumulateur directement, il écraserait des bits de l’opérande en cours d'utilisation, ce qui fausserait le résultat. [[File:Accumulateur avec registre de sortie.png|centre|vignette|upright=2|Accumulateur avec registre de sortie]] Une autre solution utilisait un registre entre l'accumulateur et l'unité de calcul, appelé l’'''''accumulator latch'''''. Il remplace le registre en sortie de l'ALU, dans le sens où il permet d'écrire dans l'accumulateur sans effacer l'opérande, pendant que l’opération est en cours dans l'ALU. L'accumulateur est copié dans l’''accumulator latch'', avant que l'ALU démarre ses calculs. L'opérande est donc maintenue même si on commence à écrire le résultat dans l'accumulateur. Sur le 8085 d'Intel, l’''accumulator latch'' peut être initialisé avec une constante prédéfinie, ce qui permet d'implémenter certaines instructions très facilement. Par exemple, il peut être initialisé à 0, ce qui permet d'implémenter les instructions MOV et INC (incrémentation). Un MOV est équivalent à faire un OU entre le registre lu et 0. Une instruction INC initialise l'entrée de retenue de l'unité de calcul à 1, puis ajoute 0. La décrémentation est implémentée de la même manière, sauf que l’''accumulator latch'' est initialisé à -2 pour compenser l'entrée de retenue à 1. De plus, pour supporter les conversion de décimal à BCD, l’''accumulator latch'' peut être initialisé avec les constantes 0x00, 0x06, 0x60, or 0x66. L'''accumulator latch'' est relié à divers fils de commande provenant de l'unité de contrôle, qui décide quelle valeur d'initialisation utiliser en fonction de l'instruction décodée. [[File:Accumulator latch.png|centre|vignette|upright=2|Accumulator latch]] [[File:Chemin de données à un seul bus.png|vignette|Chemin de données à un seul bus]] De même, la seconde opérande, celle lue sur le bus de données, est mémorisée dans un registre en amont de l'ALU. C'était notamment très utile si le processeur utilisait une ALU plus courte que les opérandes, avec par exemple une ALU 4 bits pour un CPU 8 bits. Les anciens processeurs à accumulateur de type ''mainframe'' utilisaient des opérandes de grande taille, du genre 36 ou 48 bits, ce qui avait des conséquences sur l'unité de calcul utilisée, ainsi que sur la communication avec la mémoire. Il arrivait que de tels processeurs utilisaient des ALU sérielles, ou du moins octet-sérielles, plutôt qu'une véritable ALU 36 bits. Nous verrons aussi que c'est très utile sur les processeurs à accumulateur avec un bus interne unique, dans la suite du chapitre. ===La micro-architecture des architectures à accumulateur avec instructions LOAD/STORE=== Nous venons de voir comment est implémenté l'unité de calcul et l'accumulateur, et comment le tout est relié au bus de données. Mais cela ne permet que d'avoir un processeur à accumulateur rudimentaire, qui ne gére que des instructions arithmétiques et logiques. Il faut aussi gérer le cas des opérations LOAD/STORE et des modes d'adressages associés, mais c'est le séquenceur qui s'en occupe. Avec l'adressage absolu, les instructions LOAD et STORE ne font que connecter l'accumulateur au bus de données. L'instruction STORE nécessite de connecter l'accumulateur au bus de données, de manière à ce que le transfert des données se fasse de l'accumulateur vers le bus de données. L'instruction LOAD s'implémente de la même manière, sauf que le sens de transfert est inversé. Cependant, il existe une optimisation qui permet d'implémenter l'instruction LOAD sans ajouter de circuits. Pour cela, il suffit que l'unité de calcul gére les opérations ''pass through'', à savoir des opérations qui se contentent de recopier un opérande sur la sortie. Ici, l'idée est de recopier l'opérande provenant du bus de données. [[File:Architecture à accumulateur, microarchitecture.png|centre|vignette|upright=2|Architecture à accumulateur, microarchitecture]] Pour gérer nativement l'adressage indirect à registre, il suffit de connecter l'accumulateur au bus d'adresse. Le plus simple est d'ajouter un multiplexeur, comme illustré ci-dessous. La donnée lue est copiée dans l'accumulateur, ce qui fait qu'il vaut mieux utiliser un registre d’interfaçage, l'accumulateur n'étant pas utilisable à la fois pour le bus d'adresse et de données. [[File:Adressage indirect sur une architecture à accumulateur.png|centre|vignette|upright=2|Adressage indirect sur une architecture à accumulateur]] Pour finir, voyons comment le pointeur de pile et le ''program counter'' sont implémentés. Les architectures à accumulateur ont souvent des adresses de taille différente des données, ce qui fait qu'il vaut mieux utiliser un circuit incrémenteur dédié pour incrémenter le ''program counter'', plutôt que de l'incrémenter via l'unité de calcul. Les architectures à accumulateur ont parfois un pointeur de pile, qui gère une pile d'adresse de retour, pas une vraie pile d'appel. Aussi, le pointeur de pile est censé être incrémenté et décrémenté, pas plus. Pas d'addition ou de soustraction pour gérer des cadres de pile. Là encore, c'est la solution de l'incrémenteur séparé qui est retenue. Pour économiser des transistors, il n'y a qu'un seul incrémenteur partagé pour les deux. ==Les architectures à accumulateur à registres d'indice== Les architectures à accumulateur décrites dans la section précédente sont capables de faire de l'adressage indirect, mais n'incluent pas les modes d'adressage base + indice et absolus indicés, qui prennent une adresse et y ajoute un indice. Il s'agit des toutes premières architectures à accumulateur, comme les premiers ordinateurs IBM ou le fameux PDP-8. Mais par la suite, les processeurs à accumulateurs ont inclus un support des modes d'adressages indicés, grâce à des '''registres d'indice'''. ===Les registres d'indice=== Les registres d'indice stockent des indices de tableaux. Ils permettaient de supporter deux modes d'adressage : * Le '''mode d'adressage absolu indicé''' où une adresse fixe est additionnée à un indice variable. L'adresse fixe est intégrée dans l'instruction (adressage absolu), l'indice est dans un registre d'indice. * Le '''mode d'adressage base + indice''', où l'adresse est dans l'accumulateur et l'indice dans le registre d'indice. Les processeurs à accumulateur supportaient souvent des variantes des modes d'adressage précédents, où le registre d'indice était automatiquement incrémenté ou décrémenté à chaque utilisation. Au départ, ces processeurs n'utilisaient qu'un seul registre d'indice qui se comportait comme un second accumulateur spécialisé dans les calculs d'adresses mémoire. Le processeur supportait de nouvelles instructions qui utilisaient ce registre d'indice de façon implicite. Mais avec le temps, les processeurs finirent par incorporer plusieurs de ces registres. Les instructions de lecture ou d'écriture devaient alors préciser quel registre d'indice utiliser, en précisant un nom de registre d'indice, un numéro de registre d'indice. Il faut préciser que les registres d'indice ont une taille bien plus petite que l'accumulateur. Ils mémorisent des indices codés sur 16 bits ou moins, alors que l'accumulateur faisait typiquement 36 à 48 bits, parfois plus. La taille classique sur les anciens ''mainframes'' était de 15 bits, parfois moins. Il n'était pas rare de tomber sur des registres d'indice de 8 ou 9 bits. Leur petite taille rendait leur implémentation matérielle peu couteuse. Et c'est ce qui explique qu'ils étaient préférés à l'usage d'un second accumulateur. Un exemple est le cas du processeur Motorola 6809, un processeur à accumulateur qui contient deux registres d'indices nommés X et Y. L'accumulateur est noté D et fait 16 bits, il peut être parfois géré comme deux accumulateurs séparés A et B de 8 bits chacun. Il contenait aussi deux pointeurs de pile, l'un pour les programmes, l'autre pour le système d'exploitation, ainsi qu'un ''program counter''. Le registre de page était utilisé pour l'adressage absolu, comme vu dans le chapitre sur les modes d'adressage. [[File:6809 Internal Registers.svg|centre|vignette|upright=2|6809 Internal Registers]] Les processeurs IBM avaient autrefois plusieurs registres d'indice. Par exemple, l'IBM 704 avait trois registres d'indice de 15 bits. Leur contenu était soustrait de l'adresse absolue. Une instruction pouvait utiliser plusieurs registres d'indice pour adresser son opérande. Toute instruction utilisait trois bits pour sélectionner les registres d'indice utilisés. Fait assez original, lorsque plusieurs registres d'indice sont sélectionnés, le processeur n'additionne pas les trois registres à l'adresse de base. À la place, il fait un OU bit à bit entre les registres d'indice sélectionnés, et additionne le résultat à l'adresse. Les processeurs IBM à accumulateur ont fait ça sur toute la gamme IBM 700/7000, pour des raisons de compatibilité. Les processeurs suivants avaient 7 registres d'indices, mais conservaient les trois bits pour adresser les registres d'indices. Ils pouvaient fonctionner dans deux modes. Le premier mode est plus intuitif : les trois bits précisent un registre d'indice parmi les 7, qui est additionné avec l'adresse absolue. La valeur zéro indique qu'aucun registre d'indice n'est utilisé, ce qui explique qu'il y a 7 registres d'indice et non 8. Un second mode, compatible avec l'IBM 704, fait un OU logique entre les registres d'indice sélectionnés. Seuls les trois premiers registres d'indices peuvent être sélectionnés dans ce mode. Il y a deux instructions pour changer de mode : une pour passer en mode compatible, l'autre pour le quitter pour l'autre mode. Quelques rares processeurs à registres généraux ont utilisés des registres d'indice, en plus des registres généraux. Ce qui fait l'association que nous avons faite entre registres d'indice et architectures à accumulateur est imparfait, bien que solide sur le principe. Un exemple d'architecture de ce type sont les architectures de la série UNIVAC 1100/2200. Ils disposaient de 128 registres, qui étaient mappés en mémoire à partir de l'adresse mémoire 0, la majorité étant inaccessibles par le programmeur. Ils regroupaient 12 registres accumulateurs, 11 registres d'indice et 4 registres hybrides qui pouvaient servir soit de registre d'indice, soit de registres accumulateurs. ===La micro-architecture des architectures à accumulateur avec registres d'indice=== La présence de registres d'indice modifie grandement l'implémentation du processeur. En effet, il faut rajouter un banc de registre pour les registres d'indice. Le banc de registre est monoport, car on a besoin de lire ou d'écrire un indice à la fois. Et il faut aussi potentiellement rajouter de quoi faire les calculs d'adresse. Deux solutions sont possibles : une ALU dédiée aux calculs d'adresse, une seule ALU pour toutes les opérations. Dans le premier cas, il y a une ALU séparée associée aux registres d'indice. L'ALU et les registres d'indice sont placés en sortie du séquenceur, en-dehors du chemin de données, la sortie de l'ALU est directement connectée au bus d'adresse. L'unité de calcul d'adresse peut être utilisée pour incrémenter le ''program counter''. Un défaut de cette approche est qu'elle ne gère pas l'adresse indirect à registre. [[File:Chemin de données sans support des pointeurs, avec adressage absolu indicé.png|centre|vignette|upright=2|Chemin de données sans support des pointeurs, avec adressage absolu indicé]] Une autre option utilise un bus interne, qui interconnecte tout le chemin de données. Dans sa version la plus simple, il est relié à l'accumulateur, l'unité de calcul, le banc de registre d'indice et le bus de données. Avec cette solution, l'ALU est utilisé à la fois pour calculer les adresses et pour les instructions de calcul. En reliant le bus interne au bus d'adresse à travers un multiplexeur, on gère naturellement les adressages indirects. [[File:Architecture à accumulateur avec registres associés.png|centre|vignette|upright=2.5|Architecture à accumulateur avec registres associés]] Il faut noter que sur les architectures Von Neumann, le séquenceur est relié à ce bus interne. En effet, charger une instruction demande de passer par le bus mémoire, donc par l’intermédiaire de ce bus internet. Le ''program counter'' est envoyé sur ce bus pour lire l'instruction, puis l'instruction lue est recopiée dans le registre d'instruction. Le chargement d'une instruction est donc géré comme une lecture des plus classiques. De plus, cela permet d'incrémenter le ''program counter'' au niveau de l'unité de calcul entière. Le ''program counter'' est envoyé sur le bus interne, incrémenté par l'ALU, puis le résultat est recopié dans le ''program counter'' via le bus interne. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] ==Les processeurs bi-accumulateurs : le Motorola 6800== Le Motorola 6800 était un processeur 8 bits qui gérait des adresses de 16 bits. Il contenait deux accumulateurs nommés A et B, de 8 bits chacun. Il disposait aussi d'un registre d'indice, d'un pointeur de pile et d'un ''program counter'', tous les trois de 16 bits. Le registre d'état regroupait 6 bits, qu'on ne détaillera pas ici. [[File:MC6800 Processor Diagram.png|centre|vignette|upright=2|Interface et registres du MC6800.]] La présence des deux accumulateurs impactait surtout les instructions dyadiques. Les instructions monadiques avaient juste à préciser où se trouvait l'opérande : soit en RAM, soit dans le premier accumulateur, soit dans le second. Pour les opérations dyadiques, la gestion était totalement différente. En théorie, le premier opérande est dans un accumulateur, soit A, soit B. La seconde opérande vient soit de l'autre accumulateur, soit de la mémoire RAM. Et selon les instructions, tout variait. Pour l'addition, il y avait trois instructions. Les deux premières additionnaient un opérande provenant de la mémoire avec un accumulateur. L'instruction ADDA sélectionnait le premier accumulateur, l'instruction ADDB sélectionnait le second accumulateur. Mais une troisième instruction, l’instruction ABA, permettait d'additionner le contenu des deux accumulateurs. Pour les autres opérations, il n'était pas possible d'utiliser les deux accumulateurs en même temps. La seule possibilité était de faire une opération entre un accumulateur et un opérande venant de la mémoire. Toutes les instructions étaient en double, avec une copie par accumulateur. Par exemple, l'instruction ANDA faisait un ET entre l’accumulateur A et l'opérande mémoire, l'instruction ANDB faisait pareil avec l'accumulateur B. ==Les architectures hybrides registres-accumulateur== Il a existé quelques architectures qui étaient des hybrides entre architectures à accumulateur et architecture à registre. Elles ont servi de transition entre les deux, durant les années 80-90. Elles avaient un accumulateur unique couplé à un banc de registres généraux. Par exemple, les premiers processeurs Intel 8 bits étaient des processeurs hybrides-accumulateur. Lles CPU Intel 8 bits disposaient de 7 registres de 8 bits nommés A, B, C, D, E, F, H, L, SP. Ils correspondent respectivement à : * l'accumulateur A ; * six registres nommés B, C, D, E, H et L ; * le registre d'état F ; * le pointeur de pile SP. Sur ces processeurs, les instructions dyadiques devaient mettre leur premier opérande dans l'accumulateur, la seconde provenait soit des registres, soit de la RAM, soit d'une constante immédiate. Les opérations monadiques pouvaient lire leur opérande depuis l'accumulateur, les autres registres ou la RAM, tout était permis. Les registres d'indices disparaissaient sur ces architectures, en théorie. Les registres généraux pouvaient être utilisés comme registre d'indice ou pour stocker des opérandes, ils étaient assez versatiles pour servir de registres d'indices. La présence de registres a de nombreux avantages, comparé aux architectures à accumulateur pures. Les instructions arithmétiques sont plus rapide, lire un registre étant plus rapide qu'un accès RAM. Les performances sont donc augmentées. De plus, les instructions arithmétiques utilisant ces registres sont plus courtes : pas besoin d'encoder une adresse mémoire, un nom de registre suffit. Vu que les processeurs de l’époque avaient des instructions de taille variable, cela améliorait la densité de code. La microarchitecture de ces processeurs est très similaire à celle d'un processeur avec des registres d'indices. La seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Le banc de registre est systématiquement monoport, car il n'avait aucune raison d'être multiport. Pour les instructions dyadiques, seules à lire deux opérandes, il ne servait que pour la seconde opérande, la première était lue depuis l'accumulateur. Les processeurs hybrides registre-accumulateur se classent en deux types principaux : ceux qui ont un seul bus interne, et ceux qui en ont deux. Le premier cas est identique à celui vu précédemment pour les architectures à accumulateur avec registres d'indice, à la seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Afin de gérer l'adressage indirect à registre, le bus interne est connecté aux deux registres d’interfaçage mémoire. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] Notons que cela permet aussi d'implémenter facilement les branchements indirects, car le bus interne permet d'échanger des adresses entre ''program counter'' et banc de registre. De même, il est possible d'utiliser l'ALU pour gérer les branchements indirects., en plus de l'utiliser pour incrémenter le ''program counter''. [[File:Single bus organization.jpg|centre|vignette|upright=2|Single bus organization]] Une autre solution utilisait deux bus internes : un connecté au bus de données, un autre relié au bus d'adresse. Le bus de commande mémoire était lui commandé par le séquenceur, l'unité de contrôle. L'intermédiaire entre ces deux bus était le banc de registre, ainsi que les autres registres. Le banc de registre était connecté aux deux bus interne, avec un port de lecture relié au bus d'adresse, un port de lecture-écriture relié au bus de données. Le port de lecture était utilisé pour l'adressage indirect, l'autre l'était pour le reste. [[File:Proz1-e.png|centre|vignette|upright=2|Intérieur d'un processeur.]] L'organisation à deux bus simplifiait la gestion du ''program counter'' et le chargement des instructions. Le ''program counter'' était soit séparé du banc de registre, soit placé dans le banc de registre. Les deux solutions étaient utilisés, tout dépend du processeur. Il faut noter que si le ''program counter'' est intégré au banc de registres, alors la microarchitecture du processeur est bien plus simple. L'envoi du ''program counter'' sur le bus d'adresse utilise le port de lecture relié au bus d'adresse, qui sert aussi pour l'adressage indirect. L'économie de circuits, sans compter la simplicité d'implémentation que cela implique, explique sans doute que la technique a été utilisée sur quelques processeurs anciens. Le ''program counter'' était généralement incrémenté par l'ALU, ce qui explique qu'il soit connecté au bus interne pour les données. La connexion est aussi utile pour gérer les branchements indirects, qui copient un registre dans le ''program counter'', ainsi que les branchements relatifs (addition dans l'ALU), voire les branchements directs (l'adresse vers laquelle brancher est envoyée en entrée de l'ALU et propagée en sortie avec une opération ''pass through''). [[File:Connexion du program counter sur les bus avec PC dans le banc de registres.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC dans le banc de registres]] ===Les registres d'interruption avec un processeur hybride-accumulateur : l'exemple du Z80=== Un exemple de processeur registre-accumulateur à deux bus interne est le Z80, un processeur fortement inspiré des CPU Intel 8 bits. Il a un jeu d'instruction similaire, mais a diverses améliorations par rapport au design original. Notamment, le processeur a des registres séparés pour les interruptions. Sur le Z80, les registres généraux sont dupliqués avec 6 registres pour les interruptions et 6 registres pour les programmes autres. Leur copie pour les interruptions sont nommées B', C', D', E', H', L'. Les 12 registres sont placés dans le banc de registre, ce qui implique que le fenêtrage de registres est utilisé pour gérer la séparation entre registre d'interruption et normaux. Il faut noter que l'accumulateur et le registre d'état sont aussi dupliqués, leurs copies étant nommées A' et F'. Mais leur duplication se fait autrement que par fenêtrage de registre. En plus des registres précédents, le Z80 incorporait deux registres d'indice nommés X et Y, ainsi qu'un pointeur de pile SP et un ''program counter'' PC. Ils n'étaient pas dupliqués pour les interruptions. Les registres d'indice étaient reliés à une unité de calcul d'adresse. L'unité de calcul d'adresse prenait deux opérandes : un indice, et une adresse mémoire provenant soit du banc de registre, soit de l'accumulateur. En clair, l'unité de calcul d'adresse faisait le lien entre les deux bus internet : le bus de données interne en entrée, le bus d'adresse en sortie. À l'intérieur du processeur, tous les registres étaient regroupés dans un banc de registre unique, sauf les accumulateurs, les registres d'état et le ''program counter''. Bien que ce ne soit pas indiqué sur le schéma ci-dessous, le ''program counter'' est séparé du banc de registre, alors que le pointeur de pile est dedans. Le compteur IR est lui associé au ''program counter'', il est sortit du banc de registre. Le Z80 utilise lui aussi un incrémenteur séparé de l'ALU, qui est utilisé pour mettre à jour le ''program counter'', le pointeur de pile et un compteur de rafraichissement mémoire nommé IR sur le Z80 (pour rappel, le rafraichissement mémoire demande de balayer la mémoire d'adresse en adresse et été fait par le CPU à l'époque). De plus, il est utilisé pour les instructions INC et DEC qui incrémentent une opérande de 16 bits obtenue en combinant deux registres de 8 bits. En clair, l'incrémenteur du ''program counter'' a été réutilisé de beaucoup de manières originales. [[File:Z80 arch.svg|centre|vignette|upright=3|Microarchitecture du Z80.]] Le Z80 incorporait des instructions pour échanger le contenu des deux ensembles de registres, accumulateur inclus. Elles permettaient d'utiliser les registres d'interruption pour les programmes et réciproquement. En clair, cela doublait le nombre de registres si les interruptions n'étaient pas utilisées. * L'instruction EXX échangeait les deux fenêtres de registres généraux : les registres B, C, D, E, H et L devenaient les registres B', C', D', E', H' et L' et inversement. * L'instruction EX échangeait l'accumulateur et le registre d'état : les registres A,F devenait A',F' et inversement. Le fenêtrage de registre était modifié par l'instruction EXX, qui échangeait les deux fenêtres de registres. Pour l'implémenter, une bascule était ajouté au processeur, appelons-la la bascule INT. Elle était relié au bus d'adresse du banc de registre, dont elle mémorisait le bit de poids fort. L'instruction EXX inversait la valeur de la bascule INT. Il est aussi possible d'échanger le contenu des registres D,E et H,L avec une instruction dédiée, ce qui est là encore fait par deux bascules : une pour les registres D,E et une autre pour les registres H,L. Pour l'accumulateur et le registre d'état, le choix entre registre normal et registre d'interruption se faisait là encore par une seconde bascule appelée la bascule A. La bascule est reliée à un multiplexeur et un démultiplexeur, qui permet de choisir quel accumulateur relier à l'unité de calcul. L'instruction EX inverse le contenu de la bascule A. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=L'unité de contrôle | prevText=L'unité de contrôle | next=Les processeurs 8 bits et moins | nextText=Les processeurs 8 bits et moins }} </noinclude> 5b01xh2gbldnexgdfz9lwpr6gg9tbwn 744140 744139 2025-06-05T00:35:43Z Mewtow 31375 /* Annexe : les toutes premières architectures à accumulateur : le Manchester Baby */ 744140 wikitext text/x-wiki Les architectures que nous avons vu précédemment dans ce cours disposent de registres pour les données, en plus du pointeur de pile, d'un ''program counter'', et de quelques autres. Elles sont appelées des '''architectures à registres''', terme qui trahit bien le fait qu'elles ont des registres généraux ou spécialisés pour stocker temporairement des données. Et si on leur a donné un nom, c'est parce qu'il existe des architectures qui ne sont pas dans cette catégorie. Il en existe plusieurs types, mais ce chapitre va se concentrer sur les '''architectures à accumulateur'''. [[File:Isaccumulator.png|vignette|Architecture à accumulateur.]] Les architectures à accumulateur sont centrées autour d'un registre architectural appelé l''''accumulateur'''. Il est utilisé pour toutes les opérations arithmétiques dyadiques, où il sert à la fois de source et de destination. Toutes les instructions dyadiques sont de type ''load-op'' : une opérande est lue depuis l'accumulateur, le second opérande est lu depuis la mémoire RAM, le résultat de l'instruction est automatiquement mémorisé dans l'accumulateur. Les instructions monadiques peuvent utiliser un opérande dans l'accumulateur, ou dans la mémoire RAM, les deux sont théoriquement possibles. La conséquence est que le nombre d'accès mémoire est drastiquement diminué : de 3 par instructions sur une architecture mémoire-mémoire, on passe à seulement un avec un accumulateur. Les opérations dyadiques ont besoin d'un seul accès mémoire pour lire la seconde opérande, les opérations monadique en font aussi un seul pour lire leur unique opérande. {|class="wikitable" |- ! Classe d'architecture ! Nombre d'accès mémoire par opération dyadique |- |- ! Architecture à accumulateur | Un accès mémoire par instruction, pour lire la seconde opérande |- ! Architecture à registres | Zéro si les opérandes sont dans les registres, un pour les opérations ''load-op'', LOAD et STORE. |} ==Le jeu d'instruction des architectures à accumulateur sans registres d'indice== L'accumulateur est adressé grâce au mode d'adressage implicite, de même que le résultat de l'opération. Par contre, les autres opérandes sont localisés avec d'autres modes d'adressage, et lues en mémoire RAM. Le résultat ainsi qu'un des opérandes sont adressés de façon implicite car dans l'accumulateur, seule la seconde opérande étant adressée directement. Grâce à l'accumulateur, une instruction ne fait qu'un seul accès mémoire maximum, ce qui rend le processeur très facile à implémenter. ===Les registres des anciennes architectures à accumulateur=== [[File:IBM 701console.jpg|vignette|IBM 701, console extérieure.]] Les architectures à accumulateur étaient communes dans les années 50-60. A l'époque, les ordinateurs étaient gigantesques, ils prenaient une pièce de bâtiment entière dans le pire des cas, une armoire entière dans le meilleur. Les ordinateurs de l'époque étaient surtout utilisés pour du calcul scientifique ou des tâches d’ingénierie demandant beaucoup de calcul, rarement pour de la compatibilité. Les nombres flottants n'étaient pas encore apparus. A la place, les ordinateurs de l'époque géraient des nombres entiers de grande taille, de 30 bits ou plus. En conséquence, l'accumulateur faisait facilement 30 à 60 bits. Par exemple, les ordinateurs de la Série scientifique IBM 700/7000 géraient des entiers de 36 bits, l’accumulateur faisait 38 bits : 36 bits plus deux bits pour les débordements. Au passage, de tels processeurs utilisaient l'adressage par mot, et non par byte. Historiquement, les premières architectures à accumulateur ne contenaient aucun autre registre que l'accumulateur. Ce n'est que dans les années 60 que de nombreuses architectures à accumulateur ont ajouté un second '''registre pour les multiplication/divisions'''. Un exemple est celui de l'IBM 701, qui incorporait un registre accumulateur de 38 bits et un registre multiplieur de 36 bits. Le registre mémorise le multiplieur lors d'une opération de multiplication. Il mémorise donc un opérande, pas le résultat. Il peut aussi décaler le multiplieur vers la droite/gauche, ce qui est utile pour exécuter la multiplication. C'est ce qui est fait sur l'IBM 7094. Une autre possibilité est que ce registre mémorise une partie du résultat de l'opération. Pour rappel, le résultat d'une multiplication/division est codé sur deux fois de bits que ses opérandes. Par exemple, multipliez deux opérandes de 30 bits, vous obtiendrez un résultat de 60 bits. Les 30 bits de poids faible du résultat vont dans l'accumulateur, les 30 bits de poids fort vont dans ce second registre. Les architectures à accumulateur parfois un '''registre pour le pointeur de pile''', utilisé pour gérer les fonctions/procédures. Les architectures à accumulateurs supportaient une pile d'adresse de retour, souvent une pile d'appel. Mais pour cela, il fallait mémoriser le pointeur de pile dans le processeur, ce qui demandait un registre dédié. ===L'adressage indirect avec l'accumulateur=== Les instructions LOAD et STORE existent bel et bien sur les architectures à accumulateur, mais n'ont pas les mêmes modes d'adressages. L'instruction LOAD copie une donnée de la RAM vers l'accumulateur, l'instruction STORE copie l'accumulateur dans une adresse. Les deux instructions n'ont pas besoin d'adresser l'accumulateur, qui est adressé de manière implicite, juste de préciser l'adresse à lire/écrire. Les architectures à accumulateur supportaient souvent le mode d'adressage indirect mémoire. Un exemple est celui des ordinateurs Data General Nova, qui sont des architectures à accumulateur et qui supportaient ce mode d'adressage. Les deux instructions LOAD et STORE existaient en deux versions, distinguées par un bit d'indirection. Si ce bit est à 0 dans l'opcode, alors l'instruction utilise le mode d'adressage absolu normal : l'adresse intégrée dans l'instruction est celle de la donnée. Mais s'il est à 1, alors l'adresse intégrée dans l'instruction est celle du pointeur. Cependant, la présence de l'accumulateur permettait d'utiliser l'adressage indirect à registre, pour gérer les pointeurs. Pour rappel, avec le mode d'adressage indirect à registre, l'adresse à lire/écrire est dans un registre. Ici, l'adresse à lire/écrire est prise dans l'accumulateur, seul registre disponible pour. L'adressage indirect est plus simple à implémenter pour l'instruction LOAD, car elle prend un seul opérande : l'adresse à lire. L'adresse à lire est placée dans l'accumulateur, la donnée lue est elle aussi chargée dans l'accumulateur. Pour l'instruction STORE, il faut fournir deux opérandes, l'adresse et la donnée à écrire, ce qui peut poser problème. Mais au pire, il est toujours possible d'utiliser l'adressage absolu ou indirect mémoire : l'adresse est dans l'instruction, la donnée à écrire dans l'accumulateur. ===L'encodage des instructions=== Sur une architecture à accumulateur l'encodage d'une instruction dyadique est assez simple, vu que l'accumulateur est adressé implicitement. La seconde opérande est localisée soit par une adresse mémoire (adressage absolu), soit est une constante (adressage immédiat). L'adresse mémoire est généralement assez longue, plus que l'opcode. {|class="wikitable" |+ Encodage d'une instruction dyadique |- ! rowspan="2" | Opcode | Adresse mémoire (adressage absolu) |- | Constante (adressage immédiat) |} L'encodage d'une instruction monadique est similaire. Si l'opérande est lue depuis la mémoire RAM, alors l'instruction est encodée comme une instruction dyadique. Il en est de même pour les instructions qui copient une constante dans l'accumulateur. Par contre, si l'opérande est dans l'accumulateur, alors il y a juste besoin d'encoder l'opcode. La majorité des instructions a besoin de préciser une adresse, rares sont celles qui s'en passent. Au vu de cet encodage, les architectures à accumulateur sont qualifiées d''''architectures à une adresse''' par abus de langage. Il est intéressant de contraster leur encodage avec les architectures à registres. Les architectures à registre doivent encoder deux opérandes en plus de l'opcode, avec éventuellement où enregistrer le résultat sur les architectures 3-adresses. Par contre, les opérandes sont généralement des noms de registre, ce qui prend moins de place qu'une adresse mémoire. A la rigueur, les instructions avec une constante immédiate prennent un peu plus de place, car elles doivent encoder un nom de registre en plus de la constante et de l'opcode. Les instructions ''load-op'' des processeurs CISC sont un peu dans le même cas, sauf qu'il faut remplacer la constante par une adresse, qui a généralement la même taille. Les instructions sont donc en moyenne plus courte sur les processeurs à registre, du fait de la présence de registres. ===Annexe : les toutes premières architectures à accumulateur : le Manchester Baby=== [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] Les architectures à accumulateurs sont apparues dès les débuts de l'informatique. Le tout premier ordinateur à programme enregistré en mémoire, le ''Manchester Baby'', était une architecture à accumulateur. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 adresses, fabriquée avec des tubes Williams (abordés dans une annexe à la fin du cours). Chaque adresse mémorisait 32 bits, qui pouvaient encoder soit un nombre, soit une instruction. Le programme devait tenir dans la RAM, avec une instruction par adresse maximum, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 servait à indiquer où se trouvent les opérandes en RAM, les 16 restants sont inutilisés. Le processeur avait un registre accumulateur de 32 bits, un ''program counter'' et un registre d'instruction. Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. C'était là encore une architecture à accumulateur, sauf qu'elle intégrait aussi des registres d'indice. Et surtout : son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. [[File:MM1Schematic French.svg|centre|vignette|upright=2.5|Architecture de la Manchester Mark 1.]] ==La micro-architecture des architectures à accumulateur sans registres d'indice== L'organisation interne d'une architecture à accumulateur est très différente de celle des processeurs à registre. Elle est plus ou moins la même pour tous ces processeurs, le point important étant que le chemin de données se résume à une ALU, un registre accumulateur et le bus de données. L'ALU est reliée au registre accumulateur, ainsi qu'au bus de données pour lire la seconde opérande, comme illustré ci-dessous. [[File:Accumulator.png|centre|vignette|upright=2|Accumulateur.]] ===L'unité de calcul et l'accumulateur=== Pour simplifier l'implémentation, le résultat est mémorisé dans un registre en sortie de l'unité de calcul. La raison est qu'on ne veut pas altérer l'accumulateur tant que le résultat final n'est pas totalement calculé. Rappelons que l'ALU ne fournit pas un résultat d'un seul bloc, mais que certains bits arrivent avant les autres, typiquement les bits de poids faible. Si le résultat était écrit dans l'accumulateur directement, il écraserait des bits de l’opérande en cours d'utilisation, ce qui fausserait le résultat. [[File:Accumulateur avec registre de sortie.png|centre|vignette|upright=2|Accumulateur avec registre de sortie]] Une autre solution utilisait un registre entre l'accumulateur et l'unité de calcul, appelé l’'''''accumulator latch'''''. Il remplace le registre en sortie de l'ALU, dans le sens où il permet d'écrire dans l'accumulateur sans effacer l'opérande, pendant que l’opération est en cours dans l'ALU. L'accumulateur est copié dans l’''accumulator latch'', avant que l'ALU démarre ses calculs. L'opérande est donc maintenue même si on commence à écrire le résultat dans l'accumulateur. Sur le 8085 d'Intel, l’''accumulator latch'' peut être initialisé avec une constante prédéfinie, ce qui permet d'implémenter certaines instructions très facilement. Par exemple, il peut être initialisé à 0, ce qui permet d'implémenter les instructions MOV et INC (incrémentation). Un MOV est équivalent à faire un OU entre le registre lu et 0. Une instruction INC initialise l'entrée de retenue de l'unité de calcul à 1, puis ajoute 0. La décrémentation est implémentée de la même manière, sauf que l’''accumulator latch'' est initialisé à -2 pour compenser l'entrée de retenue à 1. De plus, pour supporter les conversion de décimal à BCD, l’''accumulator latch'' peut être initialisé avec les constantes 0x00, 0x06, 0x60, or 0x66. L'''accumulator latch'' est relié à divers fils de commande provenant de l'unité de contrôle, qui décide quelle valeur d'initialisation utiliser en fonction de l'instruction décodée. [[File:Accumulator latch.png|centre|vignette|upright=2|Accumulator latch]] [[File:Chemin de données à un seul bus.png|vignette|Chemin de données à un seul bus]] De même, la seconde opérande, celle lue sur le bus de données, est mémorisée dans un registre en amont de l'ALU. C'était notamment très utile si le processeur utilisait une ALU plus courte que les opérandes, avec par exemple une ALU 4 bits pour un CPU 8 bits. Les anciens processeurs à accumulateur de type ''mainframe'' utilisaient des opérandes de grande taille, du genre 36 ou 48 bits, ce qui avait des conséquences sur l'unité de calcul utilisée, ainsi que sur la communication avec la mémoire. Il arrivait que de tels processeurs utilisaient des ALU sérielles, ou du moins octet-sérielles, plutôt qu'une véritable ALU 36 bits. Nous verrons aussi que c'est très utile sur les processeurs à accumulateur avec un bus interne unique, dans la suite du chapitre. ===La micro-architecture des architectures à accumulateur avec instructions LOAD/STORE=== Nous venons de voir comment est implémenté l'unité de calcul et l'accumulateur, et comment le tout est relié au bus de données. Mais cela ne permet que d'avoir un processeur à accumulateur rudimentaire, qui ne gére que des instructions arithmétiques et logiques. Il faut aussi gérer le cas des opérations LOAD/STORE et des modes d'adressages associés, mais c'est le séquenceur qui s'en occupe. Avec l'adressage absolu, les instructions LOAD et STORE ne font que connecter l'accumulateur au bus de données. L'instruction STORE nécessite de connecter l'accumulateur au bus de données, de manière à ce que le transfert des données se fasse de l'accumulateur vers le bus de données. L'instruction LOAD s'implémente de la même manière, sauf que le sens de transfert est inversé. Cependant, il existe une optimisation qui permet d'implémenter l'instruction LOAD sans ajouter de circuits. Pour cela, il suffit que l'unité de calcul gére les opérations ''pass through'', à savoir des opérations qui se contentent de recopier un opérande sur la sortie. Ici, l'idée est de recopier l'opérande provenant du bus de données. [[File:Architecture à accumulateur, microarchitecture.png|centre|vignette|upright=2|Architecture à accumulateur, microarchitecture]] Pour gérer nativement l'adressage indirect à registre, il suffit de connecter l'accumulateur au bus d'adresse. Le plus simple est d'ajouter un multiplexeur, comme illustré ci-dessous. La donnée lue est copiée dans l'accumulateur, ce qui fait qu'il vaut mieux utiliser un registre d’interfaçage, l'accumulateur n'étant pas utilisable à la fois pour le bus d'adresse et de données. [[File:Adressage indirect sur une architecture à accumulateur.png|centre|vignette|upright=2|Adressage indirect sur une architecture à accumulateur]] Pour finir, voyons comment le pointeur de pile et le ''program counter'' sont implémentés. Les architectures à accumulateur ont souvent des adresses de taille différente des données, ce qui fait qu'il vaut mieux utiliser un circuit incrémenteur dédié pour incrémenter le ''program counter'', plutôt que de l'incrémenter via l'unité de calcul. Les architectures à accumulateur ont parfois un pointeur de pile, qui gère une pile d'adresse de retour, pas une vraie pile d'appel. Aussi, le pointeur de pile est censé être incrémenté et décrémenté, pas plus. Pas d'addition ou de soustraction pour gérer des cadres de pile. Là encore, c'est la solution de l'incrémenteur séparé qui est retenue. Pour économiser des transistors, il n'y a qu'un seul incrémenteur partagé pour les deux. ==Les architectures à accumulateur à registres d'indice== Les architectures à accumulateur décrites dans la section précédente sont capables de faire de l'adressage indirect, mais n'incluent pas les modes d'adressage base + indice et absolus indicés, qui prennent une adresse et y ajoute un indice. Il s'agit des toutes premières architectures à accumulateur, comme les premiers ordinateurs IBM ou le fameux PDP-8. Mais par la suite, les processeurs à accumulateurs ont inclus un support des modes d'adressages indicés, grâce à des '''registres d'indice'''. ===Les registres d'indice=== Les registres d'indice stockent des indices de tableaux. Ils permettaient de supporter deux modes d'adressage : * Le '''mode d'adressage absolu indicé''' où une adresse fixe est additionnée à un indice variable. L'adresse fixe est intégrée dans l'instruction (adressage absolu), l'indice est dans un registre d'indice. * Le '''mode d'adressage base + indice''', où l'adresse est dans l'accumulateur et l'indice dans le registre d'indice. Les processeurs à accumulateur supportaient souvent des variantes des modes d'adressage précédents, où le registre d'indice était automatiquement incrémenté ou décrémenté à chaque utilisation. Au départ, ces processeurs n'utilisaient qu'un seul registre d'indice qui se comportait comme un second accumulateur spécialisé dans les calculs d'adresses mémoire. Le processeur supportait de nouvelles instructions qui utilisaient ce registre d'indice de façon implicite. Mais avec le temps, les processeurs finirent par incorporer plusieurs de ces registres. Les instructions de lecture ou d'écriture devaient alors préciser quel registre d'indice utiliser, en précisant un nom de registre d'indice, un numéro de registre d'indice. Il faut préciser que les registres d'indice ont une taille bien plus petite que l'accumulateur. Ils mémorisent des indices codés sur 16 bits ou moins, alors que l'accumulateur faisait typiquement 36 à 48 bits, parfois plus. La taille classique sur les anciens ''mainframes'' était de 15 bits, parfois moins. Il n'était pas rare de tomber sur des registres d'indice de 8 ou 9 bits. Leur petite taille rendait leur implémentation matérielle peu couteuse. Et c'est ce qui explique qu'ils étaient préférés à l'usage d'un second accumulateur. Un exemple est le cas du processeur Motorola 6809, un processeur à accumulateur qui contient deux registres d'indices nommés X et Y. L'accumulateur est noté D et fait 16 bits, il peut être parfois géré comme deux accumulateurs séparés A et B de 8 bits chacun. Il contenait aussi deux pointeurs de pile, l'un pour les programmes, l'autre pour le système d'exploitation, ainsi qu'un ''program counter''. Le registre de page était utilisé pour l'adressage absolu, comme vu dans le chapitre sur les modes d'adressage. [[File:6809 Internal Registers.svg|centre|vignette|upright=2|6809 Internal Registers]] Les processeurs IBM avaient autrefois plusieurs registres d'indice. Par exemple, l'IBM 704 avait trois registres d'indice de 15 bits. Leur contenu était soustrait de l'adresse absolue. Une instruction pouvait utiliser plusieurs registres d'indice pour adresser son opérande. Toute instruction utilisait trois bits pour sélectionner les registres d'indice utilisés. Fait assez original, lorsque plusieurs registres d'indice sont sélectionnés, le processeur n'additionne pas les trois registres à l'adresse de base. À la place, il fait un OU bit à bit entre les registres d'indice sélectionnés, et additionne le résultat à l'adresse. Les processeurs IBM à accumulateur ont fait ça sur toute la gamme IBM 700/7000, pour des raisons de compatibilité. Les processeurs suivants avaient 7 registres d'indices, mais conservaient les trois bits pour adresser les registres d'indices. Ils pouvaient fonctionner dans deux modes. Le premier mode est plus intuitif : les trois bits précisent un registre d'indice parmi les 7, qui est additionné avec l'adresse absolue. La valeur zéro indique qu'aucun registre d'indice n'est utilisé, ce qui explique qu'il y a 7 registres d'indice et non 8. Un second mode, compatible avec l'IBM 704, fait un OU logique entre les registres d'indice sélectionnés. Seuls les trois premiers registres d'indices peuvent être sélectionnés dans ce mode. Il y a deux instructions pour changer de mode : une pour passer en mode compatible, l'autre pour le quitter pour l'autre mode. Quelques rares processeurs à registres généraux ont utilisés des registres d'indice, en plus des registres généraux. Ce qui fait l'association que nous avons faite entre registres d'indice et architectures à accumulateur est imparfait, bien que solide sur le principe. Un exemple d'architecture de ce type sont les architectures de la série UNIVAC 1100/2200. Ils disposaient de 128 registres, qui étaient mappés en mémoire à partir de l'adresse mémoire 0, la majorité étant inaccessibles par le programmeur. Ils regroupaient 12 registres accumulateurs, 11 registres d'indice et 4 registres hybrides qui pouvaient servir soit de registre d'indice, soit de registres accumulateurs. ===La micro-architecture des architectures à accumulateur avec registres d'indice=== La présence de registres d'indice modifie grandement l'implémentation du processeur. En effet, il faut rajouter un banc de registre pour les registres d'indice. Le banc de registre est monoport, car on a besoin de lire ou d'écrire un indice à la fois. Et il faut aussi potentiellement rajouter de quoi faire les calculs d'adresse. Deux solutions sont possibles : une ALU dédiée aux calculs d'adresse, une seule ALU pour toutes les opérations. Dans le premier cas, il y a une ALU séparée associée aux registres d'indice. L'ALU et les registres d'indice sont placés en sortie du séquenceur, en-dehors du chemin de données, la sortie de l'ALU est directement connectée au bus d'adresse. L'unité de calcul d'adresse peut être utilisée pour incrémenter le ''program counter''. Un défaut de cette approche est qu'elle ne gère pas l'adresse indirect à registre. [[File:Chemin de données sans support des pointeurs, avec adressage absolu indicé.png|centre|vignette|upright=2|Chemin de données sans support des pointeurs, avec adressage absolu indicé]] Une autre option utilise un bus interne, qui interconnecte tout le chemin de données. Dans sa version la plus simple, il est relié à l'accumulateur, l'unité de calcul, le banc de registre d'indice et le bus de données. Avec cette solution, l'ALU est utilisé à la fois pour calculer les adresses et pour les instructions de calcul. En reliant le bus interne au bus d'adresse à travers un multiplexeur, on gère naturellement les adressages indirects. [[File:Architecture à accumulateur avec registres associés.png|centre|vignette|upright=2.5|Architecture à accumulateur avec registres associés]] Il faut noter que sur les architectures Von Neumann, le séquenceur est relié à ce bus interne. En effet, charger une instruction demande de passer par le bus mémoire, donc par l’intermédiaire de ce bus internet. Le ''program counter'' est envoyé sur ce bus pour lire l'instruction, puis l'instruction lue est recopiée dans le registre d'instruction. Le chargement d'une instruction est donc géré comme une lecture des plus classiques. De plus, cela permet d'incrémenter le ''program counter'' au niveau de l'unité de calcul entière. Le ''program counter'' est envoyé sur le bus interne, incrémenté par l'ALU, puis le résultat est recopié dans le ''program counter'' via le bus interne. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] ==Les processeurs bi-accumulateurs : le Motorola 6800== Le Motorola 6800 était un processeur 8 bits qui gérait des adresses de 16 bits. Il contenait deux accumulateurs nommés A et B, de 8 bits chacun. Il disposait aussi d'un registre d'indice, d'un pointeur de pile et d'un ''program counter'', tous les trois de 16 bits. Le registre d'état regroupait 6 bits, qu'on ne détaillera pas ici. [[File:MC6800 Processor Diagram.png|centre|vignette|upright=2|Interface et registres du MC6800.]] La présence des deux accumulateurs impactait surtout les instructions dyadiques. Les instructions monadiques avaient juste à préciser où se trouvait l'opérande : soit en RAM, soit dans le premier accumulateur, soit dans le second. Pour les opérations dyadiques, la gestion était totalement différente. En théorie, le premier opérande est dans un accumulateur, soit A, soit B. La seconde opérande vient soit de l'autre accumulateur, soit de la mémoire RAM. Et selon les instructions, tout variait. Pour l'addition, il y avait trois instructions. Les deux premières additionnaient un opérande provenant de la mémoire avec un accumulateur. L'instruction ADDA sélectionnait le premier accumulateur, l'instruction ADDB sélectionnait le second accumulateur. Mais une troisième instruction, l’instruction ABA, permettait d'additionner le contenu des deux accumulateurs. Pour les autres opérations, il n'était pas possible d'utiliser les deux accumulateurs en même temps. La seule possibilité était de faire une opération entre un accumulateur et un opérande venant de la mémoire. Toutes les instructions étaient en double, avec une copie par accumulateur. Par exemple, l'instruction ANDA faisait un ET entre l’accumulateur A et l'opérande mémoire, l'instruction ANDB faisait pareil avec l'accumulateur B. ==Les architectures hybrides registres-accumulateur== Il a existé quelques architectures qui étaient des hybrides entre architectures à accumulateur et architecture à registre. Elles ont servi de transition entre les deux, durant les années 80-90. Elles avaient un accumulateur unique couplé à un banc de registres généraux. Par exemple, les premiers processeurs Intel 8 bits étaient des processeurs hybrides-accumulateur. Lles CPU Intel 8 bits disposaient de 7 registres de 8 bits nommés A, B, C, D, E, F, H, L, SP. Ils correspondent respectivement à : * l'accumulateur A ; * six registres nommés B, C, D, E, H et L ; * le registre d'état F ; * le pointeur de pile SP. Sur ces processeurs, les instructions dyadiques devaient mettre leur premier opérande dans l'accumulateur, la seconde provenait soit des registres, soit de la RAM, soit d'une constante immédiate. Les opérations monadiques pouvaient lire leur opérande depuis l'accumulateur, les autres registres ou la RAM, tout était permis. Les registres d'indices disparaissaient sur ces architectures, en théorie. Les registres généraux pouvaient être utilisés comme registre d'indice ou pour stocker des opérandes, ils étaient assez versatiles pour servir de registres d'indices. La présence de registres a de nombreux avantages, comparé aux architectures à accumulateur pures. Les instructions arithmétiques sont plus rapide, lire un registre étant plus rapide qu'un accès RAM. Les performances sont donc augmentées. De plus, les instructions arithmétiques utilisant ces registres sont plus courtes : pas besoin d'encoder une adresse mémoire, un nom de registre suffit. Vu que les processeurs de l’époque avaient des instructions de taille variable, cela améliorait la densité de code. La microarchitecture de ces processeurs est très similaire à celle d'un processeur avec des registres d'indices. La seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Le banc de registre est systématiquement monoport, car il n'avait aucune raison d'être multiport. Pour les instructions dyadiques, seules à lire deux opérandes, il ne servait que pour la seconde opérande, la première était lue depuis l'accumulateur. Les processeurs hybrides registre-accumulateur se classent en deux types principaux : ceux qui ont un seul bus interne, et ceux qui en ont deux. Le premier cas est identique à celui vu précédemment pour les architectures à accumulateur avec registres d'indice, à la seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Afin de gérer l'adressage indirect à registre, le bus interne est connecté aux deux registres d’interfaçage mémoire. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] Notons que cela permet aussi d'implémenter facilement les branchements indirects, car le bus interne permet d'échanger des adresses entre ''program counter'' et banc de registre. De même, il est possible d'utiliser l'ALU pour gérer les branchements indirects., en plus de l'utiliser pour incrémenter le ''program counter''. [[File:Single bus organization.jpg|centre|vignette|upright=2|Single bus organization]] Une autre solution utilisait deux bus internes : un connecté au bus de données, un autre relié au bus d'adresse. Le bus de commande mémoire était lui commandé par le séquenceur, l'unité de contrôle. L'intermédiaire entre ces deux bus était le banc de registre, ainsi que les autres registres. Le banc de registre était connecté aux deux bus interne, avec un port de lecture relié au bus d'adresse, un port de lecture-écriture relié au bus de données. Le port de lecture était utilisé pour l'adressage indirect, l'autre l'était pour le reste. [[File:Proz1-e.png|centre|vignette|upright=2|Intérieur d'un processeur.]] L'organisation à deux bus simplifiait la gestion du ''program counter'' et le chargement des instructions. Le ''program counter'' était soit séparé du banc de registre, soit placé dans le banc de registre. Les deux solutions étaient utilisés, tout dépend du processeur. Il faut noter que si le ''program counter'' est intégré au banc de registres, alors la microarchitecture du processeur est bien plus simple. L'envoi du ''program counter'' sur le bus d'adresse utilise le port de lecture relié au bus d'adresse, qui sert aussi pour l'adressage indirect. L'économie de circuits, sans compter la simplicité d'implémentation que cela implique, explique sans doute que la technique a été utilisée sur quelques processeurs anciens. Le ''program counter'' était généralement incrémenté par l'ALU, ce qui explique qu'il soit connecté au bus interne pour les données. La connexion est aussi utile pour gérer les branchements indirects, qui copient un registre dans le ''program counter'', ainsi que les branchements relatifs (addition dans l'ALU), voire les branchements directs (l'adresse vers laquelle brancher est envoyée en entrée de l'ALU et propagée en sortie avec une opération ''pass through''). [[File:Connexion du program counter sur les bus avec PC dans le banc de registres.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC dans le banc de registres]] ===Les registres d'interruption avec un processeur hybride-accumulateur : l'exemple du Z80=== Un exemple de processeur registre-accumulateur à deux bus interne est le Z80, un processeur fortement inspiré des CPU Intel 8 bits. Il a un jeu d'instruction similaire, mais a diverses améliorations par rapport au design original. Notamment, le processeur a des registres séparés pour les interruptions. Sur le Z80, les registres généraux sont dupliqués avec 6 registres pour les interruptions et 6 registres pour les programmes autres. Leur copie pour les interruptions sont nommées B', C', D', E', H', L'. Les 12 registres sont placés dans le banc de registre, ce qui implique que le fenêtrage de registres est utilisé pour gérer la séparation entre registre d'interruption et normaux. Il faut noter que l'accumulateur et le registre d'état sont aussi dupliqués, leurs copies étant nommées A' et F'. Mais leur duplication se fait autrement que par fenêtrage de registre. En plus des registres précédents, le Z80 incorporait deux registres d'indice nommés X et Y, ainsi qu'un pointeur de pile SP et un ''program counter'' PC. Ils n'étaient pas dupliqués pour les interruptions. Les registres d'indice étaient reliés à une unité de calcul d'adresse. L'unité de calcul d'adresse prenait deux opérandes : un indice, et une adresse mémoire provenant soit du banc de registre, soit de l'accumulateur. En clair, l'unité de calcul d'adresse faisait le lien entre les deux bus internet : le bus de données interne en entrée, le bus d'adresse en sortie. À l'intérieur du processeur, tous les registres étaient regroupés dans un banc de registre unique, sauf les accumulateurs, les registres d'état et le ''program counter''. Bien que ce ne soit pas indiqué sur le schéma ci-dessous, le ''program counter'' est séparé du banc de registre, alors que le pointeur de pile est dedans. Le compteur IR est lui associé au ''program counter'', il est sortit du banc de registre. Le Z80 utilise lui aussi un incrémenteur séparé de l'ALU, qui est utilisé pour mettre à jour le ''program counter'', le pointeur de pile et un compteur de rafraichissement mémoire nommé IR sur le Z80 (pour rappel, le rafraichissement mémoire demande de balayer la mémoire d'adresse en adresse et été fait par le CPU à l'époque). De plus, il est utilisé pour les instructions INC et DEC qui incrémentent une opérande de 16 bits obtenue en combinant deux registres de 8 bits. En clair, l'incrémenteur du ''program counter'' a été réutilisé de beaucoup de manières originales. [[File:Z80 arch.svg|centre|vignette|upright=3|Microarchitecture du Z80.]] Le Z80 incorporait des instructions pour échanger le contenu des deux ensembles de registres, accumulateur inclus. Elles permettaient d'utiliser les registres d'interruption pour les programmes et réciproquement. En clair, cela doublait le nombre de registres si les interruptions n'étaient pas utilisées. * L'instruction EXX échangeait les deux fenêtres de registres généraux : les registres B, C, D, E, H et L devenaient les registres B', C', D', E', H' et L' et inversement. * L'instruction EX échangeait l'accumulateur et le registre d'état : les registres A,F devenait A',F' et inversement. Le fenêtrage de registre était modifié par l'instruction EXX, qui échangeait les deux fenêtres de registres. Pour l'implémenter, une bascule était ajouté au processeur, appelons-la la bascule INT. Elle était relié au bus d'adresse du banc de registre, dont elle mémorisait le bit de poids fort. L'instruction EXX inversait la valeur de la bascule INT. Il est aussi possible d'échanger le contenu des registres D,E et H,L avec une instruction dédiée, ce qui est là encore fait par deux bascules : une pour les registres D,E et une autre pour les registres H,L. Pour l'accumulateur et le registre d'état, le choix entre registre normal et registre d'interruption se faisait là encore par une seconde bascule appelée la bascule A. La bascule est reliée à un multiplexeur et un démultiplexeur, qui permet de choisir quel accumulateur relier à l'unité de calcul. L'instruction EX inverse le contenu de la bascule A. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=L'unité de contrôle | prevText=L'unité de contrôle | next=Les processeurs 8 bits et moins | nextText=Les processeurs 8 bits et moins }} </noinclude> 2kk8xxygw1eip7u14p1rzc1lrrmgtwo 744141 744140 2025-06-05T00:39:12Z Mewtow 31375 /* Annexe : les toutes premières architectures à accumulateur : le Manchester Baby */ 744141 wikitext text/x-wiki Les architectures que nous avons vu précédemment dans ce cours disposent de registres pour les données, en plus du pointeur de pile, d'un ''program counter'', et de quelques autres. Elles sont appelées des '''architectures à registres''', terme qui trahit bien le fait qu'elles ont des registres généraux ou spécialisés pour stocker temporairement des données. Et si on leur a donné un nom, c'est parce qu'il existe des architectures qui ne sont pas dans cette catégorie. Il en existe plusieurs types, mais ce chapitre va se concentrer sur les '''architectures à accumulateur'''. [[File:Isaccumulator.png|vignette|Architecture à accumulateur.]] Les architectures à accumulateur sont centrées autour d'un registre architectural appelé l''''accumulateur'''. Il est utilisé pour toutes les opérations arithmétiques dyadiques, où il sert à la fois de source et de destination. Toutes les instructions dyadiques sont de type ''load-op'' : une opérande est lue depuis l'accumulateur, le second opérande est lu depuis la mémoire RAM, le résultat de l'instruction est automatiquement mémorisé dans l'accumulateur. Les instructions monadiques peuvent utiliser un opérande dans l'accumulateur, ou dans la mémoire RAM, les deux sont théoriquement possibles. La conséquence est que le nombre d'accès mémoire est drastiquement diminué : de 3 par instructions sur une architecture mémoire-mémoire, on passe à seulement un avec un accumulateur. Les opérations dyadiques ont besoin d'un seul accès mémoire pour lire la seconde opérande, les opérations monadique en font aussi un seul pour lire leur unique opérande. {|class="wikitable" |- ! Classe d'architecture ! Nombre d'accès mémoire par opération dyadique |- |- ! Architecture à accumulateur | Un accès mémoire par instruction, pour lire la seconde opérande |- ! Architecture à registres | Zéro si les opérandes sont dans les registres, un pour les opérations ''load-op'', LOAD et STORE. |} ==Le jeu d'instruction des architectures à accumulateur sans registres d'indice== L'accumulateur est adressé grâce au mode d'adressage implicite, de même que le résultat de l'opération. Par contre, les autres opérandes sont localisés avec d'autres modes d'adressage, et lues en mémoire RAM. Le résultat ainsi qu'un des opérandes sont adressés de façon implicite car dans l'accumulateur, seule la seconde opérande étant adressée directement. Grâce à l'accumulateur, une instruction ne fait qu'un seul accès mémoire maximum, ce qui rend le processeur très facile à implémenter. ===Les registres des anciennes architectures à accumulateur=== [[File:IBM 701console.jpg|vignette|IBM 701, console extérieure.]] Les architectures à accumulateur étaient communes dans les années 50-60. A l'époque, les ordinateurs étaient gigantesques, ils prenaient une pièce de bâtiment entière dans le pire des cas, une armoire entière dans le meilleur. Les ordinateurs de l'époque étaient surtout utilisés pour du calcul scientifique ou des tâches d’ingénierie demandant beaucoup de calcul, rarement pour de la compatibilité. Les nombres flottants n'étaient pas encore apparus. A la place, les ordinateurs de l'époque géraient des nombres entiers de grande taille, de 30 bits ou plus. En conséquence, l'accumulateur faisait facilement 30 à 60 bits. Par exemple, les ordinateurs de la Série scientifique IBM 700/7000 géraient des entiers de 36 bits, l’accumulateur faisait 38 bits : 36 bits plus deux bits pour les débordements. Au passage, de tels processeurs utilisaient l'adressage par mot, et non par byte. Historiquement, les premières architectures à accumulateur ne contenaient aucun autre registre que l'accumulateur. Ce n'est que dans les années 60 que de nombreuses architectures à accumulateur ont ajouté un second '''registre pour les multiplication/divisions'''. Un exemple est celui de l'IBM 701, qui incorporait un registre accumulateur de 38 bits et un registre multiplieur de 36 bits. Le registre mémorise le multiplieur lors d'une opération de multiplication. Il mémorise donc un opérande, pas le résultat. Il peut aussi décaler le multiplieur vers la droite/gauche, ce qui est utile pour exécuter la multiplication. C'est ce qui est fait sur l'IBM 7094. Une autre possibilité est que ce registre mémorise une partie du résultat de l'opération. Pour rappel, le résultat d'une multiplication/division est codé sur deux fois de bits que ses opérandes. Par exemple, multipliez deux opérandes de 30 bits, vous obtiendrez un résultat de 60 bits. Les 30 bits de poids faible du résultat vont dans l'accumulateur, les 30 bits de poids fort vont dans ce second registre. Les architectures à accumulateur parfois un '''registre pour le pointeur de pile''', utilisé pour gérer les fonctions/procédures. Les architectures à accumulateurs supportaient une pile d'adresse de retour, souvent une pile d'appel. Mais pour cela, il fallait mémoriser le pointeur de pile dans le processeur, ce qui demandait un registre dédié. ===L'adressage indirect avec l'accumulateur=== Les instructions LOAD et STORE existent bel et bien sur les architectures à accumulateur, mais n'ont pas les mêmes modes d'adressages. L'instruction LOAD copie une donnée de la RAM vers l'accumulateur, l'instruction STORE copie l'accumulateur dans une adresse. Les deux instructions n'ont pas besoin d'adresser l'accumulateur, qui est adressé de manière implicite, juste de préciser l'adresse à lire/écrire. Les architectures à accumulateur supportaient souvent le mode d'adressage indirect mémoire. Un exemple est celui des ordinateurs Data General Nova, qui sont des architectures à accumulateur et qui supportaient ce mode d'adressage. Les deux instructions LOAD et STORE existaient en deux versions, distinguées par un bit d'indirection. Si ce bit est à 0 dans l'opcode, alors l'instruction utilise le mode d'adressage absolu normal : l'adresse intégrée dans l'instruction est celle de la donnée. Mais s'il est à 1, alors l'adresse intégrée dans l'instruction est celle du pointeur. Cependant, la présence de l'accumulateur permettait d'utiliser l'adressage indirect à registre, pour gérer les pointeurs. Pour rappel, avec le mode d'adressage indirect à registre, l'adresse à lire/écrire est dans un registre. Ici, l'adresse à lire/écrire est prise dans l'accumulateur, seul registre disponible pour. L'adressage indirect est plus simple à implémenter pour l'instruction LOAD, car elle prend un seul opérande : l'adresse à lire. L'adresse à lire est placée dans l'accumulateur, la donnée lue est elle aussi chargée dans l'accumulateur. Pour l'instruction STORE, il faut fournir deux opérandes, l'adresse et la donnée à écrire, ce qui peut poser problème. Mais au pire, il est toujours possible d'utiliser l'adressage absolu ou indirect mémoire : l'adresse est dans l'instruction, la donnée à écrire dans l'accumulateur. ===L'encodage des instructions=== Sur une architecture à accumulateur l'encodage d'une instruction dyadique est assez simple, vu que l'accumulateur est adressé implicitement. La seconde opérande est localisée soit par une adresse mémoire (adressage absolu), soit est une constante (adressage immédiat). L'adresse mémoire est généralement assez longue, plus que l'opcode. {|class="wikitable" |+ Encodage d'une instruction dyadique |- ! rowspan="2" | Opcode | Adresse mémoire (adressage absolu) |- | Constante (adressage immédiat) |} L'encodage d'une instruction monadique est similaire. Si l'opérande est lue depuis la mémoire RAM, alors l'instruction est encodée comme une instruction dyadique. Il en est de même pour les instructions qui copient une constante dans l'accumulateur. Par contre, si l'opérande est dans l'accumulateur, alors il y a juste besoin d'encoder l'opcode. La majorité des instructions a besoin de préciser une adresse, rares sont celles qui s'en passent. Au vu de cet encodage, les architectures à accumulateur sont qualifiées d''''architectures à une adresse''' par abus de langage. Il est intéressant de contraster leur encodage avec les architectures à registres. Les architectures à registre doivent encoder deux opérandes en plus de l'opcode, avec éventuellement où enregistrer le résultat sur les architectures 3-adresses. Par contre, les opérandes sont généralement des noms de registre, ce qui prend moins de place qu'une adresse mémoire. A la rigueur, les instructions avec une constante immédiate prennent un peu plus de place, car elles doivent encoder un nom de registre en plus de la constante et de l'opcode. Les instructions ''load-op'' des processeurs CISC sont un peu dans le même cas, sauf qu'il faut remplacer la constante par une adresse, qui a généralement la même taille. Les instructions sont donc en moyenne plus courte sur les processeurs à registre, du fait de la présence de registres. ===Annexe : les toutes premières architectures à accumulateur : le Manchester Baby=== [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] Les architectures à accumulateurs sont apparues dès les débuts de l'informatique. Le tout premier ordinateur à programme enregistré en mémoire, le ''Manchester Baby'', était une architecture à accumulateur. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 adresses, fabriquée avec des tubes Williams (abordés dans une annexe à la fin du cours). Chaque adresse mémorisait 32 bits, qui pouvaient encoder soit un nombre, soit une instruction. Le programme devait tenir dans la RAM, avec une instruction par adresse maximum, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 servait à indiquer où se trouvent les opérandes en RAM, les 16 restants sont inutilisés. Le processeur avait un registre accumulateur de 32 bits, un ''program counter'' et un registre d'instruction. Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. L'ALU était une ALU sérielle, à savoir qu'elle faisait les soustractions bit par bit. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. C'était là encore une architecture à accumulateur, sauf qu'elle intégrait aussi des registres d'indice. Et surtout : son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. [[File:MM1Schematic French.svg|centre|vignette|upright=2.5|Architecture de la Manchester Mark 1.]] ==La micro-architecture des architectures à accumulateur sans registres d'indice== L'organisation interne d'une architecture à accumulateur est très différente de celle des processeurs à registre. Elle est plus ou moins la même pour tous ces processeurs, le point important étant que le chemin de données se résume à une ALU, un registre accumulateur et le bus de données. L'ALU est reliée au registre accumulateur, ainsi qu'au bus de données pour lire la seconde opérande, comme illustré ci-dessous. [[File:Accumulator.png|centre|vignette|upright=2|Accumulateur.]] ===L'unité de calcul et l'accumulateur=== Pour simplifier l'implémentation, le résultat est mémorisé dans un registre en sortie de l'unité de calcul. La raison est qu'on ne veut pas altérer l'accumulateur tant que le résultat final n'est pas totalement calculé. Rappelons que l'ALU ne fournit pas un résultat d'un seul bloc, mais que certains bits arrivent avant les autres, typiquement les bits de poids faible. Si le résultat était écrit dans l'accumulateur directement, il écraserait des bits de l’opérande en cours d'utilisation, ce qui fausserait le résultat. [[File:Accumulateur avec registre de sortie.png|centre|vignette|upright=2|Accumulateur avec registre de sortie]] Une autre solution utilisait un registre entre l'accumulateur et l'unité de calcul, appelé l’'''''accumulator latch'''''. Il remplace le registre en sortie de l'ALU, dans le sens où il permet d'écrire dans l'accumulateur sans effacer l'opérande, pendant que l’opération est en cours dans l'ALU. L'accumulateur est copié dans l’''accumulator latch'', avant que l'ALU démarre ses calculs. L'opérande est donc maintenue même si on commence à écrire le résultat dans l'accumulateur. Sur le 8085 d'Intel, l’''accumulator latch'' peut être initialisé avec une constante prédéfinie, ce qui permet d'implémenter certaines instructions très facilement. Par exemple, il peut être initialisé à 0, ce qui permet d'implémenter les instructions MOV et INC (incrémentation). Un MOV est équivalent à faire un OU entre le registre lu et 0. Une instruction INC initialise l'entrée de retenue de l'unité de calcul à 1, puis ajoute 0. La décrémentation est implémentée de la même manière, sauf que l’''accumulator latch'' est initialisé à -2 pour compenser l'entrée de retenue à 1. De plus, pour supporter les conversion de décimal à BCD, l’''accumulator latch'' peut être initialisé avec les constantes 0x00, 0x06, 0x60, or 0x66. L'''accumulator latch'' est relié à divers fils de commande provenant de l'unité de contrôle, qui décide quelle valeur d'initialisation utiliser en fonction de l'instruction décodée. [[File:Accumulator latch.png|centre|vignette|upright=2|Accumulator latch]] [[File:Chemin de données à un seul bus.png|vignette|Chemin de données à un seul bus]] De même, la seconde opérande, celle lue sur le bus de données, est mémorisée dans un registre en amont de l'ALU. C'était notamment très utile si le processeur utilisait une ALU plus courte que les opérandes, avec par exemple une ALU 4 bits pour un CPU 8 bits. Les anciens processeurs à accumulateur de type ''mainframe'' utilisaient des opérandes de grande taille, du genre 36 ou 48 bits, ce qui avait des conséquences sur l'unité de calcul utilisée, ainsi que sur la communication avec la mémoire. Il arrivait que de tels processeurs utilisaient des ALU sérielles, ou du moins octet-sérielles, plutôt qu'une véritable ALU 36 bits. Nous verrons aussi que c'est très utile sur les processeurs à accumulateur avec un bus interne unique, dans la suite du chapitre. ===La micro-architecture des architectures à accumulateur avec instructions LOAD/STORE=== Nous venons de voir comment est implémenté l'unité de calcul et l'accumulateur, et comment le tout est relié au bus de données. Mais cela ne permet que d'avoir un processeur à accumulateur rudimentaire, qui ne gére que des instructions arithmétiques et logiques. Il faut aussi gérer le cas des opérations LOAD/STORE et des modes d'adressages associés, mais c'est le séquenceur qui s'en occupe. Avec l'adressage absolu, les instructions LOAD et STORE ne font que connecter l'accumulateur au bus de données. L'instruction STORE nécessite de connecter l'accumulateur au bus de données, de manière à ce que le transfert des données se fasse de l'accumulateur vers le bus de données. L'instruction LOAD s'implémente de la même manière, sauf que le sens de transfert est inversé. Cependant, il existe une optimisation qui permet d'implémenter l'instruction LOAD sans ajouter de circuits. Pour cela, il suffit que l'unité de calcul gére les opérations ''pass through'', à savoir des opérations qui se contentent de recopier un opérande sur la sortie. Ici, l'idée est de recopier l'opérande provenant du bus de données. [[File:Architecture à accumulateur, microarchitecture.png|centre|vignette|upright=2|Architecture à accumulateur, microarchitecture]] Pour gérer nativement l'adressage indirect à registre, il suffit de connecter l'accumulateur au bus d'adresse. Le plus simple est d'ajouter un multiplexeur, comme illustré ci-dessous. La donnée lue est copiée dans l'accumulateur, ce qui fait qu'il vaut mieux utiliser un registre d’interfaçage, l'accumulateur n'étant pas utilisable à la fois pour le bus d'adresse et de données. [[File:Adressage indirect sur une architecture à accumulateur.png|centre|vignette|upright=2|Adressage indirect sur une architecture à accumulateur]] Pour finir, voyons comment le pointeur de pile et le ''program counter'' sont implémentés. Les architectures à accumulateur ont souvent des adresses de taille différente des données, ce qui fait qu'il vaut mieux utiliser un circuit incrémenteur dédié pour incrémenter le ''program counter'', plutôt que de l'incrémenter via l'unité de calcul. Les architectures à accumulateur ont parfois un pointeur de pile, qui gère une pile d'adresse de retour, pas une vraie pile d'appel. Aussi, le pointeur de pile est censé être incrémenté et décrémenté, pas plus. Pas d'addition ou de soustraction pour gérer des cadres de pile. Là encore, c'est la solution de l'incrémenteur séparé qui est retenue. Pour économiser des transistors, il n'y a qu'un seul incrémenteur partagé pour les deux. ==Les architectures à accumulateur à registres d'indice== Les architectures à accumulateur décrites dans la section précédente sont capables de faire de l'adressage indirect, mais n'incluent pas les modes d'adressage base + indice et absolus indicés, qui prennent une adresse et y ajoute un indice. Il s'agit des toutes premières architectures à accumulateur, comme les premiers ordinateurs IBM ou le fameux PDP-8. Mais par la suite, les processeurs à accumulateurs ont inclus un support des modes d'adressages indicés, grâce à des '''registres d'indice'''. ===Les registres d'indice=== Les registres d'indice stockent des indices de tableaux. Ils permettaient de supporter deux modes d'adressage : * Le '''mode d'adressage absolu indicé''' où une adresse fixe est additionnée à un indice variable. L'adresse fixe est intégrée dans l'instruction (adressage absolu), l'indice est dans un registre d'indice. * Le '''mode d'adressage base + indice''', où l'adresse est dans l'accumulateur et l'indice dans le registre d'indice. Les processeurs à accumulateur supportaient souvent des variantes des modes d'adressage précédents, où le registre d'indice était automatiquement incrémenté ou décrémenté à chaque utilisation. Au départ, ces processeurs n'utilisaient qu'un seul registre d'indice qui se comportait comme un second accumulateur spécialisé dans les calculs d'adresses mémoire. Le processeur supportait de nouvelles instructions qui utilisaient ce registre d'indice de façon implicite. Mais avec le temps, les processeurs finirent par incorporer plusieurs de ces registres. Les instructions de lecture ou d'écriture devaient alors préciser quel registre d'indice utiliser, en précisant un nom de registre d'indice, un numéro de registre d'indice. Il faut préciser que les registres d'indice ont une taille bien plus petite que l'accumulateur. Ils mémorisent des indices codés sur 16 bits ou moins, alors que l'accumulateur faisait typiquement 36 à 48 bits, parfois plus. La taille classique sur les anciens ''mainframes'' était de 15 bits, parfois moins. Il n'était pas rare de tomber sur des registres d'indice de 8 ou 9 bits. Leur petite taille rendait leur implémentation matérielle peu couteuse. Et c'est ce qui explique qu'ils étaient préférés à l'usage d'un second accumulateur. Un exemple est le cas du processeur Motorola 6809, un processeur à accumulateur qui contient deux registres d'indices nommés X et Y. L'accumulateur est noté D et fait 16 bits, il peut être parfois géré comme deux accumulateurs séparés A et B de 8 bits chacun. Il contenait aussi deux pointeurs de pile, l'un pour les programmes, l'autre pour le système d'exploitation, ainsi qu'un ''program counter''. Le registre de page était utilisé pour l'adressage absolu, comme vu dans le chapitre sur les modes d'adressage. [[File:6809 Internal Registers.svg|centre|vignette|upright=2|6809 Internal Registers]] Les processeurs IBM avaient autrefois plusieurs registres d'indice. Par exemple, l'IBM 704 avait trois registres d'indice de 15 bits. Leur contenu était soustrait de l'adresse absolue. Une instruction pouvait utiliser plusieurs registres d'indice pour adresser son opérande. Toute instruction utilisait trois bits pour sélectionner les registres d'indice utilisés. Fait assez original, lorsque plusieurs registres d'indice sont sélectionnés, le processeur n'additionne pas les trois registres à l'adresse de base. À la place, il fait un OU bit à bit entre les registres d'indice sélectionnés, et additionne le résultat à l'adresse. Les processeurs IBM à accumulateur ont fait ça sur toute la gamme IBM 700/7000, pour des raisons de compatibilité. Les processeurs suivants avaient 7 registres d'indices, mais conservaient les trois bits pour adresser les registres d'indices. Ils pouvaient fonctionner dans deux modes. Le premier mode est plus intuitif : les trois bits précisent un registre d'indice parmi les 7, qui est additionné avec l'adresse absolue. La valeur zéro indique qu'aucun registre d'indice n'est utilisé, ce qui explique qu'il y a 7 registres d'indice et non 8. Un second mode, compatible avec l'IBM 704, fait un OU logique entre les registres d'indice sélectionnés. Seuls les trois premiers registres d'indices peuvent être sélectionnés dans ce mode. Il y a deux instructions pour changer de mode : une pour passer en mode compatible, l'autre pour le quitter pour l'autre mode. Quelques rares processeurs à registres généraux ont utilisés des registres d'indice, en plus des registres généraux. Ce qui fait l'association que nous avons faite entre registres d'indice et architectures à accumulateur est imparfait, bien que solide sur le principe. Un exemple d'architecture de ce type sont les architectures de la série UNIVAC 1100/2200. Ils disposaient de 128 registres, qui étaient mappés en mémoire à partir de l'adresse mémoire 0, la majorité étant inaccessibles par le programmeur. Ils regroupaient 12 registres accumulateurs, 11 registres d'indice et 4 registres hybrides qui pouvaient servir soit de registre d'indice, soit de registres accumulateurs. ===La micro-architecture des architectures à accumulateur avec registres d'indice=== La présence de registres d'indice modifie grandement l'implémentation du processeur. En effet, il faut rajouter un banc de registre pour les registres d'indice. Le banc de registre est monoport, car on a besoin de lire ou d'écrire un indice à la fois. Et il faut aussi potentiellement rajouter de quoi faire les calculs d'adresse. Deux solutions sont possibles : une ALU dédiée aux calculs d'adresse, une seule ALU pour toutes les opérations. Dans le premier cas, il y a une ALU séparée associée aux registres d'indice. L'ALU et les registres d'indice sont placés en sortie du séquenceur, en-dehors du chemin de données, la sortie de l'ALU est directement connectée au bus d'adresse. L'unité de calcul d'adresse peut être utilisée pour incrémenter le ''program counter''. Un défaut de cette approche est qu'elle ne gère pas l'adresse indirect à registre. [[File:Chemin de données sans support des pointeurs, avec adressage absolu indicé.png|centre|vignette|upright=2|Chemin de données sans support des pointeurs, avec adressage absolu indicé]] Une autre option utilise un bus interne, qui interconnecte tout le chemin de données. Dans sa version la plus simple, il est relié à l'accumulateur, l'unité de calcul, le banc de registre d'indice et le bus de données. Avec cette solution, l'ALU est utilisé à la fois pour calculer les adresses et pour les instructions de calcul. En reliant le bus interne au bus d'adresse à travers un multiplexeur, on gère naturellement les adressages indirects. [[File:Architecture à accumulateur avec registres associés.png|centre|vignette|upright=2.5|Architecture à accumulateur avec registres associés]] Il faut noter que sur les architectures Von Neumann, le séquenceur est relié à ce bus interne. En effet, charger une instruction demande de passer par le bus mémoire, donc par l’intermédiaire de ce bus internet. Le ''program counter'' est envoyé sur ce bus pour lire l'instruction, puis l'instruction lue est recopiée dans le registre d'instruction. Le chargement d'une instruction est donc géré comme une lecture des plus classiques. De plus, cela permet d'incrémenter le ''program counter'' au niveau de l'unité de calcul entière. Le ''program counter'' est envoyé sur le bus interne, incrémenté par l'ALU, puis le résultat est recopié dans le ''program counter'' via le bus interne. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] ==Les processeurs bi-accumulateurs : le Motorola 6800== Le Motorola 6800 était un processeur 8 bits qui gérait des adresses de 16 bits. Il contenait deux accumulateurs nommés A et B, de 8 bits chacun. Il disposait aussi d'un registre d'indice, d'un pointeur de pile et d'un ''program counter'', tous les trois de 16 bits. Le registre d'état regroupait 6 bits, qu'on ne détaillera pas ici. [[File:MC6800 Processor Diagram.png|centre|vignette|upright=2|Interface et registres du MC6800.]] La présence des deux accumulateurs impactait surtout les instructions dyadiques. Les instructions monadiques avaient juste à préciser où se trouvait l'opérande : soit en RAM, soit dans le premier accumulateur, soit dans le second. Pour les opérations dyadiques, la gestion était totalement différente. En théorie, le premier opérande est dans un accumulateur, soit A, soit B. La seconde opérande vient soit de l'autre accumulateur, soit de la mémoire RAM. Et selon les instructions, tout variait. Pour l'addition, il y avait trois instructions. Les deux premières additionnaient un opérande provenant de la mémoire avec un accumulateur. L'instruction ADDA sélectionnait le premier accumulateur, l'instruction ADDB sélectionnait le second accumulateur. Mais une troisième instruction, l’instruction ABA, permettait d'additionner le contenu des deux accumulateurs. Pour les autres opérations, il n'était pas possible d'utiliser les deux accumulateurs en même temps. La seule possibilité était de faire une opération entre un accumulateur et un opérande venant de la mémoire. Toutes les instructions étaient en double, avec une copie par accumulateur. Par exemple, l'instruction ANDA faisait un ET entre l’accumulateur A et l'opérande mémoire, l'instruction ANDB faisait pareil avec l'accumulateur B. ==Les architectures hybrides registres-accumulateur== Il a existé quelques architectures qui étaient des hybrides entre architectures à accumulateur et architecture à registre. Elles ont servi de transition entre les deux, durant les années 80-90. Elles avaient un accumulateur unique couplé à un banc de registres généraux. Par exemple, les premiers processeurs Intel 8 bits étaient des processeurs hybrides-accumulateur. Lles CPU Intel 8 bits disposaient de 7 registres de 8 bits nommés A, B, C, D, E, F, H, L, SP. Ils correspondent respectivement à : * l'accumulateur A ; * six registres nommés B, C, D, E, H et L ; * le registre d'état F ; * le pointeur de pile SP. Sur ces processeurs, les instructions dyadiques devaient mettre leur premier opérande dans l'accumulateur, la seconde provenait soit des registres, soit de la RAM, soit d'une constante immédiate. Les opérations monadiques pouvaient lire leur opérande depuis l'accumulateur, les autres registres ou la RAM, tout était permis. Les registres d'indices disparaissaient sur ces architectures, en théorie. Les registres généraux pouvaient être utilisés comme registre d'indice ou pour stocker des opérandes, ils étaient assez versatiles pour servir de registres d'indices. La présence de registres a de nombreux avantages, comparé aux architectures à accumulateur pures. Les instructions arithmétiques sont plus rapide, lire un registre étant plus rapide qu'un accès RAM. Les performances sont donc augmentées. De plus, les instructions arithmétiques utilisant ces registres sont plus courtes : pas besoin d'encoder une adresse mémoire, un nom de registre suffit. Vu que les processeurs de l’époque avaient des instructions de taille variable, cela améliorait la densité de code. La microarchitecture de ces processeurs est très similaire à celle d'un processeur avec des registres d'indices. La seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Le banc de registre est systématiquement monoport, car il n'avait aucune raison d'être multiport. Pour les instructions dyadiques, seules à lire deux opérandes, il ne servait que pour la seconde opérande, la première était lue depuis l'accumulateur. Les processeurs hybrides registre-accumulateur se classent en deux types principaux : ceux qui ont un seul bus interne, et ceux qui en ont deux. Le premier cas est identique à celui vu précédemment pour les architectures à accumulateur avec registres d'indice, à la seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Afin de gérer l'adressage indirect à registre, le bus interne est connecté aux deux registres d’interfaçage mémoire. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] Notons que cela permet aussi d'implémenter facilement les branchements indirects, car le bus interne permet d'échanger des adresses entre ''program counter'' et banc de registre. De même, il est possible d'utiliser l'ALU pour gérer les branchements indirects., en plus de l'utiliser pour incrémenter le ''program counter''. [[File:Single bus organization.jpg|centre|vignette|upright=2|Single bus organization]] Une autre solution utilisait deux bus internes : un connecté au bus de données, un autre relié au bus d'adresse. Le bus de commande mémoire était lui commandé par le séquenceur, l'unité de contrôle. L'intermédiaire entre ces deux bus était le banc de registre, ainsi que les autres registres. Le banc de registre était connecté aux deux bus interne, avec un port de lecture relié au bus d'adresse, un port de lecture-écriture relié au bus de données. Le port de lecture était utilisé pour l'adressage indirect, l'autre l'était pour le reste. [[File:Proz1-e.png|centre|vignette|upright=2|Intérieur d'un processeur.]] L'organisation à deux bus simplifiait la gestion du ''program counter'' et le chargement des instructions. Le ''program counter'' était soit séparé du banc de registre, soit placé dans le banc de registre. Les deux solutions étaient utilisés, tout dépend du processeur. Il faut noter que si le ''program counter'' est intégré au banc de registres, alors la microarchitecture du processeur est bien plus simple. L'envoi du ''program counter'' sur le bus d'adresse utilise le port de lecture relié au bus d'adresse, qui sert aussi pour l'adressage indirect. L'économie de circuits, sans compter la simplicité d'implémentation que cela implique, explique sans doute que la technique a été utilisée sur quelques processeurs anciens. Le ''program counter'' était généralement incrémenté par l'ALU, ce qui explique qu'il soit connecté au bus interne pour les données. La connexion est aussi utile pour gérer les branchements indirects, qui copient un registre dans le ''program counter'', ainsi que les branchements relatifs (addition dans l'ALU), voire les branchements directs (l'adresse vers laquelle brancher est envoyée en entrée de l'ALU et propagée en sortie avec une opération ''pass through''). [[File:Connexion du program counter sur les bus avec PC dans le banc de registres.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC dans le banc de registres]] ===Les registres d'interruption avec un processeur hybride-accumulateur : l'exemple du Z80=== Un exemple de processeur registre-accumulateur à deux bus interne est le Z80, un processeur fortement inspiré des CPU Intel 8 bits. Il a un jeu d'instruction similaire, mais a diverses améliorations par rapport au design original. Notamment, le processeur a des registres séparés pour les interruptions. Sur le Z80, les registres généraux sont dupliqués avec 6 registres pour les interruptions et 6 registres pour les programmes autres. Leur copie pour les interruptions sont nommées B', C', D', E', H', L'. Les 12 registres sont placés dans le banc de registre, ce qui implique que le fenêtrage de registres est utilisé pour gérer la séparation entre registre d'interruption et normaux. Il faut noter que l'accumulateur et le registre d'état sont aussi dupliqués, leurs copies étant nommées A' et F'. Mais leur duplication se fait autrement que par fenêtrage de registre. En plus des registres précédents, le Z80 incorporait deux registres d'indice nommés X et Y, ainsi qu'un pointeur de pile SP et un ''program counter'' PC. Ils n'étaient pas dupliqués pour les interruptions. Les registres d'indice étaient reliés à une unité de calcul d'adresse. L'unité de calcul d'adresse prenait deux opérandes : un indice, et une adresse mémoire provenant soit du banc de registre, soit de l'accumulateur. En clair, l'unité de calcul d'adresse faisait le lien entre les deux bus internet : le bus de données interne en entrée, le bus d'adresse en sortie. À l'intérieur du processeur, tous les registres étaient regroupés dans un banc de registre unique, sauf les accumulateurs, les registres d'état et le ''program counter''. Bien que ce ne soit pas indiqué sur le schéma ci-dessous, le ''program counter'' est séparé du banc de registre, alors que le pointeur de pile est dedans. Le compteur IR est lui associé au ''program counter'', il est sortit du banc de registre. Le Z80 utilise lui aussi un incrémenteur séparé de l'ALU, qui est utilisé pour mettre à jour le ''program counter'', le pointeur de pile et un compteur de rafraichissement mémoire nommé IR sur le Z80 (pour rappel, le rafraichissement mémoire demande de balayer la mémoire d'adresse en adresse et été fait par le CPU à l'époque). De plus, il est utilisé pour les instructions INC et DEC qui incrémentent une opérande de 16 bits obtenue en combinant deux registres de 8 bits. En clair, l'incrémenteur du ''program counter'' a été réutilisé de beaucoup de manières originales. [[File:Z80 arch.svg|centre|vignette|upright=3|Microarchitecture du Z80.]] Le Z80 incorporait des instructions pour échanger le contenu des deux ensembles de registres, accumulateur inclus. Elles permettaient d'utiliser les registres d'interruption pour les programmes et réciproquement. En clair, cela doublait le nombre de registres si les interruptions n'étaient pas utilisées. * L'instruction EXX échangeait les deux fenêtres de registres généraux : les registres B, C, D, E, H et L devenaient les registres B', C', D', E', H' et L' et inversement. * L'instruction EX échangeait l'accumulateur et le registre d'état : les registres A,F devenait A',F' et inversement. Le fenêtrage de registre était modifié par l'instruction EXX, qui échangeait les deux fenêtres de registres. Pour l'implémenter, une bascule était ajouté au processeur, appelons-la la bascule INT. Elle était relié au bus d'adresse du banc de registre, dont elle mémorisait le bit de poids fort. L'instruction EXX inversait la valeur de la bascule INT. Il est aussi possible d'échanger le contenu des registres D,E et H,L avec une instruction dédiée, ce qui est là encore fait par deux bascules : une pour les registres D,E et une autre pour les registres H,L. Pour l'accumulateur et le registre d'état, le choix entre registre normal et registre d'interruption se faisait là encore par une seconde bascule appelée la bascule A. La bascule est reliée à un multiplexeur et un démultiplexeur, qui permet de choisir quel accumulateur relier à l'unité de calcul. L'instruction EX inverse le contenu de la bascule A. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=L'unité de contrôle | prevText=L'unité de contrôle | next=Les processeurs 8 bits et moins | nextText=Les processeurs 8 bits et moins }} </noinclude> 8gj97m8c5t53ho5ux8dwtvf7oh7v7mr 744154 744141 2025-06-05T13:48:52Z Mewtow 31375 /* Annexe : les toutes premières architectures à accumulateur : le Manchester Baby */ 744154 wikitext text/x-wiki Les architectures que nous avons vu précédemment dans ce cours disposent de registres pour les données, en plus du pointeur de pile, d'un ''program counter'', et de quelques autres. Elles sont appelées des '''architectures à registres''', terme qui trahit bien le fait qu'elles ont des registres généraux ou spécialisés pour stocker temporairement des données. Et si on leur a donné un nom, c'est parce qu'il existe des architectures qui ne sont pas dans cette catégorie. Il en existe plusieurs types, mais ce chapitre va se concentrer sur les '''architectures à accumulateur'''. [[File:Isaccumulator.png|vignette|Architecture à accumulateur.]] Les architectures à accumulateur sont centrées autour d'un registre architectural appelé l''''accumulateur'''. Il est utilisé pour toutes les opérations arithmétiques dyadiques, où il sert à la fois de source et de destination. Toutes les instructions dyadiques sont de type ''load-op'' : une opérande est lue depuis l'accumulateur, le second opérande est lu depuis la mémoire RAM, le résultat de l'instruction est automatiquement mémorisé dans l'accumulateur. Les instructions monadiques peuvent utiliser un opérande dans l'accumulateur, ou dans la mémoire RAM, les deux sont théoriquement possibles. La conséquence est que le nombre d'accès mémoire est drastiquement diminué : de 3 par instructions sur une architecture mémoire-mémoire, on passe à seulement un avec un accumulateur. Les opérations dyadiques ont besoin d'un seul accès mémoire pour lire la seconde opérande, les opérations monadique en font aussi un seul pour lire leur unique opérande. {|class="wikitable" |- ! Classe d'architecture ! Nombre d'accès mémoire par opération dyadique |- |- ! Architecture à accumulateur | Un accès mémoire par instruction, pour lire la seconde opérande |- ! Architecture à registres | Zéro si les opérandes sont dans les registres, un pour les opérations ''load-op'', LOAD et STORE. |} ==Le jeu d'instruction des architectures à accumulateur sans registres d'indice== L'accumulateur est adressé grâce au mode d'adressage implicite, de même que le résultat de l'opération. Par contre, les autres opérandes sont localisés avec d'autres modes d'adressage, et lues en mémoire RAM. Le résultat ainsi qu'un des opérandes sont adressés de façon implicite car dans l'accumulateur, seule la seconde opérande étant adressée directement. Grâce à l'accumulateur, une instruction ne fait qu'un seul accès mémoire maximum, ce qui rend le processeur très facile à implémenter. ===Les registres des anciennes architectures à accumulateur=== [[File:IBM 701console.jpg|vignette|IBM 701, console extérieure.]] Les architectures à accumulateur étaient communes dans les années 50-60. A l'époque, les ordinateurs étaient gigantesques, ils prenaient une pièce de bâtiment entière dans le pire des cas, une armoire entière dans le meilleur. Les ordinateurs de l'époque étaient surtout utilisés pour du calcul scientifique ou des tâches d’ingénierie demandant beaucoup de calcul, rarement pour de la compatibilité. Les nombres flottants n'étaient pas encore apparus. A la place, les ordinateurs de l'époque géraient des nombres entiers de grande taille, de 30 bits ou plus. En conséquence, l'accumulateur faisait facilement 30 à 60 bits. Par exemple, les ordinateurs de la Série scientifique IBM 700/7000 géraient des entiers de 36 bits, l’accumulateur faisait 38 bits : 36 bits plus deux bits pour les débordements. Au passage, de tels processeurs utilisaient l'adressage par mot, et non par byte. Historiquement, les premières architectures à accumulateur ne contenaient aucun autre registre que l'accumulateur. Ce n'est que dans les années 60 que de nombreuses architectures à accumulateur ont ajouté un second '''registre pour les multiplication/divisions'''. Un exemple est celui de l'IBM 701, qui incorporait un registre accumulateur de 38 bits et un registre multiplieur de 36 bits. Le registre mémorise le multiplieur lors d'une opération de multiplication. Il mémorise donc un opérande, pas le résultat. Il peut aussi décaler le multiplieur vers la droite/gauche, ce qui est utile pour exécuter la multiplication. C'est ce qui est fait sur l'IBM 7094. Une autre possibilité est que ce registre mémorise une partie du résultat de l'opération. Pour rappel, le résultat d'une multiplication/division est codé sur deux fois de bits que ses opérandes. Par exemple, multipliez deux opérandes de 30 bits, vous obtiendrez un résultat de 60 bits. Les 30 bits de poids faible du résultat vont dans l'accumulateur, les 30 bits de poids fort vont dans ce second registre. Les architectures à accumulateur parfois un '''registre pour le pointeur de pile''', utilisé pour gérer les fonctions/procédures. Les architectures à accumulateurs supportaient une pile d'adresse de retour, souvent une pile d'appel. Mais pour cela, il fallait mémoriser le pointeur de pile dans le processeur, ce qui demandait un registre dédié. ===L'adressage indirect avec l'accumulateur=== Les instructions LOAD et STORE existent bel et bien sur les architectures à accumulateur, mais n'ont pas les mêmes modes d'adressages. L'instruction LOAD copie une donnée de la RAM vers l'accumulateur, l'instruction STORE copie l'accumulateur dans une adresse. Les deux instructions n'ont pas besoin d'adresser l'accumulateur, qui est adressé de manière implicite, juste de préciser l'adresse à lire/écrire. Les architectures à accumulateur supportaient souvent le mode d'adressage indirect mémoire. Un exemple est celui des ordinateurs Data General Nova, qui sont des architectures à accumulateur et qui supportaient ce mode d'adressage. Les deux instructions LOAD et STORE existaient en deux versions, distinguées par un bit d'indirection. Si ce bit est à 0 dans l'opcode, alors l'instruction utilise le mode d'adressage absolu normal : l'adresse intégrée dans l'instruction est celle de la donnée. Mais s'il est à 1, alors l'adresse intégrée dans l'instruction est celle du pointeur. Cependant, la présence de l'accumulateur permettait d'utiliser l'adressage indirect à registre, pour gérer les pointeurs. Pour rappel, avec le mode d'adressage indirect à registre, l'adresse à lire/écrire est dans un registre. Ici, l'adresse à lire/écrire est prise dans l'accumulateur, seul registre disponible pour. L'adressage indirect est plus simple à implémenter pour l'instruction LOAD, car elle prend un seul opérande : l'adresse à lire. L'adresse à lire est placée dans l'accumulateur, la donnée lue est elle aussi chargée dans l'accumulateur. Pour l'instruction STORE, il faut fournir deux opérandes, l'adresse et la donnée à écrire, ce qui peut poser problème. Mais au pire, il est toujours possible d'utiliser l'adressage absolu ou indirect mémoire : l'adresse est dans l'instruction, la donnée à écrire dans l'accumulateur. ===L'encodage des instructions=== Sur une architecture à accumulateur l'encodage d'une instruction dyadique est assez simple, vu que l'accumulateur est adressé implicitement. La seconde opérande est localisée soit par une adresse mémoire (adressage absolu), soit est une constante (adressage immédiat). L'adresse mémoire est généralement assez longue, plus que l'opcode. {|class="wikitable" |+ Encodage d'une instruction dyadique |- ! rowspan="2" | Opcode | Adresse mémoire (adressage absolu) |- | Constante (adressage immédiat) |} L'encodage d'une instruction monadique est similaire. Si l'opérande est lue depuis la mémoire RAM, alors l'instruction est encodée comme une instruction dyadique. Il en est de même pour les instructions qui copient une constante dans l'accumulateur. Par contre, si l'opérande est dans l'accumulateur, alors il y a juste besoin d'encoder l'opcode. La majorité des instructions a besoin de préciser une adresse, rares sont celles qui s'en passent. Au vu de cet encodage, les architectures à accumulateur sont qualifiées d''''architectures à une adresse''' par abus de langage. Il est intéressant de contraster leur encodage avec les architectures à registres. Les architectures à registre doivent encoder deux opérandes en plus de l'opcode, avec éventuellement où enregistrer le résultat sur les architectures 3-adresses. Par contre, les opérandes sont généralement des noms de registre, ce qui prend moins de place qu'une adresse mémoire. A la rigueur, les instructions avec une constante immédiate prennent un peu plus de place, car elles doivent encoder un nom de registre en plus de la constante et de l'opcode. Les instructions ''load-op'' des processeurs CISC sont un peu dans le même cas, sauf qu'il faut remplacer la constante par une adresse, qui a généralement la même taille. Les instructions sont donc en moyenne plus courte sur les processeurs à registre, du fait de la présence de registres. ===Annexe : les toutes premières architectures à accumulateur : le Manchester Baby=== [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] Les architectures à accumulateurs sont apparues dès les débuts de l'informatique. Le tout premier ordinateur à programme enregistré en mémoire, le ''Manchester Baby'', était une architecture à accumulateur. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 adresses, fabriquée avec des tubes Williams (abordés dans une annexe à la fin du cours). Chaque adresse mémorisait 32 bits, qui pouvaient encoder soit un nombre, soit une instruction. Le programme devait tenir dans la RAM, avec une instruction par adresse maximum, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 servait à indiquer où se trouvent la seconde opérande en RAM, les 16 restants sont inutilisés. Le processeur avait un registre accumulateur de 32 bits, un ''program counter'' et un registre d'instruction. Il gérait 8 instructions en tout, mais ne gérait pas l'addition. Il gérait la soustraction, des instructions de branchement et d'accès mémoire, rien d'autre. Il pouvait cependant émuler l'addition à partir d'une soustraction et inversant l'opérande soustraite. L'ALU était une ALU sérielle, à savoir qu'elle faisait les soustractions bit par bit. Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. C'était là encore une architecture à accumulateur, sauf qu'elle intégrait aussi des registres d'indice. Et surtout : son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. [[File:MM1Schematic French.svg|centre|vignette|upright=2.5|Architecture de la Manchester Mark 1.]] ==La micro-architecture des architectures à accumulateur sans registres d'indice== L'organisation interne d'une architecture à accumulateur est très différente de celle des processeurs à registre. Elle est plus ou moins la même pour tous ces processeurs, le point important étant que le chemin de données se résume à une ALU, un registre accumulateur et le bus de données. L'ALU est reliée au registre accumulateur, ainsi qu'au bus de données pour lire la seconde opérande, comme illustré ci-dessous. [[File:Accumulator.png|centre|vignette|upright=2|Accumulateur.]] ===L'unité de calcul et l'accumulateur=== Pour simplifier l'implémentation, le résultat est mémorisé dans un registre en sortie de l'unité de calcul. La raison est qu'on ne veut pas altérer l'accumulateur tant que le résultat final n'est pas totalement calculé. Rappelons que l'ALU ne fournit pas un résultat d'un seul bloc, mais que certains bits arrivent avant les autres, typiquement les bits de poids faible. Si le résultat était écrit dans l'accumulateur directement, il écraserait des bits de l’opérande en cours d'utilisation, ce qui fausserait le résultat. [[File:Accumulateur avec registre de sortie.png|centre|vignette|upright=2|Accumulateur avec registre de sortie]] Une autre solution utilisait un registre entre l'accumulateur et l'unité de calcul, appelé l’'''''accumulator latch'''''. Il remplace le registre en sortie de l'ALU, dans le sens où il permet d'écrire dans l'accumulateur sans effacer l'opérande, pendant que l’opération est en cours dans l'ALU. L'accumulateur est copié dans l’''accumulator latch'', avant que l'ALU démarre ses calculs. L'opérande est donc maintenue même si on commence à écrire le résultat dans l'accumulateur. Sur le 8085 d'Intel, l’''accumulator latch'' peut être initialisé avec une constante prédéfinie, ce qui permet d'implémenter certaines instructions très facilement. Par exemple, il peut être initialisé à 0, ce qui permet d'implémenter les instructions MOV et INC (incrémentation). Un MOV est équivalent à faire un OU entre le registre lu et 0. Une instruction INC initialise l'entrée de retenue de l'unité de calcul à 1, puis ajoute 0. La décrémentation est implémentée de la même manière, sauf que l’''accumulator latch'' est initialisé à -2 pour compenser l'entrée de retenue à 1. De plus, pour supporter les conversion de décimal à BCD, l’''accumulator latch'' peut être initialisé avec les constantes 0x00, 0x06, 0x60, or 0x66. L'''accumulator latch'' est relié à divers fils de commande provenant de l'unité de contrôle, qui décide quelle valeur d'initialisation utiliser en fonction de l'instruction décodée. [[File:Accumulator latch.png|centre|vignette|upright=2|Accumulator latch]] [[File:Chemin de données à un seul bus.png|vignette|Chemin de données à un seul bus]] De même, la seconde opérande, celle lue sur le bus de données, est mémorisée dans un registre en amont de l'ALU. C'était notamment très utile si le processeur utilisait une ALU plus courte que les opérandes, avec par exemple une ALU 4 bits pour un CPU 8 bits. Les anciens processeurs à accumulateur de type ''mainframe'' utilisaient des opérandes de grande taille, du genre 36 ou 48 bits, ce qui avait des conséquences sur l'unité de calcul utilisée, ainsi que sur la communication avec la mémoire. Il arrivait que de tels processeurs utilisaient des ALU sérielles, ou du moins octet-sérielles, plutôt qu'une véritable ALU 36 bits. Nous verrons aussi que c'est très utile sur les processeurs à accumulateur avec un bus interne unique, dans la suite du chapitre. ===La micro-architecture des architectures à accumulateur avec instructions LOAD/STORE=== Nous venons de voir comment est implémenté l'unité de calcul et l'accumulateur, et comment le tout est relié au bus de données. Mais cela ne permet que d'avoir un processeur à accumulateur rudimentaire, qui ne gére que des instructions arithmétiques et logiques. Il faut aussi gérer le cas des opérations LOAD/STORE et des modes d'adressages associés, mais c'est le séquenceur qui s'en occupe. Avec l'adressage absolu, les instructions LOAD et STORE ne font que connecter l'accumulateur au bus de données. L'instruction STORE nécessite de connecter l'accumulateur au bus de données, de manière à ce que le transfert des données se fasse de l'accumulateur vers le bus de données. L'instruction LOAD s'implémente de la même manière, sauf que le sens de transfert est inversé. Cependant, il existe une optimisation qui permet d'implémenter l'instruction LOAD sans ajouter de circuits. Pour cela, il suffit que l'unité de calcul gére les opérations ''pass through'', à savoir des opérations qui se contentent de recopier un opérande sur la sortie. Ici, l'idée est de recopier l'opérande provenant du bus de données. [[File:Architecture à accumulateur, microarchitecture.png|centre|vignette|upright=2|Architecture à accumulateur, microarchitecture]] Pour gérer nativement l'adressage indirect à registre, il suffit de connecter l'accumulateur au bus d'adresse. Le plus simple est d'ajouter un multiplexeur, comme illustré ci-dessous. La donnée lue est copiée dans l'accumulateur, ce qui fait qu'il vaut mieux utiliser un registre d’interfaçage, l'accumulateur n'étant pas utilisable à la fois pour le bus d'adresse et de données. [[File:Adressage indirect sur une architecture à accumulateur.png|centre|vignette|upright=2|Adressage indirect sur une architecture à accumulateur]] Pour finir, voyons comment le pointeur de pile et le ''program counter'' sont implémentés. Les architectures à accumulateur ont souvent des adresses de taille différente des données, ce qui fait qu'il vaut mieux utiliser un circuit incrémenteur dédié pour incrémenter le ''program counter'', plutôt que de l'incrémenter via l'unité de calcul. Les architectures à accumulateur ont parfois un pointeur de pile, qui gère une pile d'adresse de retour, pas une vraie pile d'appel. Aussi, le pointeur de pile est censé être incrémenté et décrémenté, pas plus. Pas d'addition ou de soustraction pour gérer des cadres de pile. Là encore, c'est la solution de l'incrémenteur séparé qui est retenue. Pour économiser des transistors, il n'y a qu'un seul incrémenteur partagé pour les deux. ==Les architectures à accumulateur à registres d'indice== Les architectures à accumulateur décrites dans la section précédente sont capables de faire de l'adressage indirect, mais n'incluent pas les modes d'adressage base + indice et absolus indicés, qui prennent une adresse et y ajoute un indice. Il s'agit des toutes premières architectures à accumulateur, comme les premiers ordinateurs IBM ou le fameux PDP-8. Mais par la suite, les processeurs à accumulateurs ont inclus un support des modes d'adressages indicés, grâce à des '''registres d'indice'''. ===Les registres d'indice=== Les registres d'indice stockent des indices de tableaux. Ils permettaient de supporter deux modes d'adressage : * Le '''mode d'adressage absolu indicé''' où une adresse fixe est additionnée à un indice variable. L'adresse fixe est intégrée dans l'instruction (adressage absolu), l'indice est dans un registre d'indice. * Le '''mode d'adressage base + indice''', où l'adresse est dans l'accumulateur et l'indice dans le registre d'indice. Les processeurs à accumulateur supportaient souvent des variantes des modes d'adressage précédents, où le registre d'indice était automatiquement incrémenté ou décrémenté à chaque utilisation. Au départ, ces processeurs n'utilisaient qu'un seul registre d'indice qui se comportait comme un second accumulateur spécialisé dans les calculs d'adresses mémoire. Le processeur supportait de nouvelles instructions qui utilisaient ce registre d'indice de façon implicite. Mais avec le temps, les processeurs finirent par incorporer plusieurs de ces registres. Les instructions de lecture ou d'écriture devaient alors préciser quel registre d'indice utiliser, en précisant un nom de registre d'indice, un numéro de registre d'indice. Il faut préciser que les registres d'indice ont une taille bien plus petite que l'accumulateur. Ils mémorisent des indices codés sur 16 bits ou moins, alors que l'accumulateur faisait typiquement 36 à 48 bits, parfois plus. La taille classique sur les anciens ''mainframes'' était de 15 bits, parfois moins. Il n'était pas rare de tomber sur des registres d'indice de 8 ou 9 bits. Leur petite taille rendait leur implémentation matérielle peu couteuse. Et c'est ce qui explique qu'ils étaient préférés à l'usage d'un second accumulateur. Un exemple est le cas du processeur Motorola 6809, un processeur à accumulateur qui contient deux registres d'indices nommés X et Y. L'accumulateur est noté D et fait 16 bits, il peut être parfois géré comme deux accumulateurs séparés A et B de 8 bits chacun. Il contenait aussi deux pointeurs de pile, l'un pour les programmes, l'autre pour le système d'exploitation, ainsi qu'un ''program counter''. Le registre de page était utilisé pour l'adressage absolu, comme vu dans le chapitre sur les modes d'adressage. [[File:6809 Internal Registers.svg|centre|vignette|upright=2|6809 Internal Registers]] Les processeurs IBM avaient autrefois plusieurs registres d'indice. Par exemple, l'IBM 704 avait trois registres d'indice de 15 bits. Leur contenu était soustrait de l'adresse absolue. Une instruction pouvait utiliser plusieurs registres d'indice pour adresser son opérande. Toute instruction utilisait trois bits pour sélectionner les registres d'indice utilisés. Fait assez original, lorsque plusieurs registres d'indice sont sélectionnés, le processeur n'additionne pas les trois registres à l'adresse de base. À la place, il fait un OU bit à bit entre les registres d'indice sélectionnés, et additionne le résultat à l'adresse. Les processeurs IBM à accumulateur ont fait ça sur toute la gamme IBM 700/7000, pour des raisons de compatibilité. Les processeurs suivants avaient 7 registres d'indices, mais conservaient les trois bits pour adresser les registres d'indices. Ils pouvaient fonctionner dans deux modes. Le premier mode est plus intuitif : les trois bits précisent un registre d'indice parmi les 7, qui est additionné avec l'adresse absolue. La valeur zéro indique qu'aucun registre d'indice n'est utilisé, ce qui explique qu'il y a 7 registres d'indice et non 8. Un second mode, compatible avec l'IBM 704, fait un OU logique entre les registres d'indice sélectionnés. Seuls les trois premiers registres d'indices peuvent être sélectionnés dans ce mode. Il y a deux instructions pour changer de mode : une pour passer en mode compatible, l'autre pour le quitter pour l'autre mode. Quelques rares processeurs à registres généraux ont utilisés des registres d'indice, en plus des registres généraux. Ce qui fait l'association que nous avons faite entre registres d'indice et architectures à accumulateur est imparfait, bien que solide sur le principe. Un exemple d'architecture de ce type sont les architectures de la série UNIVAC 1100/2200. Ils disposaient de 128 registres, qui étaient mappés en mémoire à partir de l'adresse mémoire 0, la majorité étant inaccessibles par le programmeur. Ils regroupaient 12 registres accumulateurs, 11 registres d'indice et 4 registres hybrides qui pouvaient servir soit de registre d'indice, soit de registres accumulateurs. ===La micro-architecture des architectures à accumulateur avec registres d'indice=== La présence de registres d'indice modifie grandement l'implémentation du processeur. En effet, il faut rajouter un banc de registre pour les registres d'indice. Le banc de registre est monoport, car on a besoin de lire ou d'écrire un indice à la fois. Et il faut aussi potentiellement rajouter de quoi faire les calculs d'adresse. Deux solutions sont possibles : une ALU dédiée aux calculs d'adresse, une seule ALU pour toutes les opérations. Dans le premier cas, il y a une ALU séparée associée aux registres d'indice. L'ALU et les registres d'indice sont placés en sortie du séquenceur, en-dehors du chemin de données, la sortie de l'ALU est directement connectée au bus d'adresse. L'unité de calcul d'adresse peut être utilisée pour incrémenter le ''program counter''. Un défaut de cette approche est qu'elle ne gère pas l'adresse indirect à registre. [[File:Chemin de données sans support des pointeurs, avec adressage absolu indicé.png|centre|vignette|upright=2|Chemin de données sans support des pointeurs, avec adressage absolu indicé]] Une autre option utilise un bus interne, qui interconnecte tout le chemin de données. Dans sa version la plus simple, il est relié à l'accumulateur, l'unité de calcul, le banc de registre d'indice et le bus de données. Avec cette solution, l'ALU est utilisé à la fois pour calculer les adresses et pour les instructions de calcul. En reliant le bus interne au bus d'adresse à travers un multiplexeur, on gère naturellement les adressages indirects. [[File:Architecture à accumulateur avec registres associés.png|centre|vignette|upright=2.5|Architecture à accumulateur avec registres associés]] Il faut noter que sur les architectures Von Neumann, le séquenceur est relié à ce bus interne. En effet, charger une instruction demande de passer par le bus mémoire, donc par l’intermédiaire de ce bus internet. Le ''program counter'' est envoyé sur ce bus pour lire l'instruction, puis l'instruction lue est recopiée dans le registre d'instruction. Le chargement d'une instruction est donc géré comme une lecture des plus classiques. De plus, cela permet d'incrémenter le ''program counter'' au niveau de l'unité de calcul entière. Le ''program counter'' est envoyé sur le bus interne, incrémenté par l'ALU, puis le résultat est recopié dans le ''program counter'' via le bus interne. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] ==Les processeurs bi-accumulateurs : le Motorola 6800== Le Motorola 6800 était un processeur 8 bits qui gérait des adresses de 16 bits. Il contenait deux accumulateurs nommés A et B, de 8 bits chacun. Il disposait aussi d'un registre d'indice, d'un pointeur de pile et d'un ''program counter'', tous les trois de 16 bits. Le registre d'état regroupait 6 bits, qu'on ne détaillera pas ici. [[File:MC6800 Processor Diagram.png|centre|vignette|upright=2|Interface et registres du MC6800.]] La présence des deux accumulateurs impactait surtout les instructions dyadiques. Les instructions monadiques avaient juste à préciser où se trouvait l'opérande : soit en RAM, soit dans le premier accumulateur, soit dans le second. Pour les opérations dyadiques, la gestion était totalement différente. En théorie, le premier opérande est dans un accumulateur, soit A, soit B. La seconde opérande vient soit de l'autre accumulateur, soit de la mémoire RAM. Et selon les instructions, tout variait. Pour l'addition, il y avait trois instructions. Les deux premières additionnaient un opérande provenant de la mémoire avec un accumulateur. L'instruction ADDA sélectionnait le premier accumulateur, l'instruction ADDB sélectionnait le second accumulateur. Mais une troisième instruction, l’instruction ABA, permettait d'additionner le contenu des deux accumulateurs. Pour les autres opérations, il n'était pas possible d'utiliser les deux accumulateurs en même temps. La seule possibilité était de faire une opération entre un accumulateur et un opérande venant de la mémoire. Toutes les instructions étaient en double, avec une copie par accumulateur. Par exemple, l'instruction ANDA faisait un ET entre l’accumulateur A et l'opérande mémoire, l'instruction ANDB faisait pareil avec l'accumulateur B. ==Les architectures hybrides registres-accumulateur== Il a existé quelques architectures qui étaient des hybrides entre architectures à accumulateur et architecture à registre. Elles ont servi de transition entre les deux, durant les années 80-90. Elles avaient un accumulateur unique couplé à un banc de registres généraux. Par exemple, les premiers processeurs Intel 8 bits étaient des processeurs hybrides-accumulateur. Lles CPU Intel 8 bits disposaient de 7 registres de 8 bits nommés A, B, C, D, E, F, H, L, SP. Ils correspondent respectivement à : * l'accumulateur A ; * six registres nommés B, C, D, E, H et L ; * le registre d'état F ; * le pointeur de pile SP. Sur ces processeurs, les instructions dyadiques devaient mettre leur premier opérande dans l'accumulateur, la seconde provenait soit des registres, soit de la RAM, soit d'une constante immédiate. Les opérations monadiques pouvaient lire leur opérande depuis l'accumulateur, les autres registres ou la RAM, tout était permis. Les registres d'indices disparaissaient sur ces architectures, en théorie. Les registres généraux pouvaient être utilisés comme registre d'indice ou pour stocker des opérandes, ils étaient assez versatiles pour servir de registres d'indices. La présence de registres a de nombreux avantages, comparé aux architectures à accumulateur pures. Les instructions arithmétiques sont plus rapide, lire un registre étant plus rapide qu'un accès RAM. Les performances sont donc augmentées. De plus, les instructions arithmétiques utilisant ces registres sont plus courtes : pas besoin d'encoder une adresse mémoire, un nom de registre suffit. Vu que les processeurs de l’époque avaient des instructions de taille variable, cela améliorait la densité de code. La microarchitecture de ces processeurs est très similaire à celle d'un processeur avec des registres d'indices. La seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Le banc de registre est systématiquement monoport, car il n'avait aucune raison d'être multiport. Pour les instructions dyadiques, seules à lire deux opérandes, il ne servait que pour la seconde opérande, la première était lue depuis l'accumulateur. Les processeurs hybrides registre-accumulateur se classent en deux types principaux : ceux qui ont un seul bus interne, et ceux qui en ont deux. Le premier cas est identique à celui vu précédemment pour les architectures à accumulateur avec registres d'indice, à la seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Afin de gérer l'adressage indirect à registre, le bus interne est connecté aux deux registres d’interfaçage mémoire. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] Notons que cela permet aussi d'implémenter facilement les branchements indirects, car le bus interne permet d'échanger des adresses entre ''program counter'' et banc de registre. De même, il est possible d'utiliser l'ALU pour gérer les branchements indirects., en plus de l'utiliser pour incrémenter le ''program counter''. [[File:Single bus organization.jpg|centre|vignette|upright=2|Single bus organization]] Une autre solution utilisait deux bus internes : un connecté au bus de données, un autre relié au bus d'adresse. Le bus de commande mémoire était lui commandé par le séquenceur, l'unité de contrôle. L'intermédiaire entre ces deux bus était le banc de registre, ainsi que les autres registres. Le banc de registre était connecté aux deux bus interne, avec un port de lecture relié au bus d'adresse, un port de lecture-écriture relié au bus de données. Le port de lecture était utilisé pour l'adressage indirect, l'autre l'était pour le reste. [[File:Proz1-e.png|centre|vignette|upright=2|Intérieur d'un processeur.]] L'organisation à deux bus simplifiait la gestion du ''program counter'' et le chargement des instructions. Le ''program counter'' était soit séparé du banc de registre, soit placé dans le banc de registre. Les deux solutions étaient utilisés, tout dépend du processeur. Il faut noter que si le ''program counter'' est intégré au banc de registres, alors la microarchitecture du processeur est bien plus simple. L'envoi du ''program counter'' sur le bus d'adresse utilise le port de lecture relié au bus d'adresse, qui sert aussi pour l'adressage indirect. L'économie de circuits, sans compter la simplicité d'implémentation que cela implique, explique sans doute que la technique a été utilisée sur quelques processeurs anciens. Le ''program counter'' était généralement incrémenté par l'ALU, ce qui explique qu'il soit connecté au bus interne pour les données. La connexion est aussi utile pour gérer les branchements indirects, qui copient un registre dans le ''program counter'', ainsi que les branchements relatifs (addition dans l'ALU), voire les branchements directs (l'adresse vers laquelle brancher est envoyée en entrée de l'ALU et propagée en sortie avec une opération ''pass through''). [[File:Connexion du program counter sur les bus avec PC dans le banc de registres.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC dans le banc de registres]] ===Les registres d'interruption avec un processeur hybride-accumulateur : l'exemple du Z80=== Un exemple de processeur registre-accumulateur à deux bus interne est le Z80, un processeur fortement inspiré des CPU Intel 8 bits. Il a un jeu d'instruction similaire, mais a diverses améliorations par rapport au design original. Notamment, le processeur a des registres séparés pour les interruptions. Sur le Z80, les registres généraux sont dupliqués avec 6 registres pour les interruptions et 6 registres pour les programmes autres. Leur copie pour les interruptions sont nommées B', C', D', E', H', L'. Les 12 registres sont placés dans le banc de registre, ce qui implique que le fenêtrage de registres est utilisé pour gérer la séparation entre registre d'interruption et normaux. Il faut noter que l'accumulateur et le registre d'état sont aussi dupliqués, leurs copies étant nommées A' et F'. Mais leur duplication se fait autrement que par fenêtrage de registre. En plus des registres précédents, le Z80 incorporait deux registres d'indice nommés X et Y, ainsi qu'un pointeur de pile SP et un ''program counter'' PC. Ils n'étaient pas dupliqués pour les interruptions. Les registres d'indice étaient reliés à une unité de calcul d'adresse. L'unité de calcul d'adresse prenait deux opérandes : un indice, et une adresse mémoire provenant soit du banc de registre, soit de l'accumulateur. En clair, l'unité de calcul d'adresse faisait le lien entre les deux bus internet : le bus de données interne en entrée, le bus d'adresse en sortie. À l'intérieur du processeur, tous les registres étaient regroupés dans un banc de registre unique, sauf les accumulateurs, les registres d'état et le ''program counter''. Bien que ce ne soit pas indiqué sur le schéma ci-dessous, le ''program counter'' est séparé du banc de registre, alors que le pointeur de pile est dedans. Le compteur IR est lui associé au ''program counter'', il est sortit du banc de registre. Le Z80 utilise lui aussi un incrémenteur séparé de l'ALU, qui est utilisé pour mettre à jour le ''program counter'', le pointeur de pile et un compteur de rafraichissement mémoire nommé IR sur le Z80 (pour rappel, le rafraichissement mémoire demande de balayer la mémoire d'adresse en adresse et été fait par le CPU à l'époque). De plus, il est utilisé pour les instructions INC et DEC qui incrémentent une opérande de 16 bits obtenue en combinant deux registres de 8 bits. En clair, l'incrémenteur du ''program counter'' a été réutilisé de beaucoup de manières originales. [[File:Z80 arch.svg|centre|vignette|upright=3|Microarchitecture du Z80.]] Le Z80 incorporait des instructions pour échanger le contenu des deux ensembles de registres, accumulateur inclus. Elles permettaient d'utiliser les registres d'interruption pour les programmes et réciproquement. En clair, cela doublait le nombre de registres si les interruptions n'étaient pas utilisées. * L'instruction EXX échangeait les deux fenêtres de registres généraux : les registres B, C, D, E, H et L devenaient les registres B', C', D', E', H' et L' et inversement. * L'instruction EX échangeait l'accumulateur et le registre d'état : les registres A,F devenait A',F' et inversement. Le fenêtrage de registre était modifié par l'instruction EXX, qui échangeait les deux fenêtres de registres. Pour l'implémenter, une bascule était ajouté au processeur, appelons-la la bascule INT. Elle était relié au bus d'adresse du banc de registre, dont elle mémorisait le bit de poids fort. L'instruction EXX inversait la valeur de la bascule INT. Il est aussi possible d'échanger le contenu des registres D,E et H,L avec une instruction dédiée, ce qui est là encore fait par deux bascules : une pour les registres D,E et une autre pour les registres H,L. Pour l'accumulateur et le registre d'état, le choix entre registre normal et registre d'interruption se faisait là encore par une seconde bascule appelée la bascule A. La bascule est reliée à un multiplexeur et un démultiplexeur, qui permet de choisir quel accumulateur relier à l'unité de calcul. L'instruction EX inverse le contenu de la bascule A. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=L'unité de contrôle | prevText=L'unité de contrôle | next=Les processeurs 8 bits et moins | nextText=Les processeurs 8 bits et moins }} </noinclude> 7wbxedz6dwrn6wwf6wejvybkllmwwe4 744156 744154 2025-06-05T14:01:52Z Mewtow 31375 /* Annexe : les toutes premières architectures à accumulateur : le Manchester Baby */ 744156 wikitext text/x-wiki Les architectures que nous avons vu précédemment dans ce cours disposent de registres pour les données, en plus du pointeur de pile, d'un ''program counter'', et de quelques autres. Elles sont appelées des '''architectures à registres''', terme qui trahit bien le fait qu'elles ont des registres généraux ou spécialisés pour stocker temporairement des données. Et si on leur a donné un nom, c'est parce qu'il existe des architectures qui ne sont pas dans cette catégorie. Il en existe plusieurs types, mais ce chapitre va se concentrer sur les '''architectures à accumulateur'''. [[File:Isaccumulator.png|vignette|Architecture à accumulateur.]] Les architectures à accumulateur sont centrées autour d'un registre architectural appelé l''''accumulateur'''. Il est utilisé pour toutes les opérations arithmétiques dyadiques, où il sert à la fois de source et de destination. Toutes les instructions dyadiques sont de type ''load-op'' : une opérande est lue depuis l'accumulateur, le second opérande est lu depuis la mémoire RAM, le résultat de l'instruction est automatiquement mémorisé dans l'accumulateur. Les instructions monadiques peuvent utiliser un opérande dans l'accumulateur, ou dans la mémoire RAM, les deux sont théoriquement possibles. La conséquence est que le nombre d'accès mémoire est drastiquement diminué : de 3 par instructions sur une architecture mémoire-mémoire, on passe à seulement un avec un accumulateur. Les opérations dyadiques ont besoin d'un seul accès mémoire pour lire la seconde opérande, les opérations monadique en font aussi un seul pour lire leur unique opérande. {|class="wikitable" |- ! Classe d'architecture ! Nombre d'accès mémoire par opération dyadique |- |- ! Architecture à accumulateur | Un accès mémoire par instruction, pour lire la seconde opérande |- ! Architecture à registres | Zéro si les opérandes sont dans les registres, un pour les opérations ''load-op'', LOAD et STORE. |} ==Le jeu d'instruction des architectures à accumulateur sans registres d'indice== L'accumulateur est adressé grâce au mode d'adressage implicite, de même que le résultat de l'opération. Par contre, les autres opérandes sont localisés avec d'autres modes d'adressage, et lues en mémoire RAM. Le résultat ainsi qu'un des opérandes sont adressés de façon implicite car dans l'accumulateur, seule la seconde opérande étant adressée directement. Grâce à l'accumulateur, une instruction ne fait qu'un seul accès mémoire maximum, ce qui rend le processeur très facile à implémenter. ===Les registres des anciennes architectures à accumulateur=== [[File:IBM 701console.jpg|vignette|IBM 701, console extérieure.]] Les architectures à accumulateur étaient communes dans les années 50-60. A l'époque, les ordinateurs étaient gigantesques, ils prenaient une pièce de bâtiment entière dans le pire des cas, une armoire entière dans le meilleur. Les ordinateurs de l'époque étaient surtout utilisés pour du calcul scientifique ou des tâches d’ingénierie demandant beaucoup de calcul, rarement pour de la compatibilité. Les nombres flottants n'étaient pas encore apparus. A la place, les ordinateurs de l'époque géraient des nombres entiers de grande taille, de 30 bits ou plus. En conséquence, l'accumulateur faisait facilement 30 à 60 bits. Par exemple, les ordinateurs de la Série scientifique IBM 700/7000 géraient des entiers de 36 bits, l’accumulateur faisait 38 bits : 36 bits plus deux bits pour les débordements. Au passage, de tels processeurs utilisaient l'adressage par mot, et non par byte. Historiquement, les premières architectures à accumulateur ne contenaient aucun autre registre que l'accumulateur. Ce n'est que dans les années 60 que de nombreuses architectures à accumulateur ont ajouté un second '''registre pour les multiplication/divisions'''. Un exemple est celui de l'IBM 701, qui incorporait un registre accumulateur de 38 bits et un registre multiplieur de 36 bits. Le registre mémorise le multiplieur lors d'une opération de multiplication. Il mémorise donc un opérande, pas le résultat. Il peut aussi décaler le multiplieur vers la droite/gauche, ce qui est utile pour exécuter la multiplication. C'est ce qui est fait sur l'IBM 7094. Une autre possibilité est que ce registre mémorise une partie du résultat de l'opération. Pour rappel, le résultat d'une multiplication/division est codé sur deux fois de bits que ses opérandes. Par exemple, multipliez deux opérandes de 30 bits, vous obtiendrez un résultat de 60 bits. Les 30 bits de poids faible du résultat vont dans l'accumulateur, les 30 bits de poids fort vont dans ce second registre. Les architectures à accumulateur parfois un '''registre pour le pointeur de pile''', utilisé pour gérer les fonctions/procédures. Les architectures à accumulateurs supportaient une pile d'adresse de retour, souvent une pile d'appel. Mais pour cela, il fallait mémoriser le pointeur de pile dans le processeur, ce qui demandait un registre dédié. ===L'adressage indirect avec l'accumulateur=== Les instructions LOAD et STORE existent bel et bien sur les architectures à accumulateur, mais n'ont pas les mêmes modes d'adressages. L'instruction LOAD copie une donnée de la RAM vers l'accumulateur, l'instruction STORE copie l'accumulateur dans une adresse. Les deux instructions n'ont pas besoin d'adresser l'accumulateur, qui est adressé de manière implicite, juste de préciser l'adresse à lire/écrire. Les architectures à accumulateur supportaient souvent le mode d'adressage indirect mémoire. Un exemple est celui des ordinateurs Data General Nova, qui sont des architectures à accumulateur et qui supportaient ce mode d'adressage. Les deux instructions LOAD et STORE existaient en deux versions, distinguées par un bit d'indirection. Si ce bit est à 0 dans l'opcode, alors l'instruction utilise le mode d'adressage absolu normal : l'adresse intégrée dans l'instruction est celle de la donnée. Mais s'il est à 1, alors l'adresse intégrée dans l'instruction est celle du pointeur. Cependant, la présence de l'accumulateur permettait d'utiliser l'adressage indirect à registre, pour gérer les pointeurs. Pour rappel, avec le mode d'adressage indirect à registre, l'adresse à lire/écrire est dans un registre. Ici, l'adresse à lire/écrire est prise dans l'accumulateur, seul registre disponible pour. L'adressage indirect est plus simple à implémenter pour l'instruction LOAD, car elle prend un seul opérande : l'adresse à lire. L'adresse à lire est placée dans l'accumulateur, la donnée lue est elle aussi chargée dans l'accumulateur. Pour l'instruction STORE, il faut fournir deux opérandes, l'adresse et la donnée à écrire, ce qui peut poser problème. Mais au pire, il est toujours possible d'utiliser l'adressage absolu ou indirect mémoire : l'adresse est dans l'instruction, la donnée à écrire dans l'accumulateur. ===L'encodage des instructions=== Sur une architecture à accumulateur l'encodage d'une instruction dyadique est assez simple, vu que l'accumulateur est adressé implicitement. La seconde opérande est localisée soit par une adresse mémoire (adressage absolu), soit est une constante (adressage immédiat). L'adresse mémoire est généralement assez longue, plus que l'opcode. {|class="wikitable" |+ Encodage d'une instruction dyadique |- ! rowspan="2" | Opcode | Adresse mémoire (adressage absolu) |- | Constante (adressage immédiat) |} L'encodage d'une instruction monadique est similaire. Si l'opérande est lue depuis la mémoire RAM, alors l'instruction est encodée comme une instruction dyadique. Il en est de même pour les instructions qui copient une constante dans l'accumulateur. Par contre, si l'opérande est dans l'accumulateur, alors il y a juste besoin d'encoder l'opcode. La majorité des instructions a besoin de préciser une adresse, rares sont celles qui s'en passent. Au vu de cet encodage, les architectures à accumulateur sont qualifiées d''''architectures à une adresse''' par abus de langage. Il est intéressant de contraster leur encodage avec les architectures à registres. Les architectures à registre doivent encoder deux opérandes en plus de l'opcode, avec éventuellement où enregistrer le résultat sur les architectures 3-adresses. Par contre, les opérandes sont généralement des noms de registre, ce qui prend moins de place qu'une adresse mémoire. A la rigueur, les instructions avec une constante immédiate prennent un peu plus de place, car elles doivent encoder un nom de registre en plus de la constante et de l'opcode. Les instructions ''load-op'' des processeurs CISC sont un peu dans le même cas, sauf qu'il faut remplacer la constante par une adresse, qui a généralement la même taille. Les instructions sont donc en moyenne plus courte sur les processeurs à registre, du fait de la présence de registres. ===Annexe : les toutes premières architectures à accumulateur : le Manchester Baby=== [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] Les architectures à accumulateurs sont apparues dès les débuts de l'informatique. Le tout premier ordinateur à programme enregistré en mémoire, le ''Manchester Baby'', était une architecture à accumulateur. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 adresses, fabriquée avec des tubes Williams (abordés dans une annexe à la fin du cours). Chaque adresse mémorisait 32 bits, qui pouvaient encoder soit un nombre, soit une instruction. Le programme devait tenir dans la RAM, avec une instruction par adresse maximum, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 servait à indiquer où se trouvent la seconde opérande en RAM, les 16 restants sont inutilisés. Le processeur avait un registre accumulateur de 32 bits, un ''program counter'' et un registre d'instruction. Il intégrait un additionneur dédié au ''program counter'', mais l'ALU n'avait pas d'additionneur. En conséquence, il ne gérait pas l'addition. A la place, il gérait la soustraction. Il pouvait cependant émuler l'addition à partir d'une soustraction. La soustraction était utilisée pour calculer le complément d'une opérande, et soustraire le complément revient à additionner. L'ALU était une ALU sérielle, à savoir qu'elle faisait les soustractions bit par bit. Le processeur supportait 7 instructions au total : la soustraction, des instructions de branchement et d'accès mémoire, rien d'autre. {|class="wikitable" |- ! SUB | Soustrait l'opérande mémoire de l'accumulateur. |- ! CMP | Skippe l'instruction suivante si l'accumulateur a une valeur négative. |- ! JMP | Branchement indirect mémoire. : * L'adresse de destination est lue depuis la mémoire. * L'adresse lue est intégrée dans l'instruction via adressage absolu. |- ! JRP | Branchement relatif indirect. * Lit une opérande depuis la mémoire, l'adresse est intégrée dans l'instruction via adressage absolu. * Additionne l'opérande lue au ''program counter''. |- ! LDN | Instruction LOAD |- ! STO | Instruction STORE |- ! STOP | Éteint l'ordinateur. |} Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. C'était là encore une architecture à accumulateur, sauf qu'elle intégrait aussi des registres d'indice. Et surtout : son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. [[File:MM1Schematic French.svg|centre|vignette|upright=2.5|Architecture de la Manchester Mark 1.]] ==La micro-architecture des architectures à accumulateur sans registres d'indice== L'organisation interne d'une architecture à accumulateur est très différente de celle des processeurs à registre. Elle est plus ou moins la même pour tous ces processeurs, le point important étant que le chemin de données se résume à une ALU, un registre accumulateur et le bus de données. L'ALU est reliée au registre accumulateur, ainsi qu'au bus de données pour lire la seconde opérande, comme illustré ci-dessous. [[File:Accumulator.png|centre|vignette|upright=2|Accumulateur.]] ===L'unité de calcul et l'accumulateur=== Pour simplifier l'implémentation, le résultat est mémorisé dans un registre en sortie de l'unité de calcul. La raison est qu'on ne veut pas altérer l'accumulateur tant que le résultat final n'est pas totalement calculé. Rappelons que l'ALU ne fournit pas un résultat d'un seul bloc, mais que certains bits arrivent avant les autres, typiquement les bits de poids faible. Si le résultat était écrit dans l'accumulateur directement, il écraserait des bits de l’opérande en cours d'utilisation, ce qui fausserait le résultat. [[File:Accumulateur avec registre de sortie.png|centre|vignette|upright=2|Accumulateur avec registre de sortie]] Une autre solution utilisait un registre entre l'accumulateur et l'unité de calcul, appelé l’'''''accumulator latch'''''. Il remplace le registre en sortie de l'ALU, dans le sens où il permet d'écrire dans l'accumulateur sans effacer l'opérande, pendant que l’opération est en cours dans l'ALU. L'accumulateur est copié dans l’''accumulator latch'', avant que l'ALU démarre ses calculs. L'opérande est donc maintenue même si on commence à écrire le résultat dans l'accumulateur. Sur le 8085 d'Intel, l’''accumulator latch'' peut être initialisé avec une constante prédéfinie, ce qui permet d'implémenter certaines instructions très facilement. Par exemple, il peut être initialisé à 0, ce qui permet d'implémenter les instructions MOV et INC (incrémentation). Un MOV est équivalent à faire un OU entre le registre lu et 0. Une instruction INC initialise l'entrée de retenue de l'unité de calcul à 1, puis ajoute 0. La décrémentation est implémentée de la même manière, sauf que l’''accumulator latch'' est initialisé à -2 pour compenser l'entrée de retenue à 1. De plus, pour supporter les conversion de décimal à BCD, l’''accumulator latch'' peut être initialisé avec les constantes 0x00, 0x06, 0x60, or 0x66. L'''accumulator latch'' est relié à divers fils de commande provenant de l'unité de contrôle, qui décide quelle valeur d'initialisation utiliser en fonction de l'instruction décodée. [[File:Accumulator latch.png|centre|vignette|upright=2|Accumulator latch]] [[File:Chemin de données à un seul bus.png|vignette|Chemin de données à un seul bus]] De même, la seconde opérande, celle lue sur le bus de données, est mémorisée dans un registre en amont de l'ALU. C'était notamment très utile si le processeur utilisait une ALU plus courte que les opérandes, avec par exemple une ALU 4 bits pour un CPU 8 bits. Les anciens processeurs à accumulateur de type ''mainframe'' utilisaient des opérandes de grande taille, du genre 36 ou 48 bits, ce qui avait des conséquences sur l'unité de calcul utilisée, ainsi que sur la communication avec la mémoire. Il arrivait que de tels processeurs utilisaient des ALU sérielles, ou du moins octet-sérielles, plutôt qu'une véritable ALU 36 bits. Nous verrons aussi que c'est très utile sur les processeurs à accumulateur avec un bus interne unique, dans la suite du chapitre. ===La micro-architecture des architectures à accumulateur avec instructions LOAD/STORE=== Nous venons de voir comment est implémenté l'unité de calcul et l'accumulateur, et comment le tout est relié au bus de données. Mais cela ne permet que d'avoir un processeur à accumulateur rudimentaire, qui ne gére que des instructions arithmétiques et logiques. Il faut aussi gérer le cas des opérations LOAD/STORE et des modes d'adressages associés, mais c'est le séquenceur qui s'en occupe. Avec l'adressage absolu, les instructions LOAD et STORE ne font que connecter l'accumulateur au bus de données. L'instruction STORE nécessite de connecter l'accumulateur au bus de données, de manière à ce que le transfert des données se fasse de l'accumulateur vers le bus de données. L'instruction LOAD s'implémente de la même manière, sauf que le sens de transfert est inversé. Cependant, il existe une optimisation qui permet d'implémenter l'instruction LOAD sans ajouter de circuits. Pour cela, il suffit que l'unité de calcul gére les opérations ''pass through'', à savoir des opérations qui se contentent de recopier un opérande sur la sortie. Ici, l'idée est de recopier l'opérande provenant du bus de données. [[File:Architecture à accumulateur, microarchitecture.png|centre|vignette|upright=2|Architecture à accumulateur, microarchitecture]] Pour gérer nativement l'adressage indirect à registre, il suffit de connecter l'accumulateur au bus d'adresse. Le plus simple est d'ajouter un multiplexeur, comme illustré ci-dessous. La donnée lue est copiée dans l'accumulateur, ce qui fait qu'il vaut mieux utiliser un registre d’interfaçage, l'accumulateur n'étant pas utilisable à la fois pour le bus d'adresse et de données. [[File:Adressage indirect sur une architecture à accumulateur.png|centre|vignette|upright=2|Adressage indirect sur une architecture à accumulateur]] Pour finir, voyons comment le pointeur de pile et le ''program counter'' sont implémentés. Les architectures à accumulateur ont souvent des adresses de taille différente des données, ce qui fait qu'il vaut mieux utiliser un circuit incrémenteur dédié pour incrémenter le ''program counter'', plutôt que de l'incrémenter via l'unité de calcul. Les architectures à accumulateur ont parfois un pointeur de pile, qui gère une pile d'adresse de retour, pas une vraie pile d'appel. Aussi, le pointeur de pile est censé être incrémenté et décrémenté, pas plus. Pas d'addition ou de soustraction pour gérer des cadres de pile. Là encore, c'est la solution de l'incrémenteur séparé qui est retenue. Pour économiser des transistors, il n'y a qu'un seul incrémenteur partagé pour les deux. ==Les architectures à accumulateur à registres d'indice== Les architectures à accumulateur décrites dans la section précédente sont capables de faire de l'adressage indirect, mais n'incluent pas les modes d'adressage base + indice et absolus indicés, qui prennent une adresse et y ajoute un indice. Il s'agit des toutes premières architectures à accumulateur, comme les premiers ordinateurs IBM ou le fameux PDP-8. Mais par la suite, les processeurs à accumulateurs ont inclus un support des modes d'adressages indicés, grâce à des '''registres d'indice'''. ===Les registres d'indice=== Les registres d'indice stockent des indices de tableaux. Ils permettaient de supporter deux modes d'adressage : * Le '''mode d'adressage absolu indicé''' où une adresse fixe est additionnée à un indice variable. L'adresse fixe est intégrée dans l'instruction (adressage absolu), l'indice est dans un registre d'indice. * Le '''mode d'adressage base + indice''', où l'adresse est dans l'accumulateur et l'indice dans le registre d'indice. Les processeurs à accumulateur supportaient souvent des variantes des modes d'adressage précédents, où le registre d'indice était automatiquement incrémenté ou décrémenté à chaque utilisation. Au départ, ces processeurs n'utilisaient qu'un seul registre d'indice qui se comportait comme un second accumulateur spécialisé dans les calculs d'adresses mémoire. Le processeur supportait de nouvelles instructions qui utilisaient ce registre d'indice de façon implicite. Mais avec le temps, les processeurs finirent par incorporer plusieurs de ces registres. Les instructions de lecture ou d'écriture devaient alors préciser quel registre d'indice utiliser, en précisant un nom de registre d'indice, un numéro de registre d'indice. Il faut préciser que les registres d'indice ont une taille bien plus petite que l'accumulateur. Ils mémorisent des indices codés sur 16 bits ou moins, alors que l'accumulateur faisait typiquement 36 à 48 bits, parfois plus. La taille classique sur les anciens ''mainframes'' était de 15 bits, parfois moins. Il n'était pas rare de tomber sur des registres d'indice de 8 ou 9 bits. Leur petite taille rendait leur implémentation matérielle peu couteuse. Et c'est ce qui explique qu'ils étaient préférés à l'usage d'un second accumulateur. Un exemple est le cas du processeur Motorola 6809, un processeur à accumulateur qui contient deux registres d'indices nommés X et Y. L'accumulateur est noté D et fait 16 bits, il peut être parfois géré comme deux accumulateurs séparés A et B de 8 bits chacun. Il contenait aussi deux pointeurs de pile, l'un pour les programmes, l'autre pour le système d'exploitation, ainsi qu'un ''program counter''. Le registre de page était utilisé pour l'adressage absolu, comme vu dans le chapitre sur les modes d'adressage. [[File:6809 Internal Registers.svg|centre|vignette|upright=2|6809 Internal Registers]] Les processeurs IBM avaient autrefois plusieurs registres d'indice. Par exemple, l'IBM 704 avait trois registres d'indice de 15 bits. Leur contenu était soustrait de l'adresse absolue. Une instruction pouvait utiliser plusieurs registres d'indice pour adresser son opérande. Toute instruction utilisait trois bits pour sélectionner les registres d'indice utilisés. Fait assez original, lorsque plusieurs registres d'indice sont sélectionnés, le processeur n'additionne pas les trois registres à l'adresse de base. À la place, il fait un OU bit à bit entre les registres d'indice sélectionnés, et additionne le résultat à l'adresse. Les processeurs IBM à accumulateur ont fait ça sur toute la gamme IBM 700/7000, pour des raisons de compatibilité. Les processeurs suivants avaient 7 registres d'indices, mais conservaient les trois bits pour adresser les registres d'indices. Ils pouvaient fonctionner dans deux modes. Le premier mode est plus intuitif : les trois bits précisent un registre d'indice parmi les 7, qui est additionné avec l'adresse absolue. La valeur zéro indique qu'aucun registre d'indice n'est utilisé, ce qui explique qu'il y a 7 registres d'indice et non 8. Un second mode, compatible avec l'IBM 704, fait un OU logique entre les registres d'indice sélectionnés. Seuls les trois premiers registres d'indices peuvent être sélectionnés dans ce mode. Il y a deux instructions pour changer de mode : une pour passer en mode compatible, l'autre pour le quitter pour l'autre mode. Quelques rares processeurs à registres généraux ont utilisés des registres d'indice, en plus des registres généraux. Ce qui fait l'association que nous avons faite entre registres d'indice et architectures à accumulateur est imparfait, bien que solide sur le principe. Un exemple d'architecture de ce type sont les architectures de la série UNIVAC 1100/2200. Ils disposaient de 128 registres, qui étaient mappés en mémoire à partir de l'adresse mémoire 0, la majorité étant inaccessibles par le programmeur. Ils regroupaient 12 registres accumulateurs, 11 registres d'indice et 4 registres hybrides qui pouvaient servir soit de registre d'indice, soit de registres accumulateurs. ===La micro-architecture des architectures à accumulateur avec registres d'indice=== La présence de registres d'indice modifie grandement l'implémentation du processeur. En effet, il faut rajouter un banc de registre pour les registres d'indice. Le banc de registre est monoport, car on a besoin de lire ou d'écrire un indice à la fois. Et il faut aussi potentiellement rajouter de quoi faire les calculs d'adresse. Deux solutions sont possibles : une ALU dédiée aux calculs d'adresse, une seule ALU pour toutes les opérations. Dans le premier cas, il y a une ALU séparée associée aux registres d'indice. L'ALU et les registres d'indice sont placés en sortie du séquenceur, en-dehors du chemin de données, la sortie de l'ALU est directement connectée au bus d'adresse. L'unité de calcul d'adresse peut être utilisée pour incrémenter le ''program counter''. Un défaut de cette approche est qu'elle ne gère pas l'adresse indirect à registre. [[File:Chemin de données sans support des pointeurs, avec adressage absolu indicé.png|centre|vignette|upright=2|Chemin de données sans support des pointeurs, avec adressage absolu indicé]] Une autre option utilise un bus interne, qui interconnecte tout le chemin de données. Dans sa version la plus simple, il est relié à l'accumulateur, l'unité de calcul, le banc de registre d'indice et le bus de données. Avec cette solution, l'ALU est utilisé à la fois pour calculer les adresses et pour les instructions de calcul. En reliant le bus interne au bus d'adresse à travers un multiplexeur, on gère naturellement les adressages indirects. [[File:Architecture à accumulateur avec registres associés.png|centre|vignette|upright=2.5|Architecture à accumulateur avec registres associés]] Il faut noter que sur les architectures Von Neumann, le séquenceur est relié à ce bus interne. En effet, charger une instruction demande de passer par le bus mémoire, donc par l’intermédiaire de ce bus internet. Le ''program counter'' est envoyé sur ce bus pour lire l'instruction, puis l'instruction lue est recopiée dans le registre d'instruction. Le chargement d'une instruction est donc géré comme une lecture des plus classiques. De plus, cela permet d'incrémenter le ''program counter'' au niveau de l'unité de calcul entière. Le ''program counter'' est envoyé sur le bus interne, incrémenté par l'ALU, puis le résultat est recopié dans le ''program counter'' via le bus interne. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] ==Les processeurs bi-accumulateurs : le Motorola 6800== Le Motorola 6800 était un processeur 8 bits qui gérait des adresses de 16 bits. Il contenait deux accumulateurs nommés A et B, de 8 bits chacun. Il disposait aussi d'un registre d'indice, d'un pointeur de pile et d'un ''program counter'', tous les trois de 16 bits. Le registre d'état regroupait 6 bits, qu'on ne détaillera pas ici. [[File:MC6800 Processor Diagram.png|centre|vignette|upright=2|Interface et registres du MC6800.]] La présence des deux accumulateurs impactait surtout les instructions dyadiques. Les instructions monadiques avaient juste à préciser où se trouvait l'opérande : soit en RAM, soit dans le premier accumulateur, soit dans le second. Pour les opérations dyadiques, la gestion était totalement différente. En théorie, le premier opérande est dans un accumulateur, soit A, soit B. La seconde opérande vient soit de l'autre accumulateur, soit de la mémoire RAM. Et selon les instructions, tout variait. Pour l'addition, il y avait trois instructions. Les deux premières additionnaient un opérande provenant de la mémoire avec un accumulateur. L'instruction ADDA sélectionnait le premier accumulateur, l'instruction ADDB sélectionnait le second accumulateur. Mais une troisième instruction, l’instruction ABA, permettait d'additionner le contenu des deux accumulateurs. Pour les autres opérations, il n'était pas possible d'utiliser les deux accumulateurs en même temps. La seule possibilité était de faire une opération entre un accumulateur et un opérande venant de la mémoire. Toutes les instructions étaient en double, avec une copie par accumulateur. Par exemple, l'instruction ANDA faisait un ET entre l’accumulateur A et l'opérande mémoire, l'instruction ANDB faisait pareil avec l'accumulateur B. ==Les architectures hybrides registres-accumulateur== Il a existé quelques architectures qui étaient des hybrides entre architectures à accumulateur et architecture à registre. Elles ont servi de transition entre les deux, durant les années 80-90. Elles avaient un accumulateur unique couplé à un banc de registres généraux. Par exemple, les premiers processeurs Intel 8 bits étaient des processeurs hybrides-accumulateur. Lles CPU Intel 8 bits disposaient de 7 registres de 8 bits nommés A, B, C, D, E, F, H, L, SP. Ils correspondent respectivement à : * l'accumulateur A ; * six registres nommés B, C, D, E, H et L ; * le registre d'état F ; * le pointeur de pile SP. Sur ces processeurs, les instructions dyadiques devaient mettre leur premier opérande dans l'accumulateur, la seconde provenait soit des registres, soit de la RAM, soit d'une constante immédiate. Les opérations monadiques pouvaient lire leur opérande depuis l'accumulateur, les autres registres ou la RAM, tout était permis. Les registres d'indices disparaissaient sur ces architectures, en théorie. Les registres généraux pouvaient être utilisés comme registre d'indice ou pour stocker des opérandes, ils étaient assez versatiles pour servir de registres d'indices. La présence de registres a de nombreux avantages, comparé aux architectures à accumulateur pures. Les instructions arithmétiques sont plus rapide, lire un registre étant plus rapide qu'un accès RAM. Les performances sont donc augmentées. De plus, les instructions arithmétiques utilisant ces registres sont plus courtes : pas besoin d'encoder une adresse mémoire, un nom de registre suffit. Vu que les processeurs de l’époque avaient des instructions de taille variable, cela améliorait la densité de code. La microarchitecture de ces processeurs est très similaire à celle d'un processeur avec des registres d'indices. La seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Le banc de registre est systématiquement monoport, car il n'avait aucune raison d'être multiport. Pour les instructions dyadiques, seules à lire deux opérandes, il ne servait que pour la seconde opérande, la première était lue depuis l'accumulateur. Les processeurs hybrides registre-accumulateur se classent en deux types principaux : ceux qui ont un seul bus interne, et ceux qui en ont deux. Le premier cas est identique à celui vu précédemment pour les architectures à accumulateur avec registres d'indice, à la seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Afin de gérer l'adressage indirect à registre, le bus interne est connecté aux deux registres d’interfaçage mémoire. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] Notons que cela permet aussi d'implémenter facilement les branchements indirects, car le bus interne permet d'échanger des adresses entre ''program counter'' et banc de registre. De même, il est possible d'utiliser l'ALU pour gérer les branchements indirects., en plus de l'utiliser pour incrémenter le ''program counter''. [[File:Single bus organization.jpg|centre|vignette|upright=2|Single bus organization]] Une autre solution utilisait deux bus internes : un connecté au bus de données, un autre relié au bus d'adresse. Le bus de commande mémoire était lui commandé par le séquenceur, l'unité de contrôle. L'intermédiaire entre ces deux bus était le banc de registre, ainsi que les autres registres. Le banc de registre était connecté aux deux bus interne, avec un port de lecture relié au bus d'adresse, un port de lecture-écriture relié au bus de données. Le port de lecture était utilisé pour l'adressage indirect, l'autre l'était pour le reste. [[File:Proz1-e.png|centre|vignette|upright=2|Intérieur d'un processeur.]] L'organisation à deux bus simplifiait la gestion du ''program counter'' et le chargement des instructions. Le ''program counter'' était soit séparé du banc de registre, soit placé dans le banc de registre. Les deux solutions étaient utilisés, tout dépend du processeur. Il faut noter que si le ''program counter'' est intégré au banc de registres, alors la microarchitecture du processeur est bien plus simple. L'envoi du ''program counter'' sur le bus d'adresse utilise le port de lecture relié au bus d'adresse, qui sert aussi pour l'adressage indirect. L'économie de circuits, sans compter la simplicité d'implémentation que cela implique, explique sans doute que la technique a été utilisée sur quelques processeurs anciens. Le ''program counter'' était généralement incrémenté par l'ALU, ce qui explique qu'il soit connecté au bus interne pour les données. La connexion est aussi utile pour gérer les branchements indirects, qui copient un registre dans le ''program counter'', ainsi que les branchements relatifs (addition dans l'ALU), voire les branchements directs (l'adresse vers laquelle brancher est envoyée en entrée de l'ALU et propagée en sortie avec une opération ''pass through''). [[File:Connexion du program counter sur les bus avec PC dans le banc de registres.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC dans le banc de registres]] ===Les registres d'interruption avec un processeur hybride-accumulateur : l'exemple du Z80=== Un exemple de processeur registre-accumulateur à deux bus interne est le Z80, un processeur fortement inspiré des CPU Intel 8 bits. Il a un jeu d'instruction similaire, mais a diverses améliorations par rapport au design original. Notamment, le processeur a des registres séparés pour les interruptions. Sur le Z80, les registres généraux sont dupliqués avec 6 registres pour les interruptions et 6 registres pour les programmes autres. Leur copie pour les interruptions sont nommées B', C', D', E', H', L'. Les 12 registres sont placés dans le banc de registre, ce qui implique que le fenêtrage de registres est utilisé pour gérer la séparation entre registre d'interruption et normaux. Il faut noter que l'accumulateur et le registre d'état sont aussi dupliqués, leurs copies étant nommées A' et F'. Mais leur duplication se fait autrement que par fenêtrage de registre. En plus des registres précédents, le Z80 incorporait deux registres d'indice nommés X et Y, ainsi qu'un pointeur de pile SP et un ''program counter'' PC. Ils n'étaient pas dupliqués pour les interruptions. Les registres d'indice étaient reliés à une unité de calcul d'adresse. L'unité de calcul d'adresse prenait deux opérandes : un indice, et une adresse mémoire provenant soit du banc de registre, soit de l'accumulateur. En clair, l'unité de calcul d'adresse faisait le lien entre les deux bus internet : le bus de données interne en entrée, le bus d'adresse en sortie. À l'intérieur du processeur, tous les registres étaient regroupés dans un banc de registre unique, sauf les accumulateurs, les registres d'état et le ''program counter''. Bien que ce ne soit pas indiqué sur le schéma ci-dessous, le ''program counter'' est séparé du banc de registre, alors que le pointeur de pile est dedans. Le compteur IR est lui associé au ''program counter'', il est sortit du banc de registre. Le Z80 utilise lui aussi un incrémenteur séparé de l'ALU, qui est utilisé pour mettre à jour le ''program counter'', le pointeur de pile et un compteur de rafraichissement mémoire nommé IR sur le Z80 (pour rappel, le rafraichissement mémoire demande de balayer la mémoire d'adresse en adresse et été fait par le CPU à l'époque). De plus, il est utilisé pour les instructions INC et DEC qui incrémentent une opérande de 16 bits obtenue en combinant deux registres de 8 bits. En clair, l'incrémenteur du ''program counter'' a été réutilisé de beaucoup de manières originales. [[File:Z80 arch.svg|centre|vignette|upright=3|Microarchitecture du Z80.]] Le Z80 incorporait des instructions pour échanger le contenu des deux ensembles de registres, accumulateur inclus. Elles permettaient d'utiliser les registres d'interruption pour les programmes et réciproquement. En clair, cela doublait le nombre de registres si les interruptions n'étaient pas utilisées. * L'instruction EXX échangeait les deux fenêtres de registres généraux : les registres B, C, D, E, H et L devenaient les registres B', C', D', E', H' et L' et inversement. * L'instruction EX échangeait l'accumulateur et le registre d'état : les registres A,F devenait A',F' et inversement. Le fenêtrage de registre était modifié par l'instruction EXX, qui échangeait les deux fenêtres de registres. Pour l'implémenter, une bascule était ajouté au processeur, appelons-la la bascule INT. Elle était relié au bus d'adresse du banc de registre, dont elle mémorisait le bit de poids fort. L'instruction EXX inversait la valeur de la bascule INT. Il est aussi possible d'échanger le contenu des registres D,E et H,L avec une instruction dédiée, ce qui est là encore fait par deux bascules : une pour les registres D,E et une autre pour les registres H,L. Pour l'accumulateur et le registre d'état, le choix entre registre normal et registre d'interruption se faisait là encore par une seconde bascule appelée la bascule A. La bascule est reliée à un multiplexeur et un démultiplexeur, qui permet de choisir quel accumulateur relier à l'unité de calcul. L'instruction EX inverse le contenu de la bascule A. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=L'unité de contrôle | prevText=L'unité de contrôle | next=Les processeurs 8 bits et moins | nextText=Les processeurs 8 bits et moins }} </noinclude> tf5ze72wifqow5zk51jetejbuit4hki 744157 744156 2025-06-05T14:05:51Z Mewtow 31375 /* Annexe : les toutes premières architectures à accumulateur : le Manchester Baby */ 744157 wikitext text/x-wiki Les architectures que nous avons vu précédemment dans ce cours disposent de registres pour les données, en plus du pointeur de pile, d'un ''program counter'', et de quelques autres. Elles sont appelées des '''architectures à registres''', terme qui trahit bien le fait qu'elles ont des registres généraux ou spécialisés pour stocker temporairement des données. Et si on leur a donné un nom, c'est parce qu'il existe des architectures qui ne sont pas dans cette catégorie. Il en existe plusieurs types, mais ce chapitre va se concentrer sur les '''architectures à accumulateur'''. [[File:Isaccumulator.png|vignette|Architecture à accumulateur.]] Les architectures à accumulateur sont centrées autour d'un registre architectural appelé l''''accumulateur'''. Il est utilisé pour toutes les opérations arithmétiques dyadiques, où il sert à la fois de source et de destination. Toutes les instructions dyadiques sont de type ''load-op'' : une opérande est lue depuis l'accumulateur, le second opérande est lu depuis la mémoire RAM, le résultat de l'instruction est automatiquement mémorisé dans l'accumulateur. Les instructions monadiques peuvent utiliser un opérande dans l'accumulateur, ou dans la mémoire RAM, les deux sont théoriquement possibles. La conséquence est que le nombre d'accès mémoire est drastiquement diminué : de 3 par instructions sur une architecture mémoire-mémoire, on passe à seulement un avec un accumulateur. Les opérations dyadiques ont besoin d'un seul accès mémoire pour lire la seconde opérande, les opérations monadique en font aussi un seul pour lire leur unique opérande. {|class="wikitable" |- ! Classe d'architecture ! Nombre d'accès mémoire par opération dyadique |- |- ! Architecture à accumulateur | Un accès mémoire par instruction, pour lire la seconde opérande |- ! Architecture à registres | Zéro si les opérandes sont dans les registres, un pour les opérations ''load-op'', LOAD et STORE. |} ==Le jeu d'instruction des architectures à accumulateur sans registres d'indice== L'accumulateur est adressé grâce au mode d'adressage implicite, de même que le résultat de l'opération. Par contre, les autres opérandes sont localisés avec d'autres modes d'adressage, et lues en mémoire RAM. Le résultat ainsi qu'un des opérandes sont adressés de façon implicite car dans l'accumulateur, seule la seconde opérande étant adressée directement. Grâce à l'accumulateur, une instruction ne fait qu'un seul accès mémoire maximum, ce qui rend le processeur très facile à implémenter. ===Les registres des anciennes architectures à accumulateur=== [[File:IBM 701console.jpg|vignette|IBM 701, console extérieure.]] Les architectures à accumulateur étaient communes dans les années 50-60. A l'époque, les ordinateurs étaient gigantesques, ils prenaient une pièce de bâtiment entière dans le pire des cas, une armoire entière dans le meilleur. Les ordinateurs de l'époque étaient surtout utilisés pour du calcul scientifique ou des tâches d’ingénierie demandant beaucoup de calcul, rarement pour de la compatibilité. Les nombres flottants n'étaient pas encore apparus. A la place, les ordinateurs de l'époque géraient des nombres entiers de grande taille, de 30 bits ou plus. En conséquence, l'accumulateur faisait facilement 30 à 60 bits. Par exemple, les ordinateurs de la Série scientifique IBM 700/7000 géraient des entiers de 36 bits, l’accumulateur faisait 38 bits : 36 bits plus deux bits pour les débordements. Au passage, de tels processeurs utilisaient l'adressage par mot, et non par byte. Historiquement, les premières architectures à accumulateur ne contenaient aucun autre registre que l'accumulateur. Ce n'est que dans les années 60 que de nombreuses architectures à accumulateur ont ajouté un second '''registre pour les multiplication/divisions'''. Un exemple est celui de l'IBM 701, qui incorporait un registre accumulateur de 38 bits et un registre multiplieur de 36 bits. Le registre mémorise le multiplieur lors d'une opération de multiplication. Il mémorise donc un opérande, pas le résultat. Il peut aussi décaler le multiplieur vers la droite/gauche, ce qui est utile pour exécuter la multiplication. C'est ce qui est fait sur l'IBM 7094. Une autre possibilité est que ce registre mémorise une partie du résultat de l'opération. Pour rappel, le résultat d'une multiplication/division est codé sur deux fois de bits que ses opérandes. Par exemple, multipliez deux opérandes de 30 bits, vous obtiendrez un résultat de 60 bits. Les 30 bits de poids faible du résultat vont dans l'accumulateur, les 30 bits de poids fort vont dans ce second registre. Les architectures à accumulateur parfois un '''registre pour le pointeur de pile''', utilisé pour gérer les fonctions/procédures. Les architectures à accumulateurs supportaient une pile d'adresse de retour, souvent une pile d'appel. Mais pour cela, il fallait mémoriser le pointeur de pile dans le processeur, ce qui demandait un registre dédié. ===L'adressage indirect avec l'accumulateur=== Les instructions LOAD et STORE existent bel et bien sur les architectures à accumulateur, mais n'ont pas les mêmes modes d'adressages. L'instruction LOAD copie une donnée de la RAM vers l'accumulateur, l'instruction STORE copie l'accumulateur dans une adresse. Les deux instructions n'ont pas besoin d'adresser l'accumulateur, qui est adressé de manière implicite, juste de préciser l'adresse à lire/écrire. Les architectures à accumulateur supportaient souvent le mode d'adressage indirect mémoire. Un exemple est celui des ordinateurs Data General Nova, qui sont des architectures à accumulateur et qui supportaient ce mode d'adressage. Les deux instructions LOAD et STORE existaient en deux versions, distinguées par un bit d'indirection. Si ce bit est à 0 dans l'opcode, alors l'instruction utilise le mode d'adressage absolu normal : l'adresse intégrée dans l'instruction est celle de la donnée. Mais s'il est à 1, alors l'adresse intégrée dans l'instruction est celle du pointeur. Cependant, la présence de l'accumulateur permettait d'utiliser l'adressage indirect à registre, pour gérer les pointeurs. Pour rappel, avec le mode d'adressage indirect à registre, l'adresse à lire/écrire est dans un registre. Ici, l'adresse à lire/écrire est prise dans l'accumulateur, seul registre disponible pour. L'adressage indirect est plus simple à implémenter pour l'instruction LOAD, car elle prend un seul opérande : l'adresse à lire. L'adresse à lire est placée dans l'accumulateur, la donnée lue est elle aussi chargée dans l'accumulateur. Pour l'instruction STORE, il faut fournir deux opérandes, l'adresse et la donnée à écrire, ce qui peut poser problème. Mais au pire, il est toujours possible d'utiliser l'adressage absolu ou indirect mémoire : l'adresse est dans l'instruction, la donnée à écrire dans l'accumulateur. ===L'encodage des instructions=== Sur une architecture à accumulateur l'encodage d'une instruction dyadique est assez simple, vu que l'accumulateur est adressé implicitement. La seconde opérande est localisée soit par une adresse mémoire (adressage absolu), soit est une constante (adressage immédiat). L'adresse mémoire est généralement assez longue, plus que l'opcode. {|class="wikitable" |+ Encodage d'une instruction dyadique |- ! rowspan="2" | Opcode | Adresse mémoire (adressage absolu) |- | Constante (adressage immédiat) |} L'encodage d'une instruction monadique est similaire. Si l'opérande est lue depuis la mémoire RAM, alors l'instruction est encodée comme une instruction dyadique. Il en est de même pour les instructions qui copient une constante dans l'accumulateur. Par contre, si l'opérande est dans l'accumulateur, alors il y a juste besoin d'encoder l'opcode. La majorité des instructions a besoin de préciser une adresse, rares sont celles qui s'en passent. Au vu de cet encodage, les architectures à accumulateur sont qualifiées d''''architectures à une adresse''' par abus de langage. Il est intéressant de contraster leur encodage avec les architectures à registres. Les architectures à registre doivent encoder deux opérandes en plus de l'opcode, avec éventuellement où enregistrer le résultat sur les architectures 3-adresses. Par contre, les opérandes sont généralement des noms de registre, ce qui prend moins de place qu'une adresse mémoire. A la rigueur, les instructions avec une constante immédiate prennent un peu plus de place, car elles doivent encoder un nom de registre en plus de la constante et de l'opcode. Les instructions ''load-op'' des processeurs CISC sont un peu dans le même cas, sauf qu'il faut remplacer la constante par une adresse, qui a généralement la même taille. Les instructions sont donc en moyenne plus courte sur les processeurs à registre, du fait de la présence de registres. ===Annexe : les toutes premières architectures à accumulateur : le Manchester Baby=== [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] Les architectures à accumulateurs sont apparues dès les débuts de l'informatique. Le tout premier ordinateur à programme enregistré en mémoire, le ''Manchester Baby'', était une architecture à accumulateur. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 adresses, fabriquée avec des tubes Williams (abordés dans une annexe à la fin du cours). Chaque adresse mémorisait 32 bits, qui pouvaient encoder soit un nombre, soit une instruction. Le programme devait tenir dans la RAM, avec une instruction par adresse maximum, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 servait à indiquer où se trouvent la seconde opérande en RAM, les 16 restants sont inutilisés. Le processeur avait un registre accumulateur de 32 bits, un ''program counter'' et un registre d'instruction. Il intégrait un additionneur dédié au ''program counter'', mais l'ALU n'avait pas d'additionneur. En conséquence, il ne gérait pas l'addition. A la place, il gérait la soustraction. Il pouvait cependant émuler l'addition à partir d'une soustraction. La soustraction était utilisée pour calculer le complément d'une opérande, et soustraire le complément revient à additionner. L'ALU était une ALU sérielle, à savoir qu'elle faisait les soustractions bit par bit. Le processeur supportait 7 instructions au total : la soustraction, des instructions de branchement et d'accès mémoire, rien d'autre. Les instructions de branchement utilisaient des modes d'adressage très particuliers, qu'on ne retrouve pas sur les ordinateurs modernes. Les branchements inconditionnels utilisaient une forme d'adressage mémoire indirect, pas les adressages usuels pour les branchements. Il n'y avait pas de branchements conditionnels, mais une ''SKIP instruction''. {|class="wikitable" |- ! SUB | Soustrait l'opérande mémoire de l'accumulateur. |- ! CMP | Skippe l'instruction suivante si l'accumulateur a une valeur négative. |- ! JMP | Branchement indirect mémoire. : * L'adresse de destination est lue depuis la mémoire. * L'adresse lue est intégrée dans l'instruction via adressage absolu. |- ! JRP | Branchement relatif indirect. * Lit une opérande depuis la mémoire, l'adresse est intégrée dans l'instruction via adressage absolu. * Additionne l'opérande lue au ''program counter''. |- ! LDN | Instruction LOAD. La donnée lue est inversée lors de la lecture, l'accumulateur contient le complément à deux de la donnée lue après la lecture. |- ! STO | Instruction STORE |- ! STOP | Éteint l'ordinateur. |} Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. C'était là encore une architecture à accumulateur, sauf qu'elle intégrait aussi des registres d'indice. Et surtout : son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. [[File:MM1Schematic French.svg|centre|vignette|upright=2.5|Architecture de la Manchester Mark 1.]] ==La micro-architecture des architectures à accumulateur sans registres d'indice== L'organisation interne d'une architecture à accumulateur est très différente de celle des processeurs à registre. Elle est plus ou moins la même pour tous ces processeurs, le point important étant que le chemin de données se résume à une ALU, un registre accumulateur et le bus de données. L'ALU est reliée au registre accumulateur, ainsi qu'au bus de données pour lire la seconde opérande, comme illustré ci-dessous. [[File:Accumulator.png|centre|vignette|upright=2|Accumulateur.]] ===L'unité de calcul et l'accumulateur=== Pour simplifier l'implémentation, le résultat est mémorisé dans un registre en sortie de l'unité de calcul. La raison est qu'on ne veut pas altérer l'accumulateur tant que le résultat final n'est pas totalement calculé. Rappelons que l'ALU ne fournit pas un résultat d'un seul bloc, mais que certains bits arrivent avant les autres, typiquement les bits de poids faible. Si le résultat était écrit dans l'accumulateur directement, il écraserait des bits de l’opérande en cours d'utilisation, ce qui fausserait le résultat. [[File:Accumulateur avec registre de sortie.png|centre|vignette|upright=2|Accumulateur avec registre de sortie]] Une autre solution utilisait un registre entre l'accumulateur et l'unité de calcul, appelé l’'''''accumulator latch'''''. Il remplace le registre en sortie de l'ALU, dans le sens où il permet d'écrire dans l'accumulateur sans effacer l'opérande, pendant que l’opération est en cours dans l'ALU. L'accumulateur est copié dans l’''accumulator latch'', avant que l'ALU démarre ses calculs. L'opérande est donc maintenue même si on commence à écrire le résultat dans l'accumulateur. Sur le 8085 d'Intel, l’''accumulator latch'' peut être initialisé avec une constante prédéfinie, ce qui permet d'implémenter certaines instructions très facilement. Par exemple, il peut être initialisé à 0, ce qui permet d'implémenter les instructions MOV et INC (incrémentation). Un MOV est équivalent à faire un OU entre le registre lu et 0. Une instruction INC initialise l'entrée de retenue de l'unité de calcul à 1, puis ajoute 0. La décrémentation est implémentée de la même manière, sauf que l’''accumulator latch'' est initialisé à -2 pour compenser l'entrée de retenue à 1. De plus, pour supporter les conversion de décimal à BCD, l’''accumulator latch'' peut être initialisé avec les constantes 0x00, 0x06, 0x60, or 0x66. L'''accumulator latch'' est relié à divers fils de commande provenant de l'unité de contrôle, qui décide quelle valeur d'initialisation utiliser en fonction de l'instruction décodée. [[File:Accumulator latch.png|centre|vignette|upright=2|Accumulator latch]] [[File:Chemin de données à un seul bus.png|vignette|Chemin de données à un seul bus]] De même, la seconde opérande, celle lue sur le bus de données, est mémorisée dans un registre en amont de l'ALU. C'était notamment très utile si le processeur utilisait une ALU plus courte que les opérandes, avec par exemple une ALU 4 bits pour un CPU 8 bits. Les anciens processeurs à accumulateur de type ''mainframe'' utilisaient des opérandes de grande taille, du genre 36 ou 48 bits, ce qui avait des conséquences sur l'unité de calcul utilisée, ainsi que sur la communication avec la mémoire. Il arrivait que de tels processeurs utilisaient des ALU sérielles, ou du moins octet-sérielles, plutôt qu'une véritable ALU 36 bits. Nous verrons aussi que c'est très utile sur les processeurs à accumulateur avec un bus interne unique, dans la suite du chapitre. ===La micro-architecture des architectures à accumulateur avec instructions LOAD/STORE=== Nous venons de voir comment est implémenté l'unité de calcul et l'accumulateur, et comment le tout est relié au bus de données. Mais cela ne permet que d'avoir un processeur à accumulateur rudimentaire, qui ne gére que des instructions arithmétiques et logiques. Il faut aussi gérer le cas des opérations LOAD/STORE et des modes d'adressages associés, mais c'est le séquenceur qui s'en occupe. Avec l'adressage absolu, les instructions LOAD et STORE ne font que connecter l'accumulateur au bus de données. L'instruction STORE nécessite de connecter l'accumulateur au bus de données, de manière à ce que le transfert des données se fasse de l'accumulateur vers le bus de données. L'instruction LOAD s'implémente de la même manière, sauf que le sens de transfert est inversé. Cependant, il existe une optimisation qui permet d'implémenter l'instruction LOAD sans ajouter de circuits. Pour cela, il suffit que l'unité de calcul gére les opérations ''pass through'', à savoir des opérations qui se contentent de recopier un opérande sur la sortie. Ici, l'idée est de recopier l'opérande provenant du bus de données. [[File:Architecture à accumulateur, microarchitecture.png|centre|vignette|upright=2|Architecture à accumulateur, microarchitecture]] Pour gérer nativement l'adressage indirect à registre, il suffit de connecter l'accumulateur au bus d'adresse. Le plus simple est d'ajouter un multiplexeur, comme illustré ci-dessous. La donnée lue est copiée dans l'accumulateur, ce qui fait qu'il vaut mieux utiliser un registre d’interfaçage, l'accumulateur n'étant pas utilisable à la fois pour le bus d'adresse et de données. [[File:Adressage indirect sur une architecture à accumulateur.png|centre|vignette|upright=2|Adressage indirect sur une architecture à accumulateur]] Pour finir, voyons comment le pointeur de pile et le ''program counter'' sont implémentés. Les architectures à accumulateur ont souvent des adresses de taille différente des données, ce qui fait qu'il vaut mieux utiliser un circuit incrémenteur dédié pour incrémenter le ''program counter'', plutôt que de l'incrémenter via l'unité de calcul. Les architectures à accumulateur ont parfois un pointeur de pile, qui gère une pile d'adresse de retour, pas une vraie pile d'appel. Aussi, le pointeur de pile est censé être incrémenté et décrémenté, pas plus. Pas d'addition ou de soustraction pour gérer des cadres de pile. Là encore, c'est la solution de l'incrémenteur séparé qui est retenue. Pour économiser des transistors, il n'y a qu'un seul incrémenteur partagé pour les deux. ==Les architectures à accumulateur à registres d'indice== Les architectures à accumulateur décrites dans la section précédente sont capables de faire de l'adressage indirect, mais n'incluent pas les modes d'adressage base + indice et absolus indicés, qui prennent une adresse et y ajoute un indice. Il s'agit des toutes premières architectures à accumulateur, comme les premiers ordinateurs IBM ou le fameux PDP-8. Mais par la suite, les processeurs à accumulateurs ont inclus un support des modes d'adressages indicés, grâce à des '''registres d'indice'''. ===Les registres d'indice=== Les registres d'indice stockent des indices de tableaux. Ils permettaient de supporter deux modes d'adressage : * Le '''mode d'adressage absolu indicé''' où une adresse fixe est additionnée à un indice variable. L'adresse fixe est intégrée dans l'instruction (adressage absolu), l'indice est dans un registre d'indice. * Le '''mode d'adressage base + indice''', où l'adresse est dans l'accumulateur et l'indice dans le registre d'indice. Les processeurs à accumulateur supportaient souvent des variantes des modes d'adressage précédents, où le registre d'indice était automatiquement incrémenté ou décrémenté à chaque utilisation. Au départ, ces processeurs n'utilisaient qu'un seul registre d'indice qui se comportait comme un second accumulateur spécialisé dans les calculs d'adresses mémoire. Le processeur supportait de nouvelles instructions qui utilisaient ce registre d'indice de façon implicite. Mais avec le temps, les processeurs finirent par incorporer plusieurs de ces registres. Les instructions de lecture ou d'écriture devaient alors préciser quel registre d'indice utiliser, en précisant un nom de registre d'indice, un numéro de registre d'indice. Il faut préciser que les registres d'indice ont une taille bien plus petite que l'accumulateur. Ils mémorisent des indices codés sur 16 bits ou moins, alors que l'accumulateur faisait typiquement 36 à 48 bits, parfois plus. La taille classique sur les anciens ''mainframes'' était de 15 bits, parfois moins. Il n'était pas rare de tomber sur des registres d'indice de 8 ou 9 bits. Leur petite taille rendait leur implémentation matérielle peu couteuse. Et c'est ce qui explique qu'ils étaient préférés à l'usage d'un second accumulateur. Un exemple est le cas du processeur Motorola 6809, un processeur à accumulateur qui contient deux registres d'indices nommés X et Y. L'accumulateur est noté D et fait 16 bits, il peut être parfois géré comme deux accumulateurs séparés A et B de 8 bits chacun. Il contenait aussi deux pointeurs de pile, l'un pour les programmes, l'autre pour le système d'exploitation, ainsi qu'un ''program counter''. Le registre de page était utilisé pour l'adressage absolu, comme vu dans le chapitre sur les modes d'adressage. [[File:6809 Internal Registers.svg|centre|vignette|upright=2|6809 Internal Registers]] Les processeurs IBM avaient autrefois plusieurs registres d'indice. Par exemple, l'IBM 704 avait trois registres d'indice de 15 bits. Leur contenu était soustrait de l'adresse absolue. Une instruction pouvait utiliser plusieurs registres d'indice pour adresser son opérande. Toute instruction utilisait trois bits pour sélectionner les registres d'indice utilisés. Fait assez original, lorsque plusieurs registres d'indice sont sélectionnés, le processeur n'additionne pas les trois registres à l'adresse de base. À la place, il fait un OU bit à bit entre les registres d'indice sélectionnés, et additionne le résultat à l'adresse. Les processeurs IBM à accumulateur ont fait ça sur toute la gamme IBM 700/7000, pour des raisons de compatibilité. Les processeurs suivants avaient 7 registres d'indices, mais conservaient les trois bits pour adresser les registres d'indices. Ils pouvaient fonctionner dans deux modes. Le premier mode est plus intuitif : les trois bits précisent un registre d'indice parmi les 7, qui est additionné avec l'adresse absolue. La valeur zéro indique qu'aucun registre d'indice n'est utilisé, ce qui explique qu'il y a 7 registres d'indice et non 8. Un second mode, compatible avec l'IBM 704, fait un OU logique entre les registres d'indice sélectionnés. Seuls les trois premiers registres d'indices peuvent être sélectionnés dans ce mode. Il y a deux instructions pour changer de mode : une pour passer en mode compatible, l'autre pour le quitter pour l'autre mode. Quelques rares processeurs à registres généraux ont utilisés des registres d'indice, en plus des registres généraux. Ce qui fait l'association que nous avons faite entre registres d'indice et architectures à accumulateur est imparfait, bien que solide sur le principe. Un exemple d'architecture de ce type sont les architectures de la série UNIVAC 1100/2200. Ils disposaient de 128 registres, qui étaient mappés en mémoire à partir de l'adresse mémoire 0, la majorité étant inaccessibles par le programmeur. Ils regroupaient 12 registres accumulateurs, 11 registres d'indice et 4 registres hybrides qui pouvaient servir soit de registre d'indice, soit de registres accumulateurs. ===La micro-architecture des architectures à accumulateur avec registres d'indice=== La présence de registres d'indice modifie grandement l'implémentation du processeur. En effet, il faut rajouter un banc de registre pour les registres d'indice. Le banc de registre est monoport, car on a besoin de lire ou d'écrire un indice à la fois. Et il faut aussi potentiellement rajouter de quoi faire les calculs d'adresse. Deux solutions sont possibles : une ALU dédiée aux calculs d'adresse, une seule ALU pour toutes les opérations. Dans le premier cas, il y a une ALU séparée associée aux registres d'indice. L'ALU et les registres d'indice sont placés en sortie du séquenceur, en-dehors du chemin de données, la sortie de l'ALU est directement connectée au bus d'adresse. L'unité de calcul d'adresse peut être utilisée pour incrémenter le ''program counter''. Un défaut de cette approche est qu'elle ne gère pas l'adresse indirect à registre. [[File:Chemin de données sans support des pointeurs, avec adressage absolu indicé.png|centre|vignette|upright=2|Chemin de données sans support des pointeurs, avec adressage absolu indicé]] Une autre option utilise un bus interne, qui interconnecte tout le chemin de données. Dans sa version la plus simple, il est relié à l'accumulateur, l'unité de calcul, le banc de registre d'indice et le bus de données. Avec cette solution, l'ALU est utilisé à la fois pour calculer les adresses et pour les instructions de calcul. En reliant le bus interne au bus d'adresse à travers un multiplexeur, on gère naturellement les adressages indirects. [[File:Architecture à accumulateur avec registres associés.png|centre|vignette|upright=2.5|Architecture à accumulateur avec registres associés]] Il faut noter que sur les architectures Von Neumann, le séquenceur est relié à ce bus interne. En effet, charger une instruction demande de passer par le bus mémoire, donc par l’intermédiaire de ce bus internet. Le ''program counter'' est envoyé sur ce bus pour lire l'instruction, puis l'instruction lue est recopiée dans le registre d'instruction. Le chargement d'une instruction est donc géré comme une lecture des plus classiques. De plus, cela permet d'incrémenter le ''program counter'' au niveau de l'unité de calcul entière. Le ''program counter'' est envoyé sur le bus interne, incrémenté par l'ALU, puis le résultat est recopié dans le ''program counter'' via le bus interne. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] ==Les processeurs bi-accumulateurs : le Motorola 6800== Le Motorola 6800 était un processeur 8 bits qui gérait des adresses de 16 bits. Il contenait deux accumulateurs nommés A et B, de 8 bits chacun. Il disposait aussi d'un registre d'indice, d'un pointeur de pile et d'un ''program counter'', tous les trois de 16 bits. Le registre d'état regroupait 6 bits, qu'on ne détaillera pas ici. [[File:MC6800 Processor Diagram.png|centre|vignette|upright=2|Interface et registres du MC6800.]] La présence des deux accumulateurs impactait surtout les instructions dyadiques. Les instructions monadiques avaient juste à préciser où se trouvait l'opérande : soit en RAM, soit dans le premier accumulateur, soit dans le second. Pour les opérations dyadiques, la gestion était totalement différente. En théorie, le premier opérande est dans un accumulateur, soit A, soit B. La seconde opérande vient soit de l'autre accumulateur, soit de la mémoire RAM. Et selon les instructions, tout variait. Pour l'addition, il y avait trois instructions. Les deux premières additionnaient un opérande provenant de la mémoire avec un accumulateur. L'instruction ADDA sélectionnait le premier accumulateur, l'instruction ADDB sélectionnait le second accumulateur. Mais une troisième instruction, l’instruction ABA, permettait d'additionner le contenu des deux accumulateurs. Pour les autres opérations, il n'était pas possible d'utiliser les deux accumulateurs en même temps. La seule possibilité était de faire une opération entre un accumulateur et un opérande venant de la mémoire. Toutes les instructions étaient en double, avec une copie par accumulateur. Par exemple, l'instruction ANDA faisait un ET entre l’accumulateur A et l'opérande mémoire, l'instruction ANDB faisait pareil avec l'accumulateur B. ==Les architectures hybrides registres-accumulateur== Il a existé quelques architectures qui étaient des hybrides entre architectures à accumulateur et architecture à registre. Elles ont servi de transition entre les deux, durant les années 80-90. Elles avaient un accumulateur unique couplé à un banc de registres généraux. Par exemple, les premiers processeurs Intel 8 bits étaient des processeurs hybrides-accumulateur. Lles CPU Intel 8 bits disposaient de 7 registres de 8 bits nommés A, B, C, D, E, F, H, L, SP. Ils correspondent respectivement à : * l'accumulateur A ; * six registres nommés B, C, D, E, H et L ; * le registre d'état F ; * le pointeur de pile SP. Sur ces processeurs, les instructions dyadiques devaient mettre leur premier opérande dans l'accumulateur, la seconde provenait soit des registres, soit de la RAM, soit d'une constante immédiate. Les opérations monadiques pouvaient lire leur opérande depuis l'accumulateur, les autres registres ou la RAM, tout était permis. Les registres d'indices disparaissaient sur ces architectures, en théorie. Les registres généraux pouvaient être utilisés comme registre d'indice ou pour stocker des opérandes, ils étaient assez versatiles pour servir de registres d'indices. La présence de registres a de nombreux avantages, comparé aux architectures à accumulateur pures. Les instructions arithmétiques sont plus rapide, lire un registre étant plus rapide qu'un accès RAM. Les performances sont donc augmentées. De plus, les instructions arithmétiques utilisant ces registres sont plus courtes : pas besoin d'encoder une adresse mémoire, un nom de registre suffit. Vu que les processeurs de l’époque avaient des instructions de taille variable, cela améliorait la densité de code. La microarchitecture de ces processeurs est très similaire à celle d'un processeur avec des registres d'indices. La seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Le banc de registre est systématiquement monoport, car il n'avait aucune raison d'être multiport. Pour les instructions dyadiques, seules à lire deux opérandes, il ne servait que pour la seconde opérande, la première était lue depuis l'accumulateur. Les processeurs hybrides registre-accumulateur se classent en deux types principaux : ceux qui ont un seul bus interne, et ceux qui en ont deux. Le premier cas est identique à celui vu précédemment pour les architectures à accumulateur avec registres d'indice, à la seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Afin de gérer l'adressage indirect à registre, le bus interne est connecté aux deux registres d’interfaçage mémoire. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] Notons que cela permet aussi d'implémenter facilement les branchements indirects, car le bus interne permet d'échanger des adresses entre ''program counter'' et banc de registre. De même, il est possible d'utiliser l'ALU pour gérer les branchements indirects., en plus de l'utiliser pour incrémenter le ''program counter''. [[File:Single bus organization.jpg|centre|vignette|upright=2|Single bus organization]] Une autre solution utilisait deux bus internes : un connecté au bus de données, un autre relié au bus d'adresse. Le bus de commande mémoire était lui commandé par le séquenceur, l'unité de contrôle. L'intermédiaire entre ces deux bus était le banc de registre, ainsi que les autres registres. Le banc de registre était connecté aux deux bus interne, avec un port de lecture relié au bus d'adresse, un port de lecture-écriture relié au bus de données. Le port de lecture était utilisé pour l'adressage indirect, l'autre l'était pour le reste. [[File:Proz1-e.png|centre|vignette|upright=2|Intérieur d'un processeur.]] L'organisation à deux bus simplifiait la gestion du ''program counter'' et le chargement des instructions. Le ''program counter'' était soit séparé du banc de registre, soit placé dans le banc de registre. Les deux solutions étaient utilisés, tout dépend du processeur. Il faut noter que si le ''program counter'' est intégré au banc de registres, alors la microarchitecture du processeur est bien plus simple. L'envoi du ''program counter'' sur le bus d'adresse utilise le port de lecture relié au bus d'adresse, qui sert aussi pour l'adressage indirect. L'économie de circuits, sans compter la simplicité d'implémentation que cela implique, explique sans doute que la technique a été utilisée sur quelques processeurs anciens. Le ''program counter'' était généralement incrémenté par l'ALU, ce qui explique qu'il soit connecté au bus interne pour les données. La connexion est aussi utile pour gérer les branchements indirects, qui copient un registre dans le ''program counter'', ainsi que les branchements relatifs (addition dans l'ALU), voire les branchements directs (l'adresse vers laquelle brancher est envoyée en entrée de l'ALU et propagée en sortie avec une opération ''pass through''). [[File:Connexion du program counter sur les bus avec PC dans le banc de registres.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC dans le banc de registres]] ===Les registres d'interruption avec un processeur hybride-accumulateur : l'exemple du Z80=== Un exemple de processeur registre-accumulateur à deux bus interne est le Z80, un processeur fortement inspiré des CPU Intel 8 bits. Il a un jeu d'instruction similaire, mais a diverses améliorations par rapport au design original. Notamment, le processeur a des registres séparés pour les interruptions. Sur le Z80, les registres généraux sont dupliqués avec 6 registres pour les interruptions et 6 registres pour les programmes autres. Leur copie pour les interruptions sont nommées B', C', D', E', H', L'. Les 12 registres sont placés dans le banc de registre, ce qui implique que le fenêtrage de registres est utilisé pour gérer la séparation entre registre d'interruption et normaux. Il faut noter que l'accumulateur et le registre d'état sont aussi dupliqués, leurs copies étant nommées A' et F'. Mais leur duplication se fait autrement que par fenêtrage de registre. En plus des registres précédents, le Z80 incorporait deux registres d'indice nommés X et Y, ainsi qu'un pointeur de pile SP et un ''program counter'' PC. Ils n'étaient pas dupliqués pour les interruptions. Les registres d'indice étaient reliés à une unité de calcul d'adresse. L'unité de calcul d'adresse prenait deux opérandes : un indice, et une adresse mémoire provenant soit du banc de registre, soit de l'accumulateur. En clair, l'unité de calcul d'adresse faisait le lien entre les deux bus internet : le bus de données interne en entrée, le bus d'adresse en sortie. À l'intérieur du processeur, tous les registres étaient regroupés dans un banc de registre unique, sauf les accumulateurs, les registres d'état et le ''program counter''. Bien que ce ne soit pas indiqué sur le schéma ci-dessous, le ''program counter'' est séparé du banc de registre, alors que le pointeur de pile est dedans. Le compteur IR est lui associé au ''program counter'', il est sortit du banc de registre. Le Z80 utilise lui aussi un incrémenteur séparé de l'ALU, qui est utilisé pour mettre à jour le ''program counter'', le pointeur de pile et un compteur de rafraichissement mémoire nommé IR sur le Z80 (pour rappel, le rafraichissement mémoire demande de balayer la mémoire d'adresse en adresse et été fait par le CPU à l'époque). De plus, il est utilisé pour les instructions INC et DEC qui incrémentent une opérande de 16 bits obtenue en combinant deux registres de 8 bits. En clair, l'incrémenteur du ''program counter'' a été réutilisé de beaucoup de manières originales. [[File:Z80 arch.svg|centre|vignette|upright=3|Microarchitecture du Z80.]] Le Z80 incorporait des instructions pour échanger le contenu des deux ensembles de registres, accumulateur inclus. Elles permettaient d'utiliser les registres d'interruption pour les programmes et réciproquement. En clair, cela doublait le nombre de registres si les interruptions n'étaient pas utilisées. * L'instruction EXX échangeait les deux fenêtres de registres généraux : les registres B, C, D, E, H et L devenaient les registres B', C', D', E', H' et L' et inversement. * L'instruction EX échangeait l'accumulateur et le registre d'état : les registres A,F devenait A',F' et inversement. Le fenêtrage de registre était modifié par l'instruction EXX, qui échangeait les deux fenêtres de registres. Pour l'implémenter, une bascule était ajouté au processeur, appelons-la la bascule INT. Elle était relié au bus d'adresse du banc de registre, dont elle mémorisait le bit de poids fort. L'instruction EXX inversait la valeur de la bascule INT. Il est aussi possible d'échanger le contenu des registres D,E et H,L avec une instruction dédiée, ce qui est là encore fait par deux bascules : une pour les registres D,E et une autre pour les registres H,L. Pour l'accumulateur et le registre d'état, le choix entre registre normal et registre d'interruption se faisait là encore par une seconde bascule appelée la bascule A. La bascule est reliée à un multiplexeur et un démultiplexeur, qui permet de choisir quel accumulateur relier à l'unité de calcul. L'instruction EX inverse le contenu de la bascule A. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=L'unité de contrôle | prevText=L'unité de contrôle | next=Les processeurs 8 bits et moins | nextText=Les processeurs 8 bits et moins }} </noinclude> b6ivzncgomrrb2j863hrkb2mudtok76 744158 744157 2025-06-05T14:11:58Z Mewtow 31375 /* Annexe : les toutes premières architectures à accumulateur : le Manchester Baby */ 744158 wikitext text/x-wiki Les architectures que nous avons vu précédemment dans ce cours disposent de registres pour les données, en plus du pointeur de pile, d'un ''program counter'', et de quelques autres. Elles sont appelées des '''architectures à registres''', terme qui trahit bien le fait qu'elles ont des registres généraux ou spécialisés pour stocker temporairement des données. Et si on leur a donné un nom, c'est parce qu'il existe des architectures qui ne sont pas dans cette catégorie. Il en existe plusieurs types, mais ce chapitre va se concentrer sur les '''architectures à accumulateur'''. [[File:Isaccumulator.png|vignette|Architecture à accumulateur.]] Les architectures à accumulateur sont centrées autour d'un registre architectural appelé l''''accumulateur'''. Il est utilisé pour toutes les opérations arithmétiques dyadiques, où il sert à la fois de source et de destination. Toutes les instructions dyadiques sont de type ''load-op'' : une opérande est lue depuis l'accumulateur, le second opérande est lu depuis la mémoire RAM, le résultat de l'instruction est automatiquement mémorisé dans l'accumulateur. Les instructions monadiques peuvent utiliser un opérande dans l'accumulateur, ou dans la mémoire RAM, les deux sont théoriquement possibles. La conséquence est que le nombre d'accès mémoire est drastiquement diminué : de 3 par instructions sur une architecture mémoire-mémoire, on passe à seulement un avec un accumulateur. Les opérations dyadiques ont besoin d'un seul accès mémoire pour lire la seconde opérande, les opérations monadique en font aussi un seul pour lire leur unique opérande. {|class="wikitable" |- ! Classe d'architecture ! Nombre d'accès mémoire par opération dyadique |- |- ! Architecture à accumulateur | Un accès mémoire par instruction, pour lire la seconde opérande |- ! Architecture à registres | Zéro si les opérandes sont dans les registres, un pour les opérations ''load-op'', LOAD et STORE. |} ==Le jeu d'instruction des architectures à accumulateur sans registres d'indice== L'accumulateur est adressé grâce au mode d'adressage implicite, de même que le résultat de l'opération. Par contre, les autres opérandes sont localisés avec d'autres modes d'adressage, et lues en mémoire RAM. Le résultat ainsi qu'un des opérandes sont adressés de façon implicite car dans l'accumulateur, seule la seconde opérande étant adressée directement. Grâce à l'accumulateur, une instruction ne fait qu'un seul accès mémoire maximum, ce qui rend le processeur très facile à implémenter. ===Les registres des anciennes architectures à accumulateur=== [[File:IBM 701console.jpg|vignette|IBM 701, console extérieure.]] Les architectures à accumulateur étaient communes dans les années 50-60. A l'époque, les ordinateurs étaient gigantesques, ils prenaient une pièce de bâtiment entière dans le pire des cas, une armoire entière dans le meilleur. Les ordinateurs de l'époque étaient surtout utilisés pour du calcul scientifique ou des tâches d’ingénierie demandant beaucoup de calcul, rarement pour de la compatibilité. Les nombres flottants n'étaient pas encore apparus. A la place, les ordinateurs de l'époque géraient des nombres entiers de grande taille, de 30 bits ou plus. En conséquence, l'accumulateur faisait facilement 30 à 60 bits. Par exemple, les ordinateurs de la Série scientifique IBM 700/7000 géraient des entiers de 36 bits, l’accumulateur faisait 38 bits : 36 bits plus deux bits pour les débordements. Au passage, de tels processeurs utilisaient l'adressage par mot, et non par byte. Historiquement, les premières architectures à accumulateur ne contenaient aucun autre registre que l'accumulateur. Ce n'est que dans les années 60 que de nombreuses architectures à accumulateur ont ajouté un second '''registre pour les multiplication/divisions'''. Un exemple est celui de l'IBM 701, qui incorporait un registre accumulateur de 38 bits et un registre multiplieur de 36 bits. Le registre mémorise le multiplieur lors d'une opération de multiplication. Il mémorise donc un opérande, pas le résultat. Il peut aussi décaler le multiplieur vers la droite/gauche, ce qui est utile pour exécuter la multiplication. C'est ce qui est fait sur l'IBM 7094. Une autre possibilité est que ce registre mémorise une partie du résultat de l'opération. Pour rappel, le résultat d'une multiplication/division est codé sur deux fois de bits que ses opérandes. Par exemple, multipliez deux opérandes de 30 bits, vous obtiendrez un résultat de 60 bits. Les 30 bits de poids faible du résultat vont dans l'accumulateur, les 30 bits de poids fort vont dans ce second registre. Les architectures à accumulateur parfois un '''registre pour le pointeur de pile''', utilisé pour gérer les fonctions/procédures. Les architectures à accumulateurs supportaient une pile d'adresse de retour, souvent une pile d'appel. Mais pour cela, il fallait mémoriser le pointeur de pile dans le processeur, ce qui demandait un registre dédié. ===L'adressage indirect avec l'accumulateur=== Les instructions LOAD et STORE existent bel et bien sur les architectures à accumulateur, mais n'ont pas les mêmes modes d'adressages. L'instruction LOAD copie une donnée de la RAM vers l'accumulateur, l'instruction STORE copie l'accumulateur dans une adresse. Les deux instructions n'ont pas besoin d'adresser l'accumulateur, qui est adressé de manière implicite, juste de préciser l'adresse à lire/écrire. Les architectures à accumulateur supportaient souvent le mode d'adressage indirect mémoire. Un exemple est celui des ordinateurs Data General Nova, qui sont des architectures à accumulateur et qui supportaient ce mode d'adressage. Les deux instructions LOAD et STORE existaient en deux versions, distinguées par un bit d'indirection. Si ce bit est à 0 dans l'opcode, alors l'instruction utilise le mode d'adressage absolu normal : l'adresse intégrée dans l'instruction est celle de la donnée. Mais s'il est à 1, alors l'adresse intégrée dans l'instruction est celle du pointeur. Cependant, la présence de l'accumulateur permettait d'utiliser l'adressage indirect à registre, pour gérer les pointeurs. Pour rappel, avec le mode d'adressage indirect à registre, l'adresse à lire/écrire est dans un registre. Ici, l'adresse à lire/écrire est prise dans l'accumulateur, seul registre disponible pour. L'adressage indirect est plus simple à implémenter pour l'instruction LOAD, car elle prend un seul opérande : l'adresse à lire. L'adresse à lire est placée dans l'accumulateur, la donnée lue est elle aussi chargée dans l'accumulateur. Pour l'instruction STORE, il faut fournir deux opérandes, l'adresse et la donnée à écrire, ce qui peut poser problème. Mais au pire, il est toujours possible d'utiliser l'adressage absolu ou indirect mémoire : l'adresse est dans l'instruction, la donnée à écrire dans l'accumulateur. ===L'encodage des instructions=== Sur une architecture à accumulateur l'encodage d'une instruction dyadique est assez simple, vu que l'accumulateur est adressé implicitement. La seconde opérande est localisée soit par une adresse mémoire (adressage absolu), soit est une constante (adressage immédiat). L'adresse mémoire est généralement assez longue, plus que l'opcode. {|class="wikitable" |+ Encodage d'une instruction dyadique |- ! rowspan="2" | Opcode | Adresse mémoire (adressage absolu) |- | Constante (adressage immédiat) |} L'encodage d'une instruction monadique est similaire. Si l'opérande est lue depuis la mémoire RAM, alors l'instruction est encodée comme une instruction dyadique. Il en est de même pour les instructions qui copient une constante dans l'accumulateur. Par contre, si l'opérande est dans l'accumulateur, alors il y a juste besoin d'encoder l'opcode. La majorité des instructions a besoin de préciser une adresse, rares sont celles qui s'en passent. Au vu de cet encodage, les architectures à accumulateur sont qualifiées d''''architectures à une adresse''' par abus de langage. Il est intéressant de contraster leur encodage avec les architectures à registres. Les architectures à registre doivent encoder deux opérandes en plus de l'opcode, avec éventuellement où enregistrer le résultat sur les architectures 3-adresses. Par contre, les opérandes sont généralement des noms de registre, ce qui prend moins de place qu'une adresse mémoire. A la rigueur, les instructions avec une constante immédiate prennent un peu plus de place, car elles doivent encoder un nom de registre en plus de la constante et de l'opcode. Les instructions ''load-op'' des processeurs CISC sont un peu dans le même cas, sauf qu'il faut remplacer la constante par une adresse, qui a généralement la même taille. Les instructions sont donc en moyenne plus courte sur les processeurs à registre, du fait de la présence de registres. ===Annexe : les toutes premières architectures à accumulateur : le Manchester Baby=== [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] Les architectures à accumulateurs sont apparues dès les débuts de l'informatique. Le tout premier ordinateur à programme enregistré en mémoire, le ''Manchester Baby'', était une architecture à accumulateur. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 adresses, fabriquée avec des tubes Williams (abordés dans une annexe à la fin du cours). Chaque adresse mémorisait 32 bits, qui pouvaient encoder soit un nombre, soit une instruction. Le programme devait tenir dans la RAM, avec une instruction par adresse maximum, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 bits d'adresse servait à indiquer où se trouvent la seconde opérande en RAM, les 16 restants sont inutilisés. En théorie, les 12 bits d'adresse permettaient d'adresser 4096 adresses, mais seules 32 étaient réellement présentes. Le processeur avait un registre accumulateur de 32 bits, un ''program counter'' et un registre d'instruction. Il intégrait un additionneur dédié au ''program counter'', mais l'ALU n'avait pas d'additionneur. En conséquence, il ne gérait pas l'addition. A la place, il gérait la soustraction. Il pouvait cependant émuler l'addition à partir d'une soustraction. La soustraction était utilisée pour calculer le complément d'une opérande, et soustraire le complément revient à additionner. L'ALU était une ALU sérielle, à savoir qu'elle faisait les soustractions bit par bit. Le processeur supportait 7 instructions au total : la soustraction, des instructions de branchement et d'accès mémoire, rien d'autre. Les instructions de branchement utilisaient des modes d'adressage très particuliers, qu'on ne retrouve pas sur les ordinateurs modernes. Les branchements inconditionnels utilisaient une forme d'adressage mémoire indirect, pas les adressages usuels pour les branchements. Il n'y avait pas de branchements conditionnels, mais une ''SKIP instruction''. {|class="wikitable" |- ! SUB | Soustrait l'opérande mémoire de l'accumulateur. |- ! CMP | Skippe l'instruction suivante si l'accumulateur a une valeur négative. |- ! JMP | Branchement indirect mémoire. : * L'adresse de destination est lue depuis la mémoire. * L'adresse lue est intégrée dans l'instruction via adressage absolu. |- ! JRP | Branchement relatif indirect. * Lit une opérande depuis la mémoire, l'adresse est intégrée dans l'instruction via adressage absolu. * Additionne l'opérande lue au ''program counter''. |- ! LDN | Instruction LOAD. La donnée lue est inversée lors de la lecture, l'accumulateur contient le complément à deux de la donnée lue après la lecture. |- ! STO | Instruction STORE |- ! STOP | Éteint l'ordinateur. |} Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. La RAM avait la même taille, à savoir 32 nombres, leur taille était simplement augmentée. Par contre, la RAM était complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique, l’ancêtre du disque dur magnétique. Il contenait 40 pages, chacune ayant la même taille que la RAM. C'était là encore une architecture à accumulateur, sauf qu'elle intégrait aussi des registres d'indice. Et surtout : son processeur gérait l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. [[File:MM1Schematic French.svg|centre|vignette|upright=2.5|Architecture de la Manchester Mark 1.]] ==La micro-architecture des architectures à accumulateur sans registres d'indice== L'organisation interne d'une architecture à accumulateur est très différente de celle des processeurs à registre. Elle est plus ou moins la même pour tous ces processeurs, le point important étant que le chemin de données se résume à une ALU, un registre accumulateur et le bus de données. L'ALU est reliée au registre accumulateur, ainsi qu'au bus de données pour lire la seconde opérande, comme illustré ci-dessous. [[File:Accumulator.png|centre|vignette|upright=2|Accumulateur.]] ===L'unité de calcul et l'accumulateur=== Pour simplifier l'implémentation, le résultat est mémorisé dans un registre en sortie de l'unité de calcul. La raison est qu'on ne veut pas altérer l'accumulateur tant que le résultat final n'est pas totalement calculé. Rappelons que l'ALU ne fournit pas un résultat d'un seul bloc, mais que certains bits arrivent avant les autres, typiquement les bits de poids faible. Si le résultat était écrit dans l'accumulateur directement, il écraserait des bits de l’opérande en cours d'utilisation, ce qui fausserait le résultat. [[File:Accumulateur avec registre de sortie.png|centre|vignette|upright=2|Accumulateur avec registre de sortie]] Une autre solution utilisait un registre entre l'accumulateur et l'unité de calcul, appelé l’'''''accumulator latch'''''. Il remplace le registre en sortie de l'ALU, dans le sens où il permet d'écrire dans l'accumulateur sans effacer l'opérande, pendant que l’opération est en cours dans l'ALU. L'accumulateur est copié dans l’''accumulator latch'', avant que l'ALU démarre ses calculs. L'opérande est donc maintenue même si on commence à écrire le résultat dans l'accumulateur. Sur le 8085 d'Intel, l’''accumulator latch'' peut être initialisé avec une constante prédéfinie, ce qui permet d'implémenter certaines instructions très facilement. Par exemple, il peut être initialisé à 0, ce qui permet d'implémenter les instructions MOV et INC (incrémentation). Un MOV est équivalent à faire un OU entre le registre lu et 0. Une instruction INC initialise l'entrée de retenue de l'unité de calcul à 1, puis ajoute 0. La décrémentation est implémentée de la même manière, sauf que l’''accumulator latch'' est initialisé à -2 pour compenser l'entrée de retenue à 1. De plus, pour supporter les conversion de décimal à BCD, l’''accumulator latch'' peut être initialisé avec les constantes 0x00, 0x06, 0x60, or 0x66. L'''accumulator latch'' est relié à divers fils de commande provenant de l'unité de contrôle, qui décide quelle valeur d'initialisation utiliser en fonction de l'instruction décodée. [[File:Accumulator latch.png|centre|vignette|upright=2|Accumulator latch]] [[File:Chemin de données à un seul bus.png|vignette|Chemin de données à un seul bus]] De même, la seconde opérande, celle lue sur le bus de données, est mémorisée dans un registre en amont de l'ALU. C'était notamment très utile si le processeur utilisait une ALU plus courte que les opérandes, avec par exemple une ALU 4 bits pour un CPU 8 bits. Les anciens processeurs à accumulateur de type ''mainframe'' utilisaient des opérandes de grande taille, du genre 36 ou 48 bits, ce qui avait des conséquences sur l'unité de calcul utilisée, ainsi que sur la communication avec la mémoire. Il arrivait que de tels processeurs utilisaient des ALU sérielles, ou du moins octet-sérielles, plutôt qu'une véritable ALU 36 bits. Nous verrons aussi que c'est très utile sur les processeurs à accumulateur avec un bus interne unique, dans la suite du chapitre. ===La micro-architecture des architectures à accumulateur avec instructions LOAD/STORE=== Nous venons de voir comment est implémenté l'unité de calcul et l'accumulateur, et comment le tout est relié au bus de données. Mais cela ne permet que d'avoir un processeur à accumulateur rudimentaire, qui ne gére que des instructions arithmétiques et logiques. Il faut aussi gérer le cas des opérations LOAD/STORE et des modes d'adressages associés, mais c'est le séquenceur qui s'en occupe. Avec l'adressage absolu, les instructions LOAD et STORE ne font que connecter l'accumulateur au bus de données. L'instruction STORE nécessite de connecter l'accumulateur au bus de données, de manière à ce que le transfert des données se fasse de l'accumulateur vers le bus de données. L'instruction LOAD s'implémente de la même manière, sauf que le sens de transfert est inversé. Cependant, il existe une optimisation qui permet d'implémenter l'instruction LOAD sans ajouter de circuits. Pour cela, il suffit que l'unité de calcul gére les opérations ''pass through'', à savoir des opérations qui se contentent de recopier un opérande sur la sortie. Ici, l'idée est de recopier l'opérande provenant du bus de données. [[File:Architecture à accumulateur, microarchitecture.png|centre|vignette|upright=2|Architecture à accumulateur, microarchitecture]] Pour gérer nativement l'adressage indirect à registre, il suffit de connecter l'accumulateur au bus d'adresse. Le plus simple est d'ajouter un multiplexeur, comme illustré ci-dessous. La donnée lue est copiée dans l'accumulateur, ce qui fait qu'il vaut mieux utiliser un registre d’interfaçage, l'accumulateur n'étant pas utilisable à la fois pour le bus d'adresse et de données. [[File:Adressage indirect sur une architecture à accumulateur.png|centre|vignette|upright=2|Adressage indirect sur une architecture à accumulateur]] Pour finir, voyons comment le pointeur de pile et le ''program counter'' sont implémentés. Les architectures à accumulateur ont souvent des adresses de taille différente des données, ce qui fait qu'il vaut mieux utiliser un circuit incrémenteur dédié pour incrémenter le ''program counter'', plutôt que de l'incrémenter via l'unité de calcul. Les architectures à accumulateur ont parfois un pointeur de pile, qui gère une pile d'adresse de retour, pas une vraie pile d'appel. Aussi, le pointeur de pile est censé être incrémenté et décrémenté, pas plus. Pas d'addition ou de soustraction pour gérer des cadres de pile. Là encore, c'est la solution de l'incrémenteur séparé qui est retenue. Pour économiser des transistors, il n'y a qu'un seul incrémenteur partagé pour les deux. ==Les architectures à accumulateur à registres d'indice== Les architectures à accumulateur décrites dans la section précédente sont capables de faire de l'adressage indirect, mais n'incluent pas les modes d'adressage base + indice et absolus indicés, qui prennent une adresse et y ajoute un indice. Il s'agit des toutes premières architectures à accumulateur, comme les premiers ordinateurs IBM ou le fameux PDP-8. Mais par la suite, les processeurs à accumulateurs ont inclus un support des modes d'adressages indicés, grâce à des '''registres d'indice'''. ===Les registres d'indice=== Les registres d'indice stockent des indices de tableaux. Ils permettaient de supporter deux modes d'adressage : * Le '''mode d'adressage absolu indicé''' où une adresse fixe est additionnée à un indice variable. L'adresse fixe est intégrée dans l'instruction (adressage absolu), l'indice est dans un registre d'indice. * Le '''mode d'adressage base + indice''', où l'adresse est dans l'accumulateur et l'indice dans le registre d'indice. Les processeurs à accumulateur supportaient souvent des variantes des modes d'adressage précédents, où le registre d'indice était automatiquement incrémenté ou décrémenté à chaque utilisation. Au départ, ces processeurs n'utilisaient qu'un seul registre d'indice qui se comportait comme un second accumulateur spécialisé dans les calculs d'adresses mémoire. Le processeur supportait de nouvelles instructions qui utilisaient ce registre d'indice de façon implicite. Mais avec le temps, les processeurs finirent par incorporer plusieurs de ces registres. Les instructions de lecture ou d'écriture devaient alors préciser quel registre d'indice utiliser, en précisant un nom de registre d'indice, un numéro de registre d'indice. Il faut préciser que les registres d'indice ont une taille bien plus petite que l'accumulateur. Ils mémorisent des indices codés sur 16 bits ou moins, alors que l'accumulateur faisait typiquement 36 à 48 bits, parfois plus. La taille classique sur les anciens ''mainframes'' était de 15 bits, parfois moins. Il n'était pas rare de tomber sur des registres d'indice de 8 ou 9 bits. Leur petite taille rendait leur implémentation matérielle peu couteuse. Et c'est ce qui explique qu'ils étaient préférés à l'usage d'un second accumulateur. Un exemple est le cas du processeur Motorola 6809, un processeur à accumulateur qui contient deux registres d'indices nommés X et Y. L'accumulateur est noté D et fait 16 bits, il peut être parfois géré comme deux accumulateurs séparés A et B de 8 bits chacun. Il contenait aussi deux pointeurs de pile, l'un pour les programmes, l'autre pour le système d'exploitation, ainsi qu'un ''program counter''. Le registre de page était utilisé pour l'adressage absolu, comme vu dans le chapitre sur les modes d'adressage. [[File:6809 Internal Registers.svg|centre|vignette|upright=2|6809 Internal Registers]] Les processeurs IBM avaient autrefois plusieurs registres d'indice. Par exemple, l'IBM 704 avait trois registres d'indice de 15 bits. Leur contenu était soustrait de l'adresse absolue. Une instruction pouvait utiliser plusieurs registres d'indice pour adresser son opérande. Toute instruction utilisait trois bits pour sélectionner les registres d'indice utilisés. Fait assez original, lorsque plusieurs registres d'indice sont sélectionnés, le processeur n'additionne pas les trois registres à l'adresse de base. À la place, il fait un OU bit à bit entre les registres d'indice sélectionnés, et additionne le résultat à l'adresse. Les processeurs IBM à accumulateur ont fait ça sur toute la gamme IBM 700/7000, pour des raisons de compatibilité. Les processeurs suivants avaient 7 registres d'indices, mais conservaient les trois bits pour adresser les registres d'indices. Ils pouvaient fonctionner dans deux modes. Le premier mode est plus intuitif : les trois bits précisent un registre d'indice parmi les 7, qui est additionné avec l'adresse absolue. La valeur zéro indique qu'aucun registre d'indice n'est utilisé, ce qui explique qu'il y a 7 registres d'indice et non 8. Un second mode, compatible avec l'IBM 704, fait un OU logique entre les registres d'indice sélectionnés. Seuls les trois premiers registres d'indices peuvent être sélectionnés dans ce mode. Il y a deux instructions pour changer de mode : une pour passer en mode compatible, l'autre pour le quitter pour l'autre mode. Quelques rares processeurs à registres généraux ont utilisés des registres d'indice, en plus des registres généraux. Ce qui fait l'association que nous avons faite entre registres d'indice et architectures à accumulateur est imparfait, bien que solide sur le principe. Un exemple d'architecture de ce type sont les architectures de la série UNIVAC 1100/2200. Ils disposaient de 128 registres, qui étaient mappés en mémoire à partir de l'adresse mémoire 0, la majorité étant inaccessibles par le programmeur. Ils regroupaient 12 registres accumulateurs, 11 registres d'indice et 4 registres hybrides qui pouvaient servir soit de registre d'indice, soit de registres accumulateurs. ===La micro-architecture des architectures à accumulateur avec registres d'indice=== La présence de registres d'indice modifie grandement l'implémentation du processeur. En effet, il faut rajouter un banc de registre pour les registres d'indice. Le banc de registre est monoport, car on a besoin de lire ou d'écrire un indice à la fois. Et il faut aussi potentiellement rajouter de quoi faire les calculs d'adresse. Deux solutions sont possibles : une ALU dédiée aux calculs d'adresse, une seule ALU pour toutes les opérations. Dans le premier cas, il y a une ALU séparée associée aux registres d'indice. L'ALU et les registres d'indice sont placés en sortie du séquenceur, en-dehors du chemin de données, la sortie de l'ALU est directement connectée au bus d'adresse. L'unité de calcul d'adresse peut être utilisée pour incrémenter le ''program counter''. Un défaut de cette approche est qu'elle ne gère pas l'adresse indirect à registre. [[File:Chemin de données sans support des pointeurs, avec adressage absolu indicé.png|centre|vignette|upright=2|Chemin de données sans support des pointeurs, avec adressage absolu indicé]] Une autre option utilise un bus interne, qui interconnecte tout le chemin de données. Dans sa version la plus simple, il est relié à l'accumulateur, l'unité de calcul, le banc de registre d'indice et le bus de données. Avec cette solution, l'ALU est utilisé à la fois pour calculer les adresses et pour les instructions de calcul. En reliant le bus interne au bus d'adresse à travers un multiplexeur, on gère naturellement les adressages indirects. [[File:Architecture à accumulateur avec registres associés.png|centre|vignette|upright=2.5|Architecture à accumulateur avec registres associés]] Il faut noter que sur les architectures Von Neumann, le séquenceur est relié à ce bus interne. En effet, charger une instruction demande de passer par le bus mémoire, donc par l’intermédiaire de ce bus internet. Le ''program counter'' est envoyé sur ce bus pour lire l'instruction, puis l'instruction lue est recopiée dans le registre d'instruction. Le chargement d'une instruction est donc géré comme une lecture des plus classiques. De plus, cela permet d'incrémenter le ''program counter'' au niveau de l'unité de calcul entière. Le ''program counter'' est envoyé sur le bus interne, incrémenté par l'ALU, puis le résultat est recopié dans le ''program counter'' via le bus interne. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] ==Les processeurs bi-accumulateurs : le Motorola 6800== Le Motorola 6800 était un processeur 8 bits qui gérait des adresses de 16 bits. Il contenait deux accumulateurs nommés A et B, de 8 bits chacun. Il disposait aussi d'un registre d'indice, d'un pointeur de pile et d'un ''program counter'', tous les trois de 16 bits. Le registre d'état regroupait 6 bits, qu'on ne détaillera pas ici. [[File:MC6800 Processor Diagram.png|centre|vignette|upright=2|Interface et registres du MC6800.]] La présence des deux accumulateurs impactait surtout les instructions dyadiques. Les instructions monadiques avaient juste à préciser où se trouvait l'opérande : soit en RAM, soit dans le premier accumulateur, soit dans le second. Pour les opérations dyadiques, la gestion était totalement différente. En théorie, le premier opérande est dans un accumulateur, soit A, soit B. La seconde opérande vient soit de l'autre accumulateur, soit de la mémoire RAM. Et selon les instructions, tout variait. Pour l'addition, il y avait trois instructions. Les deux premières additionnaient un opérande provenant de la mémoire avec un accumulateur. L'instruction ADDA sélectionnait le premier accumulateur, l'instruction ADDB sélectionnait le second accumulateur. Mais une troisième instruction, l’instruction ABA, permettait d'additionner le contenu des deux accumulateurs. Pour les autres opérations, il n'était pas possible d'utiliser les deux accumulateurs en même temps. La seule possibilité était de faire une opération entre un accumulateur et un opérande venant de la mémoire. Toutes les instructions étaient en double, avec une copie par accumulateur. Par exemple, l'instruction ANDA faisait un ET entre l’accumulateur A et l'opérande mémoire, l'instruction ANDB faisait pareil avec l'accumulateur B. ==Les architectures hybrides registres-accumulateur== Il a existé quelques architectures qui étaient des hybrides entre architectures à accumulateur et architecture à registre. Elles ont servi de transition entre les deux, durant les années 80-90. Elles avaient un accumulateur unique couplé à un banc de registres généraux. Par exemple, les premiers processeurs Intel 8 bits étaient des processeurs hybrides-accumulateur. Lles CPU Intel 8 bits disposaient de 7 registres de 8 bits nommés A, B, C, D, E, F, H, L, SP. Ils correspondent respectivement à : * l'accumulateur A ; * six registres nommés B, C, D, E, H et L ; * le registre d'état F ; * le pointeur de pile SP. Sur ces processeurs, les instructions dyadiques devaient mettre leur premier opérande dans l'accumulateur, la seconde provenait soit des registres, soit de la RAM, soit d'une constante immédiate. Les opérations monadiques pouvaient lire leur opérande depuis l'accumulateur, les autres registres ou la RAM, tout était permis. Les registres d'indices disparaissaient sur ces architectures, en théorie. Les registres généraux pouvaient être utilisés comme registre d'indice ou pour stocker des opérandes, ils étaient assez versatiles pour servir de registres d'indices. La présence de registres a de nombreux avantages, comparé aux architectures à accumulateur pures. Les instructions arithmétiques sont plus rapide, lire un registre étant plus rapide qu'un accès RAM. Les performances sont donc augmentées. De plus, les instructions arithmétiques utilisant ces registres sont plus courtes : pas besoin d'encoder une adresse mémoire, un nom de registre suffit. Vu que les processeurs de l’époque avaient des instructions de taille variable, cela améliorait la densité de code. La microarchitecture de ces processeurs est très similaire à celle d'un processeur avec des registres d'indices. La seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Le banc de registre est systématiquement monoport, car il n'avait aucune raison d'être multiport. Pour les instructions dyadiques, seules à lire deux opérandes, il ne servait que pour la seconde opérande, la première était lue depuis l'accumulateur. Les processeurs hybrides registre-accumulateur se classent en deux types principaux : ceux qui ont un seul bus interne, et ceux qui en ont deux. Le premier cas est identique à celui vu précédemment pour les architectures à accumulateur avec registres d'indice, à la seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Afin de gérer l'adressage indirect à registre, le bus interne est connecté aux deux registres d’interfaçage mémoire. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] Notons que cela permet aussi d'implémenter facilement les branchements indirects, car le bus interne permet d'échanger des adresses entre ''program counter'' et banc de registre. De même, il est possible d'utiliser l'ALU pour gérer les branchements indirects., en plus de l'utiliser pour incrémenter le ''program counter''. [[File:Single bus organization.jpg|centre|vignette|upright=2|Single bus organization]] Une autre solution utilisait deux bus internes : un connecté au bus de données, un autre relié au bus d'adresse. Le bus de commande mémoire était lui commandé par le séquenceur, l'unité de contrôle. L'intermédiaire entre ces deux bus était le banc de registre, ainsi que les autres registres. Le banc de registre était connecté aux deux bus interne, avec un port de lecture relié au bus d'adresse, un port de lecture-écriture relié au bus de données. Le port de lecture était utilisé pour l'adressage indirect, l'autre l'était pour le reste. [[File:Proz1-e.png|centre|vignette|upright=2|Intérieur d'un processeur.]] L'organisation à deux bus simplifiait la gestion du ''program counter'' et le chargement des instructions. Le ''program counter'' était soit séparé du banc de registre, soit placé dans le banc de registre. Les deux solutions étaient utilisés, tout dépend du processeur. Il faut noter que si le ''program counter'' est intégré au banc de registres, alors la microarchitecture du processeur est bien plus simple. L'envoi du ''program counter'' sur le bus d'adresse utilise le port de lecture relié au bus d'adresse, qui sert aussi pour l'adressage indirect. L'économie de circuits, sans compter la simplicité d'implémentation que cela implique, explique sans doute que la technique a été utilisée sur quelques processeurs anciens. Le ''program counter'' était généralement incrémenté par l'ALU, ce qui explique qu'il soit connecté au bus interne pour les données. La connexion est aussi utile pour gérer les branchements indirects, qui copient un registre dans le ''program counter'', ainsi que les branchements relatifs (addition dans l'ALU), voire les branchements directs (l'adresse vers laquelle brancher est envoyée en entrée de l'ALU et propagée en sortie avec une opération ''pass through''). [[File:Connexion du program counter sur les bus avec PC dans le banc de registres.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC dans le banc de registres]] ===Les registres d'interruption avec un processeur hybride-accumulateur : l'exemple du Z80=== Un exemple de processeur registre-accumulateur à deux bus interne est le Z80, un processeur fortement inspiré des CPU Intel 8 bits. Il a un jeu d'instruction similaire, mais a diverses améliorations par rapport au design original. Notamment, le processeur a des registres séparés pour les interruptions. Sur le Z80, les registres généraux sont dupliqués avec 6 registres pour les interruptions et 6 registres pour les programmes autres. Leur copie pour les interruptions sont nommées B', C', D', E', H', L'. Les 12 registres sont placés dans le banc de registre, ce qui implique que le fenêtrage de registres est utilisé pour gérer la séparation entre registre d'interruption et normaux. Il faut noter que l'accumulateur et le registre d'état sont aussi dupliqués, leurs copies étant nommées A' et F'. Mais leur duplication se fait autrement que par fenêtrage de registre. En plus des registres précédents, le Z80 incorporait deux registres d'indice nommés X et Y, ainsi qu'un pointeur de pile SP et un ''program counter'' PC. Ils n'étaient pas dupliqués pour les interruptions. Les registres d'indice étaient reliés à une unité de calcul d'adresse. L'unité de calcul d'adresse prenait deux opérandes : un indice, et une adresse mémoire provenant soit du banc de registre, soit de l'accumulateur. En clair, l'unité de calcul d'adresse faisait le lien entre les deux bus internet : le bus de données interne en entrée, le bus d'adresse en sortie. À l'intérieur du processeur, tous les registres étaient regroupés dans un banc de registre unique, sauf les accumulateurs, les registres d'état et le ''program counter''. Bien que ce ne soit pas indiqué sur le schéma ci-dessous, le ''program counter'' est séparé du banc de registre, alors que le pointeur de pile est dedans. Le compteur IR est lui associé au ''program counter'', il est sortit du banc de registre. Le Z80 utilise lui aussi un incrémenteur séparé de l'ALU, qui est utilisé pour mettre à jour le ''program counter'', le pointeur de pile et un compteur de rafraichissement mémoire nommé IR sur le Z80 (pour rappel, le rafraichissement mémoire demande de balayer la mémoire d'adresse en adresse et été fait par le CPU à l'époque). De plus, il est utilisé pour les instructions INC et DEC qui incrémentent une opérande de 16 bits obtenue en combinant deux registres de 8 bits. En clair, l'incrémenteur du ''program counter'' a été réutilisé de beaucoup de manières originales. [[File:Z80 arch.svg|centre|vignette|upright=3|Microarchitecture du Z80.]] Le Z80 incorporait des instructions pour échanger le contenu des deux ensembles de registres, accumulateur inclus. Elles permettaient d'utiliser les registres d'interruption pour les programmes et réciproquement. En clair, cela doublait le nombre de registres si les interruptions n'étaient pas utilisées. * L'instruction EXX échangeait les deux fenêtres de registres généraux : les registres B, C, D, E, H et L devenaient les registres B', C', D', E', H' et L' et inversement. * L'instruction EX échangeait l'accumulateur et le registre d'état : les registres A,F devenait A',F' et inversement. Le fenêtrage de registre était modifié par l'instruction EXX, qui échangeait les deux fenêtres de registres. Pour l'implémenter, une bascule était ajouté au processeur, appelons-la la bascule INT. Elle était relié au bus d'adresse du banc de registre, dont elle mémorisait le bit de poids fort. L'instruction EXX inversait la valeur de la bascule INT. Il est aussi possible d'échanger le contenu des registres D,E et H,L avec une instruction dédiée, ce qui est là encore fait par deux bascules : une pour les registres D,E et une autre pour les registres H,L. Pour l'accumulateur et le registre d'état, le choix entre registre normal et registre d'interruption se faisait là encore par une seconde bascule appelée la bascule A. La bascule est reliée à un multiplexeur et un démultiplexeur, qui permet de choisir quel accumulateur relier à l'unité de calcul. L'instruction EX inverse le contenu de la bascule A. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=L'unité de contrôle | prevText=L'unité de contrôle | next=Les processeurs 8 bits et moins | nextText=Les processeurs 8 bits et moins }} </noinclude> mm851vwjyyuznx2j5h2ed4eldxotvsp 744159 744158 2025-06-05T14:22:36Z Mewtow 31375 /* Annexe : les toutes premières architectures à accumulateur : le Manchester Baby */ 744159 wikitext text/x-wiki Les architectures que nous avons vu précédemment dans ce cours disposent de registres pour les données, en plus du pointeur de pile, d'un ''program counter'', et de quelques autres. Elles sont appelées des '''architectures à registres''', terme qui trahit bien le fait qu'elles ont des registres généraux ou spécialisés pour stocker temporairement des données. Et si on leur a donné un nom, c'est parce qu'il existe des architectures qui ne sont pas dans cette catégorie. Il en existe plusieurs types, mais ce chapitre va se concentrer sur les '''architectures à accumulateur'''. [[File:Isaccumulator.png|vignette|Architecture à accumulateur.]] Les architectures à accumulateur sont centrées autour d'un registre architectural appelé l''''accumulateur'''. Il est utilisé pour toutes les opérations arithmétiques dyadiques, où il sert à la fois de source et de destination. Toutes les instructions dyadiques sont de type ''load-op'' : une opérande est lue depuis l'accumulateur, le second opérande est lu depuis la mémoire RAM, le résultat de l'instruction est automatiquement mémorisé dans l'accumulateur. Les instructions monadiques peuvent utiliser un opérande dans l'accumulateur, ou dans la mémoire RAM, les deux sont théoriquement possibles. La conséquence est que le nombre d'accès mémoire est drastiquement diminué : de 3 par instructions sur une architecture mémoire-mémoire, on passe à seulement un avec un accumulateur. Les opérations dyadiques ont besoin d'un seul accès mémoire pour lire la seconde opérande, les opérations monadique en font aussi un seul pour lire leur unique opérande. {|class="wikitable" |- ! Classe d'architecture ! Nombre d'accès mémoire par opération dyadique |- |- ! Architecture à accumulateur | Un accès mémoire par instruction, pour lire la seconde opérande |- ! Architecture à registres | Zéro si les opérandes sont dans les registres, un pour les opérations ''load-op'', LOAD et STORE. |} ==Le jeu d'instruction des architectures à accumulateur sans registres d'indice== L'accumulateur est adressé grâce au mode d'adressage implicite, de même que le résultat de l'opération. Par contre, les autres opérandes sont localisés avec d'autres modes d'adressage, et lues en mémoire RAM. Le résultat ainsi qu'un des opérandes sont adressés de façon implicite car dans l'accumulateur, seule la seconde opérande étant adressée directement. Grâce à l'accumulateur, une instruction ne fait qu'un seul accès mémoire maximum, ce qui rend le processeur très facile à implémenter. ===Les registres des anciennes architectures à accumulateur=== [[File:IBM 701console.jpg|vignette|IBM 701, console extérieure.]] Les architectures à accumulateur étaient communes dans les années 50-60. A l'époque, les ordinateurs étaient gigantesques, ils prenaient une pièce de bâtiment entière dans le pire des cas, une armoire entière dans le meilleur. Les ordinateurs de l'époque étaient surtout utilisés pour du calcul scientifique ou des tâches d’ingénierie demandant beaucoup de calcul, rarement pour de la compatibilité. Les nombres flottants n'étaient pas encore apparus. A la place, les ordinateurs de l'époque géraient des nombres entiers de grande taille, de 30 bits ou plus. En conséquence, l'accumulateur faisait facilement 30 à 60 bits. Par exemple, les ordinateurs de la Série scientifique IBM 700/7000 géraient des entiers de 36 bits, l’accumulateur faisait 38 bits : 36 bits plus deux bits pour les débordements. Au passage, de tels processeurs utilisaient l'adressage par mot, et non par byte. Historiquement, les premières architectures à accumulateur ne contenaient aucun autre registre que l'accumulateur. Ce n'est que dans les années 60 que de nombreuses architectures à accumulateur ont ajouté un second '''registre pour les multiplication/divisions'''. Un exemple est celui de l'IBM 701, qui incorporait un registre accumulateur de 38 bits et un registre multiplieur de 36 bits. Le registre mémorise le multiplieur lors d'une opération de multiplication. Il mémorise donc un opérande, pas le résultat. Il peut aussi décaler le multiplieur vers la droite/gauche, ce qui est utile pour exécuter la multiplication. C'est ce qui est fait sur l'IBM 7094. Une autre possibilité est que ce registre mémorise une partie du résultat de l'opération. Pour rappel, le résultat d'une multiplication/division est codé sur deux fois de bits que ses opérandes. Par exemple, multipliez deux opérandes de 30 bits, vous obtiendrez un résultat de 60 bits. Les 30 bits de poids faible du résultat vont dans l'accumulateur, les 30 bits de poids fort vont dans ce second registre. Les architectures à accumulateur parfois un '''registre pour le pointeur de pile''', utilisé pour gérer les fonctions/procédures. Les architectures à accumulateurs supportaient une pile d'adresse de retour, souvent une pile d'appel. Mais pour cela, il fallait mémoriser le pointeur de pile dans le processeur, ce qui demandait un registre dédié. ===L'adressage indirect avec l'accumulateur=== Les instructions LOAD et STORE existent bel et bien sur les architectures à accumulateur, mais n'ont pas les mêmes modes d'adressages. L'instruction LOAD copie une donnée de la RAM vers l'accumulateur, l'instruction STORE copie l'accumulateur dans une adresse. Les deux instructions n'ont pas besoin d'adresser l'accumulateur, qui est adressé de manière implicite, juste de préciser l'adresse à lire/écrire. Les architectures à accumulateur supportaient souvent le mode d'adressage indirect mémoire. Un exemple est celui des ordinateurs Data General Nova, qui sont des architectures à accumulateur et qui supportaient ce mode d'adressage. Les deux instructions LOAD et STORE existaient en deux versions, distinguées par un bit d'indirection. Si ce bit est à 0 dans l'opcode, alors l'instruction utilise le mode d'adressage absolu normal : l'adresse intégrée dans l'instruction est celle de la donnée. Mais s'il est à 1, alors l'adresse intégrée dans l'instruction est celle du pointeur. Cependant, la présence de l'accumulateur permettait d'utiliser l'adressage indirect à registre, pour gérer les pointeurs. Pour rappel, avec le mode d'adressage indirect à registre, l'adresse à lire/écrire est dans un registre. Ici, l'adresse à lire/écrire est prise dans l'accumulateur, seul registre disponible pour. L'adressage indirect est plus simple à implémenter pour l'instruction LOAD, car elle prend un seul opérande : l'adresse à lire. L'adresse à lire est placée dans l'accumulateur, la donnée lue est elle aussi chargée dans l'accumulateur. Pour l'instruction STORE, il faut fournir deux opérandes, l'adresse et la donnée à écrire, ce qui peut poser problème. Mais au pire, il est toujours possible d'utiliser l'adressage absolu ou indirect mémoire : l'adresse est dans l'instruction, la donnée à écrire dans l'accumulateur. ===L'encodage des instructions=== Sur une architecture à accumulateur l'encodage d'une instruction dyadique est assez simple, vu que l'accumulateur est adressé implicitement. La seconde opérande est localisée soit par une adresse mémoire (adressage absolu), soit est une constante (adressage immédiat). L'adresse mémoire est généralement assez longue, plus que l'opcode. {|class="wikitable" |+ Encodage d'une instruction dyadique |- ! rowspan="2" | Opcode | Adresse mémoire (adressage absolu) |- | Constante (adressage immédiat) |} L'encodage d'une instruction monadique est similaire. Si l'opérande est lue depuis la mémoire RAM, alors l'instruction est encodée comme une instruction dyadique. Il en est de même pour les instructions qui copient une constante dans l'accumulateur. Par contre, si l'opérande est dans l'accumulateur, alors il y a juste besoin d'encoder l'opcode. La majorité des instructions a besoin de préciser une adresse, rares sont celles qui s'en passent. Au vu de cet encodage, les architectures à accumulateur sont qualifiées d''''architectures à une adresse''' par abus de langage. Il est intéressant de contraster leur encodage avec les architectures à registres. Les architectures à registre doivent encoder deux opérandes en plus de l'opcode, avec éventuellement où enregistrer le résultat sur les architectures 3-adresses. Par contre, les opérandes sont généralement des noms de registre, ce qui prend moins de place qu'une adresse mémoire. A la rigueur, les instructions avec une constante immédiate prennent un peu plus de place, car elles doivent encoder un nom de registre en plus de la constante et de l'opcode. Les instructions ''load-op'' des processeurs CISC sont un peu dans le même cas, sauf qu'il faut remplacer la constante par une adresse, qui a généralement la même taille. Les instructions sont donc en moyenne plus courte sur les processeurs à registre, du fait de la présence de registres. ===Annexe : les toutes premières architectures à accumulateur : le Manchester Baby=== [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] Les architectures à accumulateurs sont apparues dès les débuts de l'informatique. Le tout premier ordinateur à programme enregistré en mémoire, le ''Manchester Baby'', était une architecture à accumulateur. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 adresses, fabriquée avec des tubes Williams (abordés dans une annexe à la fin du cours). Chaque adresse mémorisait 32 bits, qui pouvaient encoder soit un nombre, soit une instruction. Le programme devait tenir dans la RAM, avec une instruction par adresse maximum, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 bits d'adresse servait à indiquer où se trouvent la seconde opérande en RAM, les 16 restants sont inutilisés. En théorie, les 12 bits d'adresse permettaient d'adresser 4096 adresses, mais seules 32 étaient réellement présentes. Le processeur avait un registre accumulateur de 32 bits, un ''program counter'' et un registre d'instruction. Il intégrait un additionneur dédié au ''program counter'', mais l'ALU n'avait pas d'additionneur. En conséquence, il ne gérait pas l'addition. A la place, il gérait la soustraction. Il pouvait cependant émuler l'addition à partir d'une soustraction. La soustraction était utilisée pour calculer le complément d'une opérande, et soustraire le complément revient à additionner. L'ALU était une ALU sérielle, à savoir qu'elle faisait les soustractions bit par bit. Le processeur supportait 7 instructions au total : la soustraction, des instructions de branchement et d'accès mémoire, rien d'autre. Les instructions de branchement utilisaient des modes d'adressage très particuliers, qu'on ne retrouve pas sur les ordinateurs modernes. Les branchements inconditionnels utilisaient une forme d'adressage mémoire indirect, pas les adressages usuels pour les branchements. Il n'y avait pas de branchements conditionnels, mais une ''SKIP instruction''. {|class="wikitable" |- ! SUB | Soustrait l'opérande mémoire de l'accumulateur. |- ! CMP | Skippe l'instruction suivante si l'accumulateur a une valeur négative. |- ! JMP | Branchement indirect mémoire. : * L'adresse de destination est lue depuis la mémoire. * L'adresse lue est intégrée dans l'instruction via adressage absolu. |- ! JRP | Branchement relatif indirect. * Lit une opérande depuis la mémoire, l'adresse est intégrée dans l'instruction via adressage absolu. * Additionne l'opérande lue au ''program counter''. |- ! LDN | Instruction LOAD. La donnée lue est inversée lors de la lecture, l'accumulateur contient le complément à deux de la donnée lue après la lecture. |- ! STO | Instruction STORE |- ! STOP | Éteint l'ordinateur. |} Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. Le Manchester Baby était un prototype, mais il avait été pensé pour être étendu, notamment afin d'avoir plus de mémoire. C'est pour cela que ses adresses étaient codées sur 12 bits, malgré sa mémoire de seulement 32 mots. Le plan initial, à savoir utiliser une RAM de 4096 mots, a cependant été abandonné pour la Manchester Mark 1. A la place, la RAM a gardé la même taille, à savoir 32 nombres, mais a été complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique. Le tambour magnétique contenait 40 pages, chacune ayant la même taille que la RAM. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. Le processeur gérait maintenant l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. De plus, il intégrait deux registres dédiés aux multiplications : un pour le multiplicande, un autre pour le multiplieur. Cependant, les multiplications étaient réalisées en enchainant une série d'additions, dans l'additionneur-soustracteur. C'était là encore une architecture à accumulateur, sauf qu'elle intégrait aussi des registres d'indice. Les registres d'indices étaient au nom de deux. Lors du chargement d'une instruction, un registre d'indice était sélectionné grâce à un bit de l'instruction. Le contenu de ce registre d'indice était additionné à l'instruction , l'adresse encodée dedans pour être précis, et le résultat était envoyé sur le bus mémoire. [[File:MM1Schematic French.svg|centre|vignette|upright=2.5|Architecture de la Manchester Mark 1.]] ==La micro-architecture des architectures à accumulateur sans registres d'indice== L'organisation interne d'une architecture à accumulateur est très différente de celle des processeurs à registre. Elle est plus ou moins la même pour tous ces processeurs, le point important étant que le chemin de données se résume à une ALU, un registre accumulateur et le bus de données. L'ALU est reliée au registre accumulateur, ainsi qu'au bus de données pour lire la seconde opérande, comme illustré ci-dessous. [[File:Accumulator.png|centre|vignette|upright=2|Accumulateur.]] ===L'unité de calcul et l'accumulateur=== Pour simplifier l'implémentation, le résultat est mémorisé dans un registre en sortie de l'unité de calcul. La raison est qu'on ne veut pas altérer l'accumulateur tant que le résultat final n'est pas totalement calculé. Rappelons que l'ALU ne fournit pas un résultat d'un seul bloc, mais que certains bits arrivent avant les autres, typiquement les bits de poids faible. Si le résultat était écrit dans l'accumulateur directement, il écraserait des bits de l’opérande en cours d'utilisation, ce qui fausserait le résultat. [[File:Accumulateur avec registre de sortie.png|centre|vignette|upright=2|Accumulateur avec registre de sortie]] Une autre solution utilisait un registre entre l'accumulateur et l'unité de calcul, appelé l’'''''accumulator latch'''''. Il remplace le registre en sortie de l'ALU, dans le sens où il permet d'écrire dans l'accumulateur sans effacer l'opérande, pendant que l’opération est en cours dans l'ALU. L'accumulateur est copié dans l’''accumulator latch'', avant que l'ALU démarre ses calculs. L'opérande est donc maintenue même si on commence à écrire le résultat dans l'accumulateur. Sur le 8085 d'Intel, l’''accumulator latch'' peut être initialisé avec une constante prédéfinie, ce qui permet d'implémenter certaines instructions très facilement. Par exemple, il peut être initialisé à 0, ce qui permet d'implémenter les instructions MOV et INC (incrémentation). Un MOV est équivalent à faire un OU entre le registre lu et 0. Une instruction INC initialise l'entrée de retenue de l'unité de calcul à 1, puis ajoute 0. La décrémentation est implémentée de la même manière, sauf que l’''accumulator latch'' est initialisé à -2 pour compenser l'entrée de retenue à 1. De plus, pour supporter les conversion de décimal à BCD, l’''accumulator latch'' peut être initialisé avec les constantes 0x00, 0x06, 0x60, or 0x66. L'''accumulator latch'' est relié à divers fils de commande provenant de l'unité de contrôle, qui décide quelle valeur d'initialisation utiliser en fonction de l'instruction décodée. [[File:Accumulator latch.png|centre|vignette|upright=2|Accumulator latch]] [[File:Chemin de données à un seul bus.png|vignette|Chemin de données à un seul bus]] De même, la seconde opérande, celle lue sur le bus de données, est mémorisée dans un registre en amont de l'ALU. C'était notamment très utile si le processeur utilisait une ALU plus courte que les opérandes, avec par exemple une ALU 4 bits pour un CPU 8 bits. Les anciens processeurs à accumulateur de type ''mainframe'' utilisaient des opérandes de grande taille, du genre 36 ou 48 bits, ce qui avait des conséquences sur l'unité de calcul utilisée, ainsi que sur la communication avec la mémoire. Il arrivait que de tels processeurs utilisaient des ALU sérielles, ou du moins octet-sérielles, plutôt qu'une véritable ALU 36 bits. Nous verrons aussi que c'est très utile sur les processeurs à accumulateur avec un bus interne unique, dans la suite du chapitre. ===La micro-architecture des architectures à accumulateur avec instructions LOAD/STORE=== Nous venons de voir comment est implémenté l'unité de calcul et l'accumulateur, et comment le tout est relié au bus de données. Mais cela ne permet que d'avoir un processeur à accumulateur rudimentaire, qui ne gére que des instructions arithmétiques et logiques. Il faut aussi gérer le cas des opérations LOAD/STORE et des modes d'adressages associés, mais c'est le séquenceur qui s'en occupe. Avec l'adressage absolu, les instructions LOAD et STORE ne font que connecter l'accumulateur au bus de données. L'instruction STORE nécessite de connecter l'accumulateur au bus de données, de manière à ce que le transfert des données se fasse de l'accumulateur vers le bus de données. L'instruction LOAD s'implémente de la même manière, sauf que le sens de transfert est inversé. Cependant, il existe une optimisation qui permet d'implémenter l'instruction LOAD sans ajouter de circuits. Pour cela, il suffit que l'unité de calcul gére les opérations ''pass through'', à savoir des opérations qui se contentent de recopier un opérande sur la sortie. Ici, l'idée est de recopier l'opérande provenant du bus de données. [[File:Architecture à accumulateur, microarchitecture.png|centre|vignette|upright=2|Architecture à accumulateur, microarchitecture]] Pour gérer nativement l'adressage indirect à registre, il suffit de connecter l'accumulateur au bus d'adresse. Le plus simple est d'ajouter un multiplexeur, comme illustré ci-dessous. La donnée lue est copiée dans l'accumulateur, ce qui fait qu'il vaut mieux utiliser un registre d’interfaçage, l'accumulateur n'étant pas utilisable à la fois pour le bus d'adresse et de données. [[File:Adressage indirect sur une architecture à accumulateur.png|centre|vignette|upright=2|Adressage indirect sur une architecture à accumulateur]] Pour finir, voyons comment le pointeur de pile et le ''program counter'' sont implémentés. Les architectures à accumulateur ont souvent des adresses de taille différente des données, ce qui fait qu'il vaut mieux utiliser un circuit incrémenteur dédié pour incrémenter le ''program counter'', plutôt que de l'incrémenter via l'unité de calcul. Les architectures à accumulateur ont parfois un pointeur de pile, qui gère une pile d'adresse de retour, pas une vraie pile d'appel. Aussi, le pointeur de pile est censé être incrémenté et décrémenté, pas plus. Pas d'addition ou de soustraction pour gérer des cadres de pile. Là encore, c'est la solution de l'incrémenteur séparé qui est retenue. Pour économiser des transistors, il n'y a qu'un seul incrémenteur partagé pour les deux. ==Les architectures à accumulateur à registres d'indice== Les architectures à accumulateur décrites dans la section précédente sont capables de faire de l'adressage indirect, mais n'incluent pas les modes d'adressage base + indice et absolus indicés, qui prennent une adresse et y ajoute un indice. Il s'agit des toutes premières architectures à accumulateur, comme les premiers ordinateurs IBM ou le fameux PDP-8. Mais par la suite, les processeurs à accumulateurs ont inclus un support des modes d'adressages indicés, grâce à des '''registres d'indice'''. ===Les registres d'indice=== Les registres d'indice stockent des indices de tableaux. Ils permettaient de supporter deux modes d'adressage : * Le '''mode d'adressage absolu indicé''' où une adresse fixe est additionnée à un indice variable. L'adresse fixe est intégrée dans l'instruction (adressage absolu), l'indice est dans un registre d'indice. * Le '''mode d'adressage base + indice''', où l'adresse est dans l'accumulateur et l'indice dans le registre d'indice. Les processeurs à accumulateur supportaient souvent des variantes des modes d'adressage précédents, où le registre d'indice était automatiquement incrémenté ou décrémenté à chaque utilisation. Au départ, ces processeurs n'utilisaient qu'un seul registre d'indice qui se comportait comme un second accumulateur spécialisé dans les calculs d'adresses mémoire. Le processeur supportait de nouvelles instructions qui utilisaient ce registre d'indice de façon implicite. Mais avec le temps, les processeurs finirent par incorporer plusieurs de ces registres. Les instructions de lecture ou d'écriture devaient alors préciser quel registre d'indice utiliser, en précisant un nom de registre d'indice, un numéro de registre d'indice. Il faut préciser que les registres d'indice ont une taille bien plus petite que l'accumulateur. Ils mémorisent des indices codés sur 16 bits ou moins, alors que l'accumulateur faisait typiquement 36 à 48 bits, parfois plus. La taille classique sur les anciens ''mainframes'' était de 15 bits, parfois moins. Il n'était pas rare de tomber sur des registres d'indice de 8 ou 9 bits. Leur petite taille rendait leur implémentation matérielle peu couteuse. Et c'est ce qui explique qu'ils étaient préférés à l'usage d'un second accumulateur. Un exemple est le cas du processeur Motorola 6809, un processeur à accumulateur qui contient deux registres d'indices nommés X et Y. L'accumulateur est noté D et fait 16 bits, il peut être parfois géré comme deux accumulateurs séparés A et B de 8 bits chacun. Il contenait aussi deux pointeurs de pile, l'un pour les programmes, l'autre pour le système d'exploitation, ainsi qu'un ''program counter''. Le registre de page était utilisé pour l'adressage absolu, comme vu dans le chapitre sur les modes d'adressage. [[File:6809 Internal Registers.svg|centre|vignette|upright=2|6809 Internal Registers]] Les processeurs IBM avaient autrefois plusieurs registres d'indice. Par exemple, l'IBM 704 avait trois registres d'indice de 15 bits. Leur contenu était soustrait de l'adresse absolue. Une instruction pouvait utiliser plusieurs registres d'indice pour adresser son opérande. Toute instruction utilisait trois bits pour sélectionner les registres d'indice utilisés. Fait assez original, lorsque plusieurs registres d'indice sont sélectionnés, le processeur n'additionne pas les trois registres à l'adresse de base. À la place, il fait un OU bit à bit entre les registres d'indice sélectionnés, et additionne le résultat à l'adresse. Les processeurs IBM à accumulateur ont fait ça sur toute la gamme IBM 700/7000, pour des raisons de compatibilité. Les processeurs suivants avaient 7 registres d'indices, mais conservaient les trois bits pour adresser les registres d'indices. Ils pouvaient fonctionner dans deux modes. Le premier mode est plus intuitif : les trois bits précisent un registre d'indice parmi les 7, qui est additionné avec l'adresse absolue. La valeur zéro indique qu'aucun registre d'indice n'est utilisé, ce qui explique qu'il y a 7 registres d'indice et non 8. Un second mode, compatible avec l'IBM 704, fait un OU logique entre les registres d'indice sélectionnés. Seuls les trois premiers registres d'indices peuvent être sélectionnés dans ce mode. Il y a deux instructions pour changer de mode : une pour passer en mode compatible, l'autre pour le quitter pour l'autre mode. Quelques rares processeurs à registres généraux ont utilisés des registres d'indice, en plus des registres généraux. Ce qui fait l'association que nous avons faite entre registres d'indice et architectures à accumulateur est imparfait, bien que solide sur le principe. Un exemple d'architecture de ce type sont les architectures de la série UNIVAC 1100/2200. Ils disposaient de 128 registres, qui étaient mappés en mémoire à partir de l'adresse mémoire 0, la majorité étant inaccessibles par le programmeur. Ils regroupaient 12 registres accumulateurs, 11 registres d'indice et 4 registres hybrides qui pouvaient servir soit de registre d'indice, soit de registres accumulateurs. ===La micro-architecture des architectures à accumulateur avec registres d'indice=== La présence de registres d'indice modifie grandement l'implémentation du processeur. En effet, il faut rajouter un banc de registre pour les registres d'indice. Le banc de registre est monoport, car on a besoin de lire ou d'écrire un indice à la fois. Et il faut aussi potentiellement rajouter de quoi faire les calculs d'adresse. Deux solutions sont possibles : une ALU dédiée aux calculs d'adresse, une seule ALU pour toutes les opérations. Dans le premier cas, il y a une ALU séparée associée aux registres d'indice. L'ALU et les registres d'indice sont placés en sortie du séquenceur, en-dehors du chemin de données, la sortie de l'ALU est directement connectée au bus d'adresse. L'unité de calcul d'adresse peut être utilisée pour incrémenter le ''program counter''. Un défaut de cette approche est qu'elle ne gère pas l'adresse indirect à registre. [[File:Chemin de données sans support des pointeurs, avec adressage absolu indicé.png|centre|vignette|upright=2|Chemin de données sans support des pointeurs, avec adressage absolu indicé]] Une autre option utilise un bus interne, qui interconnecte tout le chemin de données. Dans sa version la plus simple, il est relié à l'accumulateur, l'unité de calcul, le banc de registre d'indice et le bus de données. Avec cette solution, l'ALU est utilisé à la fois pour calculer les adresses et pour les instructions de calcul. En reliant le bus interne au bus d'adresse à travers un multiplexeur, on gère naturellement les adressages indirects. [[File:Architecture à accumulateur avec registres associés.png|centre|vignette|upright=2.5|Architecture à accumulateur avec registres associés]] Il faut noter que sur les architectures Von Neumann, le séquenceur est relié à ce bus interne. En effet, charger une instruction demande de passer par le bus mémoire, donc par l’intermédiaire de ce bus internet. Le ''program counter'' est envoyé sur ce bus pour lire l'instruction, puis l'instruction lue est recopiée dans le registre d'instruction. Le chargement d'une instruction est donc géré comme une lecture des plus classiques. De plus, cela permet d'incrémenter le ''program counter'' au niveau de l'unité de calcul entière. Le ''program counter'' est envoyé sur le bus interne, incrémenté par l'ALU, puis le résultat est recopié dans le ''program counter'' via le bus interne. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] ==Les processeurs bi-accumulateurs : le Motorola 6800== Le Motorola 6800 était un processeur 8 bits qui gérait des adresses de 16 bits. Il contenait deux accumulateurs nommés A et B, de 8 bits chacun. Il disposait aussi d'un registre d'indice, d'un pointeur de pile et d'un ''program counter'', tous les trois de 16 bits. Le registre d'état regroupait 6 bits, qu'on ne détaillera pas ici. [[File:MC6800 Processor Diagram.png|centre|vignette|upright=2|Interface et registres du MC6800.]] La présence des deux accumulateurs impactait surtout les instructions dyadiques. Les instructions monadiques avaient juste à préciser où se trouvait l'opérande : soit en RAM, soit dans le premier accumulateur, soit dans le second. Pour les opérations dyadiques, la gestion était totalement différente. En théorie, le premier opérande est dans un accumulateur, soit A, soit B. La seconde opérande vient soit de l'autre accumulateur, soit de la mémoire RAM. Et selon les instructions, tout variait. Pour l'addition, il y avait trois instructions. Les deux premières additionnaient un opérande provenant de la mémoire avec un accumulateur. L'instruction ADDA sélectionnait le premier accumulateur, l'instruction ADDB sélectionnait le second accumulateur. Mais une troisième instruction, l’instruction ABA, permettait d'additionner le contenu des deux accumulateurs. Pour les autres opérations, il n'était pas possible d'utiliser les deux accumulateurs en même temps. La seule possibilité était de faire une opération entre un accumulateur et un opérande venant de la mémoire. Toutes les instructions étaient en double, avec une copie par accumulateur. Par exemple, l'instruction ANDA faisait un ET entre l’accumulateur A et l'opérande mémoire, l'instruction ANDB faisait pareil avec l'accumulateur B. ==Les architectures hybrides registres-accumulateur== Il a existé quelques architectures qui étaient des hybrides entre architectures à accumulateur et architecture à registre. Elles ont servi de transition entre les deux, durant les années 80-90. Elles avaient un accumulateur unique couplé à un banc de registres généraux. Par exemple, les premiers processeurs Intel 8 bits étaient des processeurs hybrides-accumulateur. Lles CPU Intel 8 bits disposaient de 7 registres de 8 bits nommés A, B, C, D, E, F, H, L, SP. Ils correspondent respectivement à : * l'accumulateur A ; * six registres nommés B, C, D, E, H et L ; * le registre d'état F ; * le pointeur de pile SP. Sur ces processeurs, les instructions dyadiques devaient mettre leur premier opérande dans l'accumulateur, la seconde provenait soit des registres, soit de la RAM, soit d'une constante immédiate. Les opérations monadiques pouvaient lire leur opérande depuis l'accumulateur, les autres registres ou la RAM, tout était permis. Les registres d'indices disparaissaient sur ces architectures, en théorie. Les registres généraux pouvaient être utilisés comme registre d'indice ou pour stocker des opérandes, ils étaient assez versatiles pour servir de registres d'indices. La présence de registres a de nombreux avantages, comparé aux architectures à accumulateur pures. Les instructions arithmétiques sont plus rapide, lire un registre étant plus rapide qu'un accès RAM. Les performances sont donc augmentées. De plus, les instructions arithmétiques utilisant ces registres sont plus courtes : pas besoin d'encoder une adresse mémoire, un nom de registre suffit. Vu que les processeurs de l’époque avaient des instructions de taille variable, cela améliorait la densité de code. La microarchitecture de ces processeurs est très similaire à celle d'un processeur avec des registres d'indices. La seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Le banc de registre est systématiquement monoport, car il n'avait aucune raison d'être multiport. Pour les instructions dyadiques, seules à lire deux opérandes, il ne servait que pour la seconde opérande, la première était lue depuis l'accumulateur. Les processeurs hybrides registre-accumulateur se classent en deux types principaux : ceux qui ont un seul bus interne, et ceux qui en ont deux. Le premier cas est identique à celui vu précédemment pour les architectures à accumulateur avec registres d'indice, à la seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Afin de gérer l'adressage indirect à registre, le bus interne est connecté aux deux registres d’interfaçage mémoire. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] Notons que cela permet aussi d'implémenter facilement les branchements indirects, car le bus interne permet d'échanger des adresses entre ''program counter'' et banc de registre. De même, il est possible d'utiliser l'ALU pour gérer les branchements indirects., en plus de l'utiliser pour incrémenter le ''program counter''. [[File:Single bus organization.jpg|centre|vignette|upright=2|Single bus organization]] Une autre solution utilisait deux bus internes : un connecté au bus de données, un autre relié au bus d'adresse. Le bus de commande mémoire était lui commandé par le séquenceur, l'unité de contrôle. L'intermédiaire entre ces deux bus était le banc de registre, ainsi que les autres registres. Le banc de registre était connecté aux deux bus interne, avec un port de lecture relié au bus d'adresse, un port de lecture-écriture relié au bus de données. Le port de lecture était utilisé pour l'adressage indirect, l'autre l'était pour le reste. [[File:Proz1-e.png|centre|vignette|upright=2|Intérieur d'un processeur.]] L'organisation à deux bus simplifiait la gestion du ''program counter'' et le chargement des instructions. Le ''program counter'' était soit séparé du banc de registre, soit placé dans le banc de registre. Les deux solutions étaient utilisés, tout dépend du processeur. Il faut noter que si le ''program counter'' est intégré au banc de registres, alors la microarchitecture du processeur est bien plus simple. L'envoi du ''program counter'' sur le bus d'adresse utilise le port de lecture relié au bus d'adresse, qui sert aussi pour l'adressage indirect. L'économie de circuits, sans compter la simplicité d'implémentation que cela implique, explique sans doute que la technique a été utilisée sur quelques processeurs anciens. Le ''program counter'' était généralement incrémenté par l'ALU, ce qui explique qu'il soit connecté au bus interne pour les données. La connexion est aussi utile pour gérer les branchements indirects, qui copient un registre dans le ''program counter'', ainsi que les branchements relatifs (addition dans l'ALU), voire les branchements directs (l'adresse vers laquelle brancher est envoyée en entrée de l'ALU et propagée en sortie avec une opération ''pass through''). [[File:Connexion du program counter sur les bus avec PC dans le banc de registres.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC dans le banc de registres]] ===Les registres d'interruption avec un processeur hybride-accumulateur : l'exemple du Z80=== Un exemple de processeur registre-accumulateur à deux bus interne est le Z80, un processeur fortement inspiré des CPU Intel 8 bits. Il a un jeu d'instruction similaire, mais a diverses améliorations par rapport au design original. Notamment, le processeur a des registres séparés pour les interruptions. Sur le Z80, les registres généraux sont dupliqués avec 6 registres pour les interruptions et 6 registres pour les programmes autres. Leur copie pour les interruptions sont nommées B', C', D', E', H', L'. Les 12 registres sont placés dans le banc de registre, ce qui implique que le fenêtrage de registres est utilisé pour gérer la séparation entre registre d'interruption et normaux. Il faut noter que l'accumulateur et le registre d'état sont aussi dupliqués, leurs copies étant nommées A' et F'. Mais leur duplication se fait autrement que par fenêtrage de registre. En plus des registres précédents, le Z80 incorporait deux registres d'indice nommés X et Y, ainsi qu'un pointeur de pile SP et un ''program counter'' PC. Ils n'étaient pas dupliqués pour les interruptions. Les registres d'indice étaient reliés à une unité de calcul d'adresse. L'unité de calcul d'adresse prenait deux opérandes : un indice, et une adresse mémoire provenant soit du banc de registre, soit de l'accumulateur. En clair, l'unité de calcul d'adresse faisait le lien entre les deux bus internet : le bus de données interne en entrée, le bus d'adresse en sortie. À l'intérieur du processeur, tous les registres étaient regroupés dans un banc de registre unique, sauf les accumulateurs, les registres d'état et le ''program counter''. Bien que ce ne soit pas indiqué sur le schéma ci-dessous, le ''program counter'' est séparé du banc de registre, alors que le pointeur de pile est dedans. Le compteur IR est lui associé au ''program counter'', il est sortit du banc de registre. Le Z80 utilise lui aussi un incrémenteur séparé de l'ALU, qui est utilisé pour mettre à jour le ''program counter'', le pointeur de pile et un compteur de rafraichissement mémoire nommé IR sur le Z80 (pour rappel, le rafraichissement mémoire demande de balayer la mémoire d'adresse en adresse et été fait par le CPU à l'époque). De plus, il est utilisé pour les instructions INC et DEC qui incrémentent une opérande de 16 bits obtenue en combinant deux registres de 8 bits. En clair, l'incrémenteur du ''program counter'' a été réutilisé de beaucoup de manières originales. [[File:Z80 arch.svg|centre|vignette|upright=3|Microarchitecture du Z80.]] Le Z80 incorporait des instructions pour échanger le contenu des deux ensembles de registres, accumulateur inclus. Elles permettaient d'utiliser les registres d'interruption pour les programmes et réciproquement. En clair, cela doublait le nombre de registres si les interruptions n'étaient pas utilisées. * L'instruction EXX échangeait les deux fenêtres de registres généraux : les registres B, C, D, E, H et L devenaient les registres B', C', D', E', H' et L' et inversement. * L'instruction EX échangeait l'accumulateur et le registre d'état : les registres A,F devenait A',F' et inversement. Le fenêtrage de registre était modifié par l'instruction EXX, qui échangeait les deux fenêtres de registres. Pour l'implémenter, une bascule était ajouté au processeur, appelons-la la bascule INT. Elle était relié au bus d'adresse du banc de registre, dont elle mémorisait le bit de poids fort. L'instruction EXX inversait la valeur de la bascule INT. Il est aussi possible d'échanger le contenu des registres D,E et H,L avec une instruction dédiée, ce qui est là encore fait par deux bascules : une pour les registres D,E et une autre pour les registres H,L. Pour l'accumulateur et le registre d'état, le choix entre registre normal et registre d'interruption se faisait là encore par une seconde bascule appelée la bascule A. La bascule est reliée à un multiplexeur et un démultiplexeur, qui permet de choisir quel accumulateur relier à l'unité de calcul. L'instruction EX inverse le contenu de la bascule A. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=L'unité de contrôle | prevText=L'unité de contrôle | next=Les processeurs 8 bits et moins | nextText=Les processeurs 8 bits et moins }} </noinclude> 1tga0sm99bwjqukick75n9wyvyi7j2h 744160 744159 2025-06-05T14:28:48Z Mewtow 31375 /* Annexe : les toutes premières architectures à accumulateur : le Manchester Baby */ 744160 wikitext text/x-wiki Les architectures que nous avons vu précédemment dans ce cours disposent de registres pour les données, en plus du pointeur de pile, d'un ''program counter'', et de quelques autres. Elles sont appelées des '''architectures à registres''', terme qui trahit bien le fait qu'elles ont des registres généraux ou spécialisés pour stocker temporairement des données. Et si on leur a donné un nom, c'est parce qu'il existe des architectures qui ne sont pas dans cette catégorie. Il en existe plusieurs types, mais ce chapitre va se concentrer sur les '''architectures à accumulateur'''. [[File:Isaccumulator.png|vignette|Architecture à accumulateur.]] Les architectures à accumulateur sont centrées autour d'un registre architectural appelé l''''accumulateur'''. Il est utilisé pour toutes les opérations arithmétiques dyadiques, où il sert à la fois de source et de destination. Toutes les instructions dyadiques sont de type ''load-op'' : une opérande est lue depuis l'accumulateur, le second opérande est lu depuis la mémoire RAM, le résultat de l'instruction est automatiquement mémorisé dans l'accumulateur. Les instructions monadiques peuvent utiliser un opérande dans l'accumulateur, ou dans la mémoire RAM, les deux sont théoriquement possibles. La conséquence est que le nombre d'accès mémoire est drastiquement diminué : de 3 par instructions sur une architecture mémoire-mémoire, on passe à seulement un avec un accumulateur. Les opérations dyadiques ont besoin d'un seul accès mémoire pour lire la seconde opérande, les opérations monadique en font aussi un seul pour lire leur unique opérande. {|class="wikitable" |- ! Classe d'architecture ! Nombre d'accès mémoire par opération dyadique |- |- ! Architecture à accumulateur | Un accès mémoire par instruction, pour lire la seconde opérande |- ! Architecture à registres | Zéro si les opérandes sont dans les registres, un pour les opérations ''load-op'', LOAD et STORE. |} ==Le jeu d'instruction des architectures à accumulateur sans registres d'indice== L'accumulateur est adressé grâce au mode d'adressage implicite, de même que le résultat de l'opération. Par contre, les autres opérandes sont localisés avec d'autres modes d'adressage, et lues en mémoire RAM. Le résultat ainsi qu'un des opérandes sont adressés de façon implicite car dans l'accumulateur, seule la seconde opérande étant adressée directement. Grâce à l'accumulateur, une instruction ne fait qu'un seul accès mémoire maximum, ce qui rend le processeur très facile à implémenter. ===Les registres des anciennes architectures à accumulateur=== [[File:IBM 701console.jpg|vignette|IBM 701, console extérieure.]] Les architectures à accumulateur étaient communes dans les années 50-60. A l'époque, les ordinateurs étaient gigantesques, ils prenaient une pièce de bâtiment entière dans le pire des cas, une armoire entière dans le meilleur. Les ordinateurs de l'époque étaient surtout utilisés pour du calcul scientifique ou des tâches d’ingénierie demandant beaucoup de calcul, rarement pour de la compatibilité. Les nombres flottants n'étaient pas encore apparus. A la place, les ordinateurs de l'époque géraient des nombres entiers de grande taille, de 30 bits ou plus. En conséquence, l'accumulateur faisait facilement 30 à 60 bits. Par exemple, les ordinateurs de la Série scientifique IBM 700/7000 géraient des entiers de 36 bits, l’accumulateur faisait 38 bits : 36 bits plus deux bits pour les débordements. Au passage, de tels processeurs utilisaient l'adressage par mot, et non par byte. Historiquement, les premières architectures à accumulateur ne contenaient aucun autre registre que l'accumulateur. Ce n'est que dans les années 60 que de nombreuses architectures à accumulateur ont ajouté un second '''registre pour les multiplication/divisions'''. Un exemple est celui de l'IBM 701, qui incorporait un registre accumulateur de 38 bits et un registre multiplieur de 36 bits. Le registre mémorise le multiplieur lors d'une opération de multiplication. Il mémorise donc un opérande, pas le résultat. Il peut aussi décaler le multiplieur vers la droite/gauche, ce qui est utile pour exécuter la multiplication. C'est ce qui est fait sur l'IBM 7094. Une autre possibilité est que ce registre mémorise une partie du résultat de l'opération. Pour rappel, le résultat d'une multiplication/division est codé sur deux fois de bits que ses opérandes. Par exemple, multipliez deux opérandes de 30 bits, vous obtiendrez un résultat de 60 bits. Les 30 bits de poids faible du résultat vont dans l'accumulateur, les 30 bits de poids fort vont dans ce second registre. Les architectures à accumulateur parfois un '''registre pour le pointeur de pile''', utilisé pour gérer les fonctions/procédures. Les architectures à accumulateurs supportaient une pile d'adresse de retour, souvent une pile d'appel. Mais pour cela, il fallait mémoriser le pointeur de pile dans le processeur, ce qui demandait un registre dédié. ===L'adressage indirect avec l'accumulateur=== Les instructions LOAD et STORE existent bel et bien sur les architectures à accumulateur, mais n'ont pas les mêmes modes d'adressages. L'instruction LOAD copie une donnée de la RAM vers l'accumulateur, l'instruction STORE copie l'accumulateur dans une adresse. Les deux instructions n'ont pas besoin d'adresser l'accumulateur, qui est adressé de manière implicite, juste de préciser l'adresse à lire/écrire. Les architectures à accumulateur supportaient souvent le mode d'adressage indirect mémoire. Un exemple est celui des ordinateurs Data General Nova, qui sont des architectures à accumulateur et qui supportaient ce mode d'adressage. Les deux instructions LOAD et STORE existaient en deux versions, distinguées par un bit d'indirection. Si ce bit est à 0 dans l'opcode, alors l'instruction utilise le mode d'adressage absolu normal : l'adresse intégrée dans l'instruction est celle de la donnée. Mais s'il est à 1, alors l'adresse intégrée dans l'instruction est celle du pointeur. Cependant, la présence de l'accumulateur permettait d'utiliser l'adressage indirect à registre, pour gérer les pointeurs. Pour rappel, avec le mode d'adressage indirect à registre, l'adresse à lire/écrire est dans un registre. Ici, l'adresse à lire/écrire est prise dans l'accumulateur, seul registre disponible pour. L'adressage indirect est plus simple à implémenter pour l'instruction LOAD, car elle prend un seul opérande : l'adresse à lire. L'adresse à lire est placée dans l'accumulateur, la donnée lue est elle aussi chargée dans l'accumulateur. Pour l'instruction STORE, il faut fournir deux opérandes, l'adresse et la donnée à écrire, ce qui peut poser problème. Mais au pire, il est toujours possible d'utiliser l'adressage absolu ou indirect mémoire : l'adresse est dans l'instruction, la donnée à écrire dans l'accumulateur. ===L'encodage des instructions=== Sur une architecture à accumulateur l'encodage d'une instruction dyadique est assez simple, vu que l'accumulateur est adressé implicitement. La seconde opérande est localisée soit par une adresse mémoire (adressage absolu), soit est une constante (adressage immédiat). L'adresse mémoire est généralement assez longue, plus que l'opcode. {|class="wikitable" |+ Encodage d'une instruction dyadique |- ! rowspan="2" | Opcode | Adresse mémoire (adressage absolu) |- | Constante (adressage immédiat) |} L'encodage d'une instruction monadique est similaire. Si l'opérande est lue depuis la mémoire RAM, alors l'instruction est encodée comme une instruction dyadique. Il en est de même pour les instructions qui copient une constante dans l'accumulateur. Par contre, si l'opérande est dans l'accumulateur, alors il y a juste besoin d'encoder l'opcode. La majorité des instructions a besoin de préciser une adresse, rares sont celles qui s'en passent. Au vu de cet encodage, les architectures à accumulateur sont qualifiées d''''architectures à une adresse''' par abus de langage. Il est intéressant de contraster leur encodage avec les architectures à registres. Les architectures à registre doivent encoder deux opérandes en plus de l'opcode, avec éventuellement où enregistrer le résultat sur les architectures 3-adresses. Par contre, les opérandes sont généralement des noms de registre, ce qui prend moins de place qu'une adresse mémoire. A la rigueur, les instructions avec une constante immédiate prennent un peu plus de place, car elles doivent encoder un nom de registre en plus de la constante et de l'opcode. Les instructions ''load-op'' des processeurs CISC sont un peu dans le même cas, sauf qu'il faut remplacer la constante par une adresse, qui a généralement la même taille. Les instructions sont donc en moyenne plus courte sur les processeurs à registre, du fait de la présence de registres. ===Annexe : les toutes premières architectures à accumulateur : le Manchester Baby=== [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] Les architectures à accumulateurs sont apparues dès les débuts de l'informatique. Le tout premier ordinateur à programme enregistré en mémoire, le ''Manchester Baby'', était une architecture à accumulateur. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 adresses, fabriquée avec des tubes Williams (abordés dans une annexe à la fin du cours). Chaque adresse mémorisait 32 bits, qui pouvaient encoder soit un nombre, soit une instruction. Le programme devait tenir dans la RAM, avec une instruction par adresse maximum, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 bits d'adresse servait à indiquer où se trouvent la seconde opérande en RAM, les 16 restants sont inutilisés. En théorie, les 12 bits d'adresse permettaient d'adresser 4096 adresses, mais seules 32 étaient réellement présentes. Le processeur avait un registre accumulateur de 32 bits, un ''program counter'' et un registre d'instruction. Il intégrait un additionneur dédié au ''program counter'', mais l'ALU n'avait pas d'additionneur. En conséquence, il ne gérait pas l'addition. A la place, il gérait la soustraction. Il pouvait cependant émuler l'addition à partir d'une soustraction. La soustraction était utilisée pour calculer le complément d'une opérande, et soustraire le complément revient à additionner. L'ALU était une ALU sérielle, à savoir qu'elle faisait les soustractions bit par bit. Le processeur supportait 7 instructions au total : la soustraction, des instructions de branchement et d'accès mémoire, rien d'autre. Les instructions de branchement utilisaient des modes d'adressage très particuliers, qu'on ne retrouve pas sur les ordinateurs modernes. Les branchements inconditionnels utilisaient une forme d'adressage mémoire indirect, pas les adressages usuels pour les branchements. Il n'y avait pas de branchements conditionnels, mais une ''SKIP instruction''. {|class="wikitable" |- ! SUB | Soustrait l'opérande mémoire de l'accumulateur. |- ! CMP | Skippe l'instruction suivante si l'accumulateur a une valeur négative. |- ! JMP | Branchement indirect mémoire. : * L'adresse de destination est lue depuis la mémoire. * L'adresse lue est intégrée dans l'instruction via adressage absolu. |- ! JRP | Branchement relatif indirect. * Lit une opérande depuis la mémoire, l'adresse est intégrée dans l'instruction via adressage absolu. * Additionne l'opérande lue au ''program counter''. |- ! LDN | Instruction LOAD. La donnée lue est inversée lors de la lecture, l'accumulateur contient le complément à deux de la donnée lue après la lecture. |- ! STO | Instruction STORE |- ! STOP | Éteint l'ordinateur. |} Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. Le Manchester Baby était un prototype, mais il avait été pensé pour être étendu, notamment afin d'avoir plus de mémoire. C'est pour cela que ses adresses étaient codées sur 12 bits, malgré sa mémoire de seulement 32 mots. Le plan initial, à savoir utiliser une RAM de 4096 mots, a cependant été abandonné pour la Manchester Mark 1. A la place, la RAM a gardé la même taille, à savoir 32 nombres, mais a été complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique. Le tambour magnétique contenait 40 pages, chacune ayant la même taille que la RAM. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. Le processeur gérait maintenant l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. De plus, il intégrait deux registres dédiés aux multiplications : un pour le multiplicande, un autre pour le multiplieur. Ils étaient nommés D et R et étaient regroupés dans un seul tube Williams noté M. Cependant, les multiplications étaient réalisées en enchainant une série d'additions, dans l'additionneur-soustracteur. C'était là encore une architecture à accumulateur, sauf qu'elle intégrait aussi des registres d'indice. Les registres d'indices étaient au nom de deux et étaient notés B0 et B1. Lors du chargement d'une instruction, un registre d'indice était sélectionné grâce à un bit de l'instruction. Le contenu de ce registre d'indice était additionné à l'instruction , l'adresse encodée dedans pour être précis, et le résultat était envoyé sur le bus mémoire. La microarchitecture de la machine est illustrée ci-dessous. Elle a une ALU unique capable de faire plusieurs opérations, qui sont représentées dans des rectangles séparés. Les cercles dans le schéma suivant sont des tubes Williams, des écrans CRT modifiés de manière à servir de mémoire DRAM, dont le fonctionnement est détaillée dans le chapitre sur les mémoires historiques. Un tube Williams implémente un banc de registre complet, c'est à dire un groupe de 2 à 10, registres. L'accumulateur est noté A, les deux registres de multiplication sont regroupés dans le tube Williams M, les registres d'indice sont dans le tube noté B. Le tube Williams C regroupe le ''program counter'' et le registre d'instruction. L'additionneur sert à incrémenter le ''program counter'', mais aussi pour les branchements relatifs. La statistation est le nom donné au séquenceur, à l'unité de contrôle, décodeur d'instruction inclus. [[File:MM1Schematic French.svg|centre|vignette|upright=2.5|Architecture de la Manchester Mark 1.]] ==La micro-architecture des architectures à accumulateur sans registres d'indice== L'organisation interne d'une architecture à accumulateur est très différente de celle des processeurs à registre. Elle est plus ou moins la même pour tous ces processeurs, le point important étant que le chemin de données se résume à une ALU, un registre accumulateur et le bus de données. L'ALU est reliée au registre accumulateur, ainsi qu'au bus de données pour lire la seconde opérande, comme illustré ci-dessous. [[File:Accumulator.png|centre|vignette|upright=2|Accumulateur.]] ===L'unité de calcul et l'accumulateur=== Pour simplifier l'implémentation, le résultat est mémorisé dans un registre en sortie de l'unité de calcul. La raison est qu'on ne veut pas altérer l'accumulateur tant que le résultat final n'est pas totalement calculé. Rappelons que l'ALU ne fournit pas un résultat d'un seul bloc, mais que certains bits arrivent avant les autres, typiquement les bits de poids faible. Si le résultat était écrit dans l'accumulateur directement, il écraserait des bits de l’opérande en cours d'utilisation, ce qui fausserait le résultat. [[File:Accumulateur avec registre de sortie.png|centre|vignette|upright=2|Accumulateur avec registre de sortie]] Une autre solution utilisait un registre entre l'accumulateur et l'unité de calcul, appelé l’'''''accumulator latch'''''. Il remplace le registre en sortie de l'ALU, dans le sens où il permet d'écrire dans l'accumulateur sans effacer l'opérande, pendant que l’opération est en cours dans l'ALU. L'accumulateur est copié dans l’''accumulator latch'', avant que l'ALU démarre ses calculs. L'opérande est donc maintenue même si on commence à écrire le résultat dans l'accumulateur. Sur le 8085 d'Intel, l’''accumulator latch'' peut être initialisé avec une constante prédéfinie, ce qui permet d'implémenter certaines instructions très facilement. Par exemple, il peut être initialisé à 0, ce qui permet d'implémenter les instructions MOV et INC (incrémentation). Un MOV est équivalent à faire un OU entre le registre lu et 0. Une instruction INC initialise l'entrée de retenue de l'unité de calcul à 1, puis ajoute 0. La décrémentation est implémentée de la même manière, sauf que l’''accumulator latch'' est initialisé à -2 pour compenser l'entrée de retenue à 1. De plus, pour supporter les conversion de décimal à BCD, l’''accumulator latch'' peut être initialisé avec les constantes 0x00, 0x06, 0x60, or 0x66. L'''accumulator latch'' est relié à divers fils de commande provenant de l'unité de contrôle, qui décide quelle valeur d'initialisation utiliser en fonction de l'instruction décodée. [[File:Accumulator latch.png|centre|vignette|upright=2|Accumulator latch]] [[File:Chemin de données à un seul bus.png|vignette|Chemin de données à un seul bus]] De même, la seconde opérande, celle lue sur le bus de données, est mémorisée dans un registre en amont de l'ALU. C'était notamment très utile si le processeur utilisait une ALU plus courte que les opérandes, avec par exemple une ALU 4 bits pour un CPU 8 bits. Les anciens processeurs à accumulateur de type ''mainframe'' utilisaient des opérandes de grande taille, du genre 36 ou 48 bits, ce qui avait des conséquences sur l'unité de calcul utilisée, ainsi que sur la communication avec la mémoire. Il arrivait que de tels processeurs utilisaient des ALU sérielles, ou du moins octet-sérielles, plutôt qu'une véritable ALU 36 bits. Nous verrons aussi que c'est très utile sur les processeurs à accumulateur avec un bus interne unique, dans la suite du chapitre. ===La micro-architecture des architectures à accumulateur avec instructions LOAD/STORE=== Nous venons de voir comment est implémenté l'unité de calcul et l'accumulateur, et comment le tout est relié au bus de données. Mais cela ne permet que d'avoir un processeur à accumulateur rudimentaire, qui ne gére que des instructions arithmétiques et logiques. Il faut aussi gérer le cas des opérations LOAD/STORE et des modes d'adressages associés, mais c'est le séquenceur qui s'en occupe. Avec l'adressage absolu, les instructions LOAD et STORE ne font que connecter l'accumulateur au bus de données. L'instruction STORE nécessite de connecter l'accumulateur au bus de données, de manière à ce que le transfert des données se fasse de l'accumulateur vers le bus de données. L'instruction LOAD s'implémente de la même manière, sauf que le sens de transfert est inversé. Cependant, il existe une optimisation qui permet d'implémenter l'instruction LOAD sans ajouter de circuits. Pour cela, il suffit que l'unité de calcul gére les opérations ''pass through'', à savoir des opérations qui se contentent de recopier un opérande sur la sortie. Ici, l'idée est de recopier l'opérande provenant du bus de données. [[File:Architecture à accumulateur, microarchitecture.png|centre|vignette|upright=2|Architecture à accumulateur, microarchitecture]] Pour gérer nativement l'adressage indirect à registre, il suffit de connecter l'accumulateur au bus d'adresse. Le plus simple est d'ajouter un multiplexeur, comme illustré ci-dessous. La donnée lue est copiée dans l'accumulateur, ce qui fait qu'il vaut mieux utiliser un registre d’interfaçage, l'accumulateur n'étant pas utilisable à la fois pour le bus d'adresse et de données. [[File:Adressage indirect sur une architecture à accumulateur.png|centre|vignette|upright=2|Adressage indirect sur une architecture à accumulateur]] Pour finir, voyons comment le pointeur de pile et le ''program counter'' sont implémentés. Les architectures à accumulateur ont souvent des adresses de taille différente des données, ce qui fait qu'il vaut mieux utiliser un circuit incrémenteur dédié pour incrémenter le ''program counter'', plutôt que de l'incrémenter via l'unité de calcul. Les architectures à accumulateur ont parfois un pointeur de pile, qui gère une pile d'adresse de retour, pas une vraie pile d'appel. Aussi, le pointeur de pile est censé être incrémenté et décrémenté, pas plus. Pas d'addition ou de soustraction pour gérer des cadres de pile. Là encore, c'est la solution de l'incrémenteur séparé qui est retenue. Pour économiser des transistors, il n'y a qu'un seul incrémenteur partagé pour les deux. ==Les architectures à accumulateur à registres d'indice== Les architectures à accumulateur décrites dans la section précédente sont capables de faire de l'adressage indirect, mais n'incluent pas les modes d'adressage base + indice et absolus indicés, qui prennent une adresse et y ajoute un indice. Il s'agit des toutes premières architectures à accumulateur, comme les premiers ordinateurs IBM ou le fameux PDP-8. Mais par la suite, les processeurs à accumulateurs ont inclus un support des modes d'adressages indicés, grâce à des '''registres d'indice'''. ===Les registres d'indice=== Les registres d'indice stockent des indices de tableaux. Ils permettaient de supporter deux modes d'adressage : * Le '''mode d'adressage absolu indicé''' où une adresse fixe est additionnée à un indice variable. L'adresse fixe est intégrée dans l'instruction (adressage absolu), l'indice est dans un registre d'indice. * Le '''mode d'adressage base + indice''', où l'adresse est dans l'accumulateur et l'indice dans le registre d'indice. Les processeurs à accumulateur supportaient souvent des variantes des modes d'adressage précédents, où le registre d'indice était automatiquement incrémenté ou décrémenté à chaque utilisation. Au départ, ces processeurs n'utilisaient qu'un seul registre d'indice qui se comportait comme un second accumulateur spécialisé dans les calculs d'adresses mémoire. Le processeur supportait de nouvelles instructions qui utilisaient ce registre d'indice de façon implicite. Mais avec le temps, les processeurs finirent par incorporer plusieurs de ces registres. Les instructions de lecture ou d'écriture devaient alors préciser quel registre d'indice utiliser, en précisant un nom de registre d'indice, un numéro de registre d'indice. Il faut préciser que les registres d'indice ont une taille bien plus petite que l'accumulateur. Ils mémorisent des indices codés sur 16 bits ou moins, alors que l'accumulateur faisait typiquement 36 à 48 bits, parfois plus. La taille classique sur les anciens ''mainframes'' était de 15 bits, parfois moins. Il n'était pas rare de tomber sur des registres d'indice de 8 ou 9 bits. Leur petite taille rendait leur implémentation matérielle peu couteuse. Et c'est ce qui explique qu'ils étaient préférés à l'usage d'un second accumulateur. Un exemple est le cas du processeur Motorola 6809, un processeur à accumulateur qui contient deux registres d'indices nommés X et Y. L'accumulateur est noté D et fait 16 bits, il peut être parfois géré comme deux accumulateurs séparés A et B de 8 bits chacun. Il contenait aussi deux pointeurs de pile, l'un pour les programmes, l'autre pour le système d'exploitation, ainsi qu'un ''program counter''. Le registre de page était utilisé pour l'adressage absolu, comme vu dans le chapitre sur les modes d'adressage. [[File:6809 Internal Registers.svg|centre|vignette|upright=2|6809 Internal Registers]] Les processeurs IBM avaient autrefois plusieurs registres d'indice. Par exemple, l'IBM 704 avait trois registres d'indice de 15 bits. Leur contenu était soustrait de l'adresse absolue. Une instruction pouvait utiliser plusieurs registres d'indice pour adresser son opérande. Toute instruction utilisait trois bits pour sélectionner les registres d'indice utilisés. Fait assez original, lorsque plusieurs registres d'indice sont sélectionnés, le processeur n'additionne pas les trois registres à l'adresse de base. À la place, il fait un OU bit à bit entre les registres d'indice sélectionnés, et additionne le résultat à l'adresse. Les processeurs IBM à accumulateur ont fait ça sur toute la gamme IBM 700/7000, pour des raisons de compatibilité. Les processeurs suivants avaient 7 registres d'indices, mais conservaient les trois bits pour adresser les registres d'indices. Ils pouvaient fonctionner dans deux modes. Le premier mode est plus intuitif : les trois bits précisent un registre d'indice parmi les 7, qui est additionné avec l'adresse absolue. La valeur zéro indique qu'aucun registre d'indice n'est utilisé, ce qui explique qu'il y a 7 registres d'indice et non 8. Un second mode, compatible avec l'IBM 704, fait un OU logique entre les registres d'indice sélectionnés. Seuls les trois premiers registres d'indices peuvent être sélectionnés dans ce mode. Il y a deux instructions pour changer de mode : une pour passer en mode compatible, l'autre pour le quitter pour l'autre mode. Quelques rares processeurs à registres généraux ont utilisés des registres d'indice, en plus des registres généraux. Ce qui fait l'association que nous avons faite entre registres d'indice et architectures à accumulateur est imparfait, bien que solide sur le principe. Un exemple d'architecture de ce type sont les architectures de la série UNIVAC 1100/2200. Ils disposaient de 128 registres, qui étaient mappés en mémoire à partir de l'adresse mémoire 0, la majorité étant inaccessibles par le programmeur. Ils regroupaient 12 registres accumulateurs, 11 registres d'indice et 4 registres hybrides qui pouvaient servir soit de registre d'indice, soit de registres accumulateurs. ===La micro-architecture des architectures à accumulateur avec registres d'indice=== La présence de registres d'indice modifie grandement l'implémentation du processeur. En effet, il faut rajouter un banc de registre pour les registres d'indice. Le banc de registre est monoport, car on a besoin de lire ou d'écrire un indice à la fois. Et il faut aussi potentiellement rajouter de quoi faire les calculs d'adresse. Deux solutions sont possibles : une ALU dédiée aux calculs d'adresse, une seule ALU pour toutes les opérations. Dans le premier cas, il y a une ALU séparée associée aux registres d'indice. L'ALU et les registres d'indice sont placés en sortie du séquenceur, en-dehors du chemin de données, la sortie de l'ALU est directement connectée au bus d'adresse. L'unité de calcul d'adresse peut être utilisée pour incrémenter le ''program counter''. Un défaut de cette approche est qu'elle ne gère pas l'adresse indirect à registre. [[File:Chemin de données sans support des pointeurs, avec adressage absolu indicé.png|centre|vignette|upright=2|Chemin de données sans support des pointeurs, avec adressage absolu indicé]] Une autre option utilise un bus interne, qui interconnecte tout le chemin de données. Dans sa version la plus simple, il est relié à l'accumulateur, l'unité de calcul, le banc de registre d'indice et le bus de données. Avec cette solution, l'ALU est utilisé à la fois pour calculer les adresses et pour les instructions de calcul. En reliant le bus interne au bus d'adresse à travers un multiplexeur, on gère naturellement les adressages indirects. [[File:Architecture à accumulateur avec registres associés.png|centre|vignette|upright=2.5|Architecture à accumulateur avec registres associés]] Il faut noter que sur les architectures Von Neumann, le séquenceur est relié à ce bus interne. En effet, charger une instruction demande de passer par le bus mémoire, donc par l’intermédiaire de ce bus internet. Le ''program counter'' est envoyé sur ce bus pour lire l'instruction, puis l'instruction lue est recopiée dans le registre d'instruction. Le chargement d'une instruction est donc géré comme une lecture des plus classiques. De plus, cela permet d'incrémenter le ''program counter'' au niveau de l'unité de calcul entière. Le ''program counter'' est envoyé sur le bus interne, incrémenté par l'ALU, puis le résultat est recopié dans le ''program counter'' via le bus interne. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] ==Les processeurs bi-accumulateurs : le Motorola 6800== Le Motorola 6800 était un processeur 8 bits qui gérait des adresses de 16 bits. Il contenait deux accumulateurs nommés A et B, de 8 bits chacun. Il disposait aussi d'un registre d'indice, d'un pointeur de pile et d'un ''program counter'', tous les trois de 16 bits. Le registre d'état regroupait 6 bits, qu'on ne détaillera pas ici. [[File:MC6800 Processor Diagram.png|centre|vignette|upright=2|Interface et registres du MC6800.]] La présence des deux accumulateurs impactait surtout les instructions dyadiques. Les instructions monadiques avaient juste à préciser où se trouvait l'opérande : soit en RAM, soit dans le premier accumulateur, soit dans le second. Pour les opérations dyadiques, la gestion était totalement différente. En théorie, le premier opérande est dans un accumulateur, soit A, soit B. La seconde opérande vient soit de l'autre accumulateur, soit de la mémoire RAM. Et selon les instructions, tout variait. Pour l'addition, il y avait trois instructions. Les deux premières additionnaient un opérande provenant de la mémoire avec un accumulateur. L'instruction ADDA sélectionnait le premier accumulateur, l'instruction ADDB sélectionnait le second accumulateur. Mais une troisième instruction, l’instruction ABA, permettait d'additionner le contenu des deux accumulateurs. Pour les autres opérations, il n'était pas possible d'utiliser les deux accumulateurs en même temps. La seule possibilité était de faire une opération entre un accumulateur et un opérande venant de la mémoire. Toutes les instructions étaient en double, avec une copie par accumulateur. Par exemple, l'instruction ANDA faisait un ET entre l’accumulateur A et l'opérande mémoire, l'instruction ANDB faisait pareil avec l'accumulateur B. ==Les architectures hybrides registres-accumulateur== Il a existé quelques architectures qui étaient des hybrides entre architectures à accumulateur et architecture à registre. Elles ont servi de transition entre les deux, durant les années 80-90. Elles avaient un accumulateur unique couplé à un banc de registres généraux. Par exemple, les premiers processeurs Intel 8 bits étaient des processeurs hybrides-accumulateur. Lles CPU Intel 8 bits disposaient de 7 registres de 8 bits nommés A, B, C, D, E, F, H, L, SP. Ils correspondent respectivement à : * l'accumulateur A ; * six registres nommés B, C, D, E, H et L ; * le registre d'état F ; * le pointeur de pile SP. Sur ces processeurs, les instructions dyadiques devaient mettre leur premier opérande dans l'accumulateur, la seconde provenait soit des registres, soit de la RAM, soit d'une constante immédiate. Les opérations monadiques pouvaient lire leur opérande depuis l'accumulateur, les autres registres ou la RAM, tout était permis. Les registres d'indices disparaissaient sur ces architectures, en théorie. Les registres généraux pouvaient être utilisés comme registre d'indice ou pour stocker des opérandes, ils étaient assez versatiles pour servir de registres d'indices. La présence de registres a de nombreux avantages, comparé aux architectures à accumulateur pures. Les instructions arithmétiques sont plus rapide, lire un registre étant plus rapide qu'un accès RAM. Les performances sont donc augmentées. De plus, les instructions arithmétiques utilisant ces registres sont plus courtes : pas besoin d'encoder une adresse mémoire, un nom de registre suffit. Vu que les processeurs de l’époque avaient des instructions de taille variable, cela améliorait la densité de code. La microarchitecture de ces processeurs est très similaire à celle d'un processeur avec des registres d'indices. La seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Le banc de registre est systématiquement monoport, car il n'avait aucune raison d'être multiport. Pour les instructions dyadiques, seules à lire deux opérandes, il ne servait que pour la seconde opérande, la première était lue depuis l'accumulateur. Les processeurs hybrides registre-accumulateur se classent en deux types principaux : ceux qui ont un seul bus interne, et ceux qui en ont deux. Le premier cas est identique à celui vu précédemment pour les architectures à accumulateur avec registres d'indice, à la seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Afin de gérer l'adressage indirect à registre, le bus interne est connecté aux deux registres d’interfaçage mémoire. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] Notons que cela permet aussi d'implémenter facilement les branchements indirects, car le bus interne permet d'échanger des adresses entre ''program counter'' et banc de registre. De même, il est possible d'utiliser l'ALU pour gérer les branchements indirects., en plus de l'utiliser pour incrémenter le ''program counter''. [[File:Single bus organization.jpg|centre|vignette|upright=2|Single bus organization]] Une autre solution utilisait deux bus internes : un connecté au bus de données, un autre relié au bus d'adresse. Le bus de commande mémoire était lui commandé par le séquenceur, l'unité de contrôle. L'intermédiaire entre ces deux bus était le banc de registre, ainsi que les autres registres. Le banc de registre était connecté aux deux bus interne, avec un port de lecture relié au bus d'adresse, un port de lecture-écriture relié au bus de données. Le port de lecture était utilisé pour l'adressage indirect, l'autre l'était pour le reste. [[File:Proz1-e.png|centre|vignette|upright=2|Intérieur d'un processeur.]] L'organisation à deux bus simplifiait la gestion du ''program counter'' et le chargement des instructions. Le ''program counter'' était soit séparé du banc de registre, soit placé dans le banc de registre. Les deux solutions étaient utilisés, tout dépend du processeur. Il faut noter que si le ''program counter'' est intégré au banc de registres, alors la microarchitecture du processeur est bien plus simple. L'envoi du ''program counter'' sur le bus d'adresse utilise le port de lecture relié au bus d'adresse, qui sert aussi pour l'adressage indirect. L'économie de circuits, sans compter la simplicité d'implémentation que cela implique, explique sans doute que la technique a été utilisée sur quelques processeurs anciens. Le ''program counter'' était généralement incrémenté par l'ALU, ce qui explique qu'il soit connecté au bus interne pour les données. La connexion est aussi utile pour gérer les branchements indirects, qui copient un registre dans le ''program counter'', ainsi que les branchements relatifs (addition dans l'ALU), voire les branchements directs (l'adresse vers laquelle brancher est envoyée en entrée de l'ALU et propagée en sortie avec une opération ''pass through''). [[File:Connexion du program counter sur les bus avec PC dans le banc de registres.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC dans le banc de registres]] ===Les registres d'interruption avec un processeur hybride-accumulateur : l'exemple du Z80=== Un exemple de processeur registre-accumulateur à deux bus interne est le Z80, un processeur fortement inspiré des CPU Intel 8 bits. Il a un jeu d'instruction similaire, mais a diverses améliorations par rapport au design original. Notamment, le processeur a des registres séparés pour les interruptions. Sur le Z80, les registres généraux sont dupliqués avec 6 registres pour les interruptions et 6 registres pour les programmes autres. Leur copie pour les interruptions sont nommées B', C', D', E', H', L'. Les 12 registres sont placés dans le banc de registre, ce qui implique que le fenêtrage de registres est utilisé pour gérer la séparation entre registre d'interruption et normaux. Il faut noter que l'accumulateur et le registre d'état sont aussi dupliqués, leurs copies étant nommées A' et F'. Mais leur duplication se fait autrement que par fenêtrage de registre. En plus des registres précédents, le Z80 incorporait deux registres d'indice nommés X et Y, ainsi qu'un pointeur de pile SP et un ''program counter'' PC. Ils n'étaient pas dupliqués pour les interruptions. Les registres d'indice étaient reliés à une unité de calcul d'adresse. L'unité de calcul d'adresse prenait deux opérandes : un indice, et une adresse mémoire provenant soit du banc de registre, soit de l'accumulateur. En clair, l'unité de calcul d'adresse faisait le lien entre les deux bus internet : le bus de données interne en entrée, le bus d'adresse en sortie. À l'intérieur du processeur, tous les registres étaient regroupés dans un banc de registre unique, sauf les accumulateurs, les registres d'état et le ''program counter''. Bien que ce ne soit pas indiqué sur le schéma ci-dessous, le ''program counter'' est séparé du banc de registre, alors que le pointeur de pile est dedans. Le compteur IR est lui associé au ''program counter'', il est sortit du banc de registre. Le Z80 utilise lui aussi un incrémenteur séparé de l'ALU, qui est utilisé pour mettre à jour le ''program counter'', le pointeur de pile et un compteur de rafraichissement mémoire nommé IR sur le Z80 (pour rappel, le rafraichissement mémoire demande de balayer la mémoire d'adresse en adresse et été fait par le CPU à l'époque). De plus, il est utilisé pour les instructions INC et DEC qui incrémentent une opérande de 16 bits obtenue en combinant deux registres de 8 bits. En clair, l'incrémenteur du ''program counter'' a été réutilisé de beaucoup de manières originales. [[File:Z80 arch.svg|centre|vignette|upright=3|Microarchitecture du Z80.]] Le Z80 incorporait des instructions pour échanger le contenu des deux ensembles de registres, accumulateur inclus. Elles permettaient d'utiliser les registres d'interruption pour les programmes et réciproquement. En clair, cela doublait le nombre de registres si les interruptions n'étaient pas utilisées. * L'instruction EXX échangeait les deux fenêtres de registres généraux : les registres B, C, D, E, H et L devenaient les registres B', C', D', E', H' et L' et inversement. * L'instruction EX échangeait l'accumulateur et le registre d'état : les registres A,F devenait A',F' et inversement. Le fenêtrage de registre était modifié par l'instruction EXX, qui échangeait les deux fenêtres de registres. Pour l'implémenter, une bascule était ajouté au processeur, appelons-la la bascule INT. Elle était relié au bus d'adresse du banc de registre, dont elle mémorisait le bit de poids fort. L'instruction EXX inversait la valeur de la bascule INT. Il est aussi possible d'échanger le contenu des registres D,E et H,L avec une instruction dédiée, ce qui est là encore fait par deux bascules : une pour les registres D,E et une autre pour les registres H,L. Pour l'accumulateur et le registre d'état, le choix entre registre normal et registre d'interruption se faisait là encore par une seconde bascule appelée la bascule A. La bascule est reliée à un multiplexeur et un démultiplexeur, qui permet de choisir quel accumulateur relier à l'unité de calcul. L'instruction EX inverse le contenu de la bascule A. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=L'unité de contrôle | prevText=L'unité de contrôle | next=Les processeurs 8 bits et moins | nextText=Les processeurs 8 bits et moins }} </noinclude> c9jpmym0n02uha90k07zneksnouwt1x 744176 744160 2025-06-05T17:24:15Z Mewtow 31375 /* Les architectures hybrides registres-accumulateur */ 744176 wikitext text/x-wiki Les architectures que nous avons vu précédemment dans ce cours disposent de registres pour les données, en plus du pointeur de pile, d'un ''program counter'', et de quelques autres. Elles sont appelées des '''architectures à registres''', terme qui trahit bien le fait qu'elles ont des registres généraux ou spécialisés pour stocker temporairement des données. Et si on leur a donné un nom, c'est parce qu'il existe des architectures qui ne sont pas dans cette catégorie. Il en existe plusieurs types, mais ce chapitre va se concentrer sur les '''architectures à accumulateur'''. [[File:Isaccumulator.png|vignette|Architecture à accumulateur.]] Les architectures à accumulateur sont centrées autour d'un registre architectural appelé l''''accumulateur'''. Il est utilisé pour toutes les opérations arithmétiques dyadiques, où il sert à la fois de source et de destination. Toutes les instructions dyadiques sont de type ''load-op'' : une opérande est lue depuis l'accumulateur, le second opérande est lu depuis la mémoire RAM, le résultat de l'instruction est automatiquement mémorisé dans l'accumulateur. Les instructions monadiques peuvent utiliser un opérande dans l'accumulateur, ou dans la mémoire RAM, les deux sont théoriquement possibles. La conséquence est que le nombre d'accès mémoire est drastiquement diminué : de 3 par instructions sur une architecture mémoire-mémoire, on passe à seulement un avec un accumulateur. Les opérations dyadiques ont besoin d'un seul accès mémoire pour lire la seconde opérande, les opérations monadique en font aussi un seul pour lire leur unique opérande. {|class="wikitable" |- ! Classe d'architecture ! Nombre d'accès mémoire par opération dyadique |- |- ! Architecture à accumulateur | Un accès mémoire par instruction, pour lire la seconde opérande |- ! Architecture à registres | Zéro si les opérandes sont dans les registres, un pour les opérations ''load-op'', LOAD et STORE. |} ==Le jeu d'instruction des architectures à accumulateur sans registres d'indice== L'accumulateur est adressé grâce au mode d'adressage implicite, de même que le résultat de l'opération. Par contre, les autres opérandes sont localisés avec d'autres modes d'adressage, et lues en mémoire RAM. Le résultat ainsi qu'un des opérandes sont adressés de façon implicite car dans l'accumulateur, seule la seconde opérande étant adressée directement. Grâce à l'accumulateur, une instruction ne fait qu'un seul accès mémoire maximum, ce qui rend le processeur très facile à implémenter. ===Les registres des anciennes architectures à accumulateur=== [[File:IBM 701console.jpg|vignette|IBM 701, console extérieure.]] Les architectures à accumulateur étaient communes dans les années 50-60. A l'époque, les ordinateurs étaient gigantesques, ils prenaient une pièce de bâtiment entière dans le pire des cas, une armoire entière dans le meilleur. Les ordinateurs de l'époque étaient surtout utilisés pour du calcul scientifique ou des tâches d’ingénierie demandant beaucoup de calcul, rarement pour de la compatibilité. Les nombres flottants n'étaient pas encore apparus. A la place, les ordinateurs de l'époque géraient des nombres entiers de grande taille, de 30 bits ou plus. En conséquence, l'accumulateur faisait facilement 30 à 60 bits. Par exemple, les ordinateurs de la Série scientifique IBM 700/7000 géraient des entiers de 36 bits, l’accumulateur faisait 38 bits : 36 bits plus deux bits pour les débordements. Au passage, de tels processeurs utilisaient l'adressage par mot, et non par byte. Historiquement, les premières architectures à accumulateur ne contenaient aucun autre registre que l'accumulateur. Ce n'est que dans les années 60 que de nombreuses architectures à accumulateur ont ajouté un second '''registre pour les multiplication/divisions'''. Un exemple est celui de l'IBM 701, qui incorporait un registre accumulateur de 38 bits et un registre multiplieur de 36 bits. Le registre mémorise le multiplieur lors d'une opération de multiplication. Il mémorise donc un opérande, pas le résultat. Il peut aussi décaler le multiplieur vers la droite/gauche, ce qui est utile pour exécuter la multiplication. C'est ce qui est fait sur l'IBM 7094. Une autre possibilité est que ce registre mémorise une partie du résultat de l'opération. Pour rappel, le résultat d'une multiplication/division est codé sur deux fois de bits que ses opérandes. Par exemple, multipliez deux opérandes de 30 bits, vous obtiendrez un résultat de 60 bits. Les 30 bits de poids faible du résultat vont dans l'accumulateur, les 30 bits de poids fort vont dans ce second registre. Les architectures à accumulateur parfois un '''registre pour le pointeur de pile''', utilisé pour gérer les fonctions/procédures. Les architectures à accumulateurs supportaient une pile d'adresse de retour, souvent une pile d'appel. Mais pour cela, il fallait mémoriser le pointeur de pile dans le processeur, ce qui demandait un registre dédié. ===L'adressage indirect avec l'accumulateur=== Les instructions LOAD et STORE existent bel et bien sur les architectures à accumulateur, mais n'ont pas les mêmes modes d'adressages. L'instruction LOAD copie une donnée de la RAM vers l'accumulateur, l'instruction STORE copie l'accumulateur dans une adresse. Les deux instructions n'ont pas besoin d'adresser l'accumulateur, qui est adressé de manière implicite, juste de préciser l'adresse à lire/écrire. Les architectures à accumulateur supportaient souvent le mode d'adressage indirect mémoire. Un exemple est celui des ordinateurs Data General Nova, qui sont des architectures à accumulateur et qui supportaient ce mode d'adressage. Les deux instructions LOAD et STORE existaient en deux versions, distinguées par un bit d'indirection. Si ce bit est à 0 dans l'opcode, alors l'instruction utilise le mode d'adressage absolu normal : l'adresse intégrée dans l'instruction est celle de la donnée. Mais s'il est à 1, alors l'adresse intégrée dans l'instruction est celle du pointeur. Cependant, la présence de l'accumulateur permettait d'utiliser l'adressage indirect à registre, pour gérer les pointeurs. Pour rappel, avec le mode d'adressage indirect à registre, l'adresse à lire/écrire est dans un registre. Ici, l'adresse à lire/écrire est prise dans l'accumulateur, seul registre disponible pour. L'adressage indirect est plus simple à implémenter pour l'instruction LOAD, car elle prend un seul opérande : l'adresse à lire. L'adresse à lire est placée dans l'accumulateur, la donnée lue est elle aussi chargée dans l'accumulateur. Pour l'instruction STORE, il faut fournir deux opérandes, l'adresse et la donnée à écrire, ce qui peut poser problème. Mais au pire, il est toujours possible d'utiliser l'adressage absolu ou indirect mémoire : l'adresse est dans l'instruction, la donnée à écrire dans l'accumulateur. ===L'encodage des instructions=== Sur une architecture à accumulateur l'encodage d'une instruction dyadique est assez simple, vu que l'accumulateur est adressé implicitement. La seconde opérande est localisée soit par une adresse mémoire (adressage absolu), soit est une constante (adressage immédiat). L'adresse mémoire est généralement assez longue, plus que l'opcode. {|class="wikitable" |+ Encodage d'une instruction dyadique |- ! rowspan="2" | Opcode | Adresse mémoire (adressage absolu) |- | Constante (adressage immédiat) |} L'encodage d'une instruction monadique est similaire. Si l'opérande est lue depuis la mémoire RAM, alors l'instruction est encodée comme une instruction dyadique. Il en est de même pour les instructions qui copient une constante dans l'accumulateur. Par contre, si l'opérande est dans l'accumulateur, alors il y a juste besoin d'encoder l'opcode. La majorité des instructions a besoin de préciser une adresse, rares sont celles qui s'en passent. Au vu de cet encodage, les architectures à accumulateur sont qualifiées d''''architectures à une adresse''' par abus de langage. Il est intéressant de contraster leur encodage avec les architectures à registres. Les architectures à registre doivent encoder deux opérandes en plus de l'opcode, avec éventuellement où enregistrer le résultat sur les architectures 3-adresses. Par contre, les opérandes sont généralement des noms de registre, ce qui prend moins de place qu'une adresse mémoire. A la rigueur, les instructions avec une constante immédiate prennent un peu plus de place, car elles doivent encoder un nom de registre en plus de la constante et de l'opcode. Les instructions ''load-op'' des processeurs CISC sont un peu dans le même cas, sauf qu'il faut remplacer la constante par une adresse, qui a généralement la même taille. Les instructions sont donc en moyenne plus courte sur les processeurs à registre, du fait de la présence de registres. ===Annexe : les toutes premières architectures à accumulateur : le Manchester Baby=== [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] Les architectures à accumulateurs sont apparues dès les débuts de l'informatique. Le tout premier ordinateur à programme enregistré en mémoire, le ''Manchester Baby'', était une architecture à accumulateur. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 adresses, fabriquée avec des tubes Williams (abordés dans une annexe à la fin du cours). Chaque adresse mémorisait 32 bits, qui pouvaient encoder soit un nombre, soit une instruction. Le programme devait tenir dans la RAM, avec une instruction par adresse maximum, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 bits d'adresse servait à indiquer où se trouvent la seconde opérande en RAM, les 16 restants sont inutilisés. En théorie, les 12 bits d'adresse permettaient d'adresser 4096 adresses, mais seules 32 étaient réellement présentes. Le processeur avait un registre accumulateur de 32 bits, un ''program counter'' et un registre d'instruction. Il intégrait un additionneur dédié au ''program counter'', mais l'ALU n'avait pas d'additionneur. En conséquence, il ne gérait pas l'addition. A la place, il gérait la soustraction. Il pouvait cependant émuler l'addition à partir d'une soustraction. La soustraction était utilisée pour calculer le complément d'une opérande, et soustraire le complément revient à additionner. L'ALU était une ALU sérielle, à savoir qu'elle faisait les soustractions bit par bit. Le processeur supportait 7 instructions au total : la soustraction, des instructions de branchement et d'accès mémoire, rien d'autre. Les instructions de branchement utilisaient des modes d'adressage très particuliers, qu'on ne retrouve pas sur les ordinateurs modernes. Les branchements inconditionnels utilisaient une forme d'adressage mémoire indirect, pas les adressages usuels pour les branchements. Il n'y avait pas de branchements conditionnels, mais une ''SKIP instruction''. {|class="wikitable" |- ! SUB | Soustrait l'opérande mémoire de l'accumulateur. |- ! CMP | Skippe l'instruction suivante si l'accumulateur a une valeur négative. |- ! JMP | Branchement indirect mémoire. : * L'adresse de destination est lue depuis la mémoire. * L'adresse lue est intégrée dans l'instruction via adressage absolu. |- ! JRP | Branchement relatif indirect. * Lit une opérande depuis la mémoire, l'adresse est intégrée dans l'instruction via adressage absolu. * Additionne l'opérande lue au ''program counter''. |- ! LDN | Instruction LOAD. La donnée lue est inversée lors de la lecture, l'accumulateur contient le complément à deux de la donnée lue après la lecture. |- ! STO | Instruction STORE |- ! STOP | Éteint l'ordinateur. |} Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. Le Manchester Baby était un prototype, mais il avait été pensé pour être étendu, notamment afin d'avoir plus de mémoire. C'est pour cela que ses adresses étaient codées sur 12 bits, malgré sa mémoire de seulement 32 mots. Le plan initial, à savoir utiliser une RAM de 4096 mots, a cependant été abandonné pour la Manchester Mark 1. A la place, la RAM a gardé la même taille, à savoir 32 nombres, mais a été complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique. Le tambour magnétique contenait 40 pages, chacune ayant la même taille que la RAM. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. Le processeur gérait maintenant l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. De plus, il intégrait deux registres dédiés aux multiplications : un pour le multiplicande, un autre pour le multiplieur. Ils étaient nommés D et R et étaient regroupés dans un seul tube Williams noté M. Cependant, les multiplications étaient réalisées en enchainant une série d'additions, dans l'additionneur-soustracteur. C'était là encore une architecture à accumulateur, sauf qu'elle intégrait aussi des registres d'indice. Les registres d'indices étaient au nom de deux et étaient notés B0 et B1. Lors du chargement d'une instruction, un registre d'indice était sélectionné grâce à un bit de l'instruction. Le contenu de ce registre d'indice était additionné à l'instruction , l'adresse encodée dedans pour être précis, et le résultat était envoyé sur le bus mémoire. La microarchitecture de la machine est illustrée ci-dessous. Elle a une ALU unique capable de faire plusieurs opérations, qui sont représentées dans des rectangles séparés. Les cercles dans le schéma suivant sont des tubes Williams, des écrans CRT modifiés de manière à servir de mémoire DRAM, dont le fonctionnement est détaillée dans le chapitre sur les mémoires historiques. Un tube Williams implémente un banc de registre complet, c'est à dire un groupe de 2 à 10, registres. L'accumulateur est noté A, les deux registres de multiplication sont regroupés dans le tube Williams M, les registres d'indice sont dans le tube noté B. Le tube Williams C regroupe le ''program counter'' et le registre d'instruction. L'additionneur sert à incrémenter le ''program counter'', mais aussi pour les branchements relatifs. La statistation est le nom donné au séquenceur, à l'unité de contrôle, décodeur d'instruction inclus. [[File:MM1Schematic French.svg|centre|vignette|upright=2.5|Architecture de la Manchester Mark 1.]] ==La micro-architecture des architectures à accumulateur sans registres d'indice== L'organisation interne d'une architecture à accumulateur est très différente de celle des processeurs à registre. Elle est plus ou moins la même pour tous ces processeurs, le point important étant que le chemin de données se résume à une ALU, un registre accumulateur et le bus de données. L'ALU est reliée au registre accumulateur, ainsi qu'au bus de données pour lire la seconde opérande, comme illustré ci-dessous. [[File:Accumulator.png|centre|vignette|upright=2|Accumulateur.]] ===L'unité de calcul et l'accumulateur=== Pour simplifier l'implémentation, le résultat est mémorisé dans un registre en sortie de l'unité de calcul. La raison est qu'on ne veut pas altérer l'accumulateur tant que le résultat final n'est pas totalement calculé. Rappelons que l'ALU ne fournit pas un résultat d'un seul bloc, mais que certains bits arrivent avant les autres, typiquement les bits de poids faible. Si le résultat était écrit dans l'accumulateur directement, il écraserait des bits de l’opérande en cours d'utilisation, ce qui fausserait le résultat. [[File:Accumulateur avec registre de sortie.png|centre|vignette|upright=2|Accumulateur avec registre de sortie]] Une autre solution utilisait un registre entre l'accumulateur et l'unité de calcul, appelé l’'''''accumulator latch'''''. Il remplace le registre en sortie de l'ALU, dans le sens où il permet d'écrire dans l'accumulateur sans effacer l'opérande, pendant que l’opération est en cours dans l'ALU. L'accumulateur est copié dans l’''accumulator latch'', avant que l'ALU démarre ses calculs. L'opérande est donc maintenue même si on commence à écrire le résultat dans l'accumulateur. Sur le 8085 d'Intel, l’''accumulator latch'' peut être initialisé avec une constante prédéfinie, ce qui permet d'implémenter certaines instructions très facilement. Par exemple, il peut être initialisé à 0, ce qui permet d'implémenter les instructions MOV et INC (incrémentation). Un MOV est équivalent à faire un OU entre le registre lu et 0. Une instruction INC initialise l'entrée de retenue de l'unité de calcul à 1, puis ajoute 0. La décrémentation est implémentée de la même manière, sauf que l’''accumulator latch'' est initialisé à -2 pour compenser l'entrée de retenue à 1. De plus, pour supporter les conversion de décimal à BCD, l’''accumulator latch'' peut être initialisé avec les constantes 0x00, 0x06, 0x60, or 0x66. L'''accumulator latch'' est relié à divers fils de commande provenant de l'unité de contrôle, qui décide quelle valeur d'initialisation utiliser en fonction de l'instruction décodée. [[File:Accumulator latch.png|centre|vignette|upright=2|Accumulator latch]] [[File:Chemin de données à un seul bus.png|vignette|Chemin de données à un seul bus]] De même, la seconde opérande, celle lue sur le bus de données, est mémorisée dans un registre en amont de l'ALU. C'était notamment très utile si le processeur utilisait une ALU plus courte que les opérandes, avec par exemple une ALU 4 bits pour un CPU 8 bits. Les anciens processeurs à accumulateur de type ''mainframe'' utilisaient des opérandes de grande taille, du genre 36 ou 48 bits, ce qui avait des conséquences sur l'unité de calcul utilisée, ainsi que sur la communication avec la mémoire. Il arrivait que de tels processeurs utilisaient des ALU sérielles, ou du moins octet-sérielles, plutôt qu'une véritable ALU 36 bits. Nous verrons aussi que c'est très utile sur les processeurs à accumulateur avec un bus interne unique, dans la suite du chapitre. ===La micro-architecture des architectures à accumulateur avec instructions LOAD/STORE=== Nous venons de voir comment est implémenté l'unité de calcul et l'accumulateur, et comment le tout est relié au bus de données. Mais cela ne permet que d'avoir un processeur à accumulateur rudimentaire, qui ne gére que des instructions arithmétiques et logiques. Il faut aussi gérer le cas des opérations LOAD/STORE et des modes d'adressages associés, mais c'est le séquenceur qui s'en occupe. Avec l'adressage absolu, les instructions LOAD et STORE ne font que connecter l'accumulateur au bus de données. L'instruction STORE nécessite de connecter l'accumulateur au bus de données, de manière à ce que le transfert des données se fasse de l'accumulateur vers le bus de données. L'instruction LOAD s'implémente de la même manière, sauf que le sens de transfert est inversé. Cependant, il existe une optimisation qui permet d'implémenter l'instruction LOAD sans ajouter de circuits. Pour cela, il suffit que l'unité de calcul gére les opérations ''pass through'', à savoir des opérations qui se contentent de recopier un opérande sur la sortie. Ici, l'idée est de recopier l'opérande provenant du bus de données. [[File:Architecture à accumulateur, microarchitecture.png|centre|vignette|upright=2|Architecture à accumulateur, microarchitecture]] Pour gérer nativement l'adressage indirect à registre, il suffit de connecter l'accumulateur au bus d'adresse. Le plus simple est d'ajouter un multiplexeur, comme illustré ci-dessous. La donnée lue est copiée dans l'accumulateur, ce qui fait qu'il vaut mieux utiliser un registre d’interfaçage, l'accumulateur n'étant pas utilisable à la fois pour le bus d'adresse et de données. [[File:Adressage indirect sur une architecture à accumulateur.png|centre|vignette|upright=2|Adressage indirect sur une architecture à accumulateur]] Pour finir, voyons comment le pointeur de pile et le ''program counter'' sont implémentés. Les architectures à accumulateur ont souvent des adresses de taille différente des données, ce qui fait qu'il vaut mieux utiliser un circuit incrémenteur dédié pour incrémenter le ''program counter'', plutôt que de l'incrémenter via l'unité de calcul. Les architectures à accumulateur ont parfois un pointeur de pile, qui gère une pile d'adresse de retour, pas une vraie pile d'appel. Aussi, le pointeur de pile est censé être incrémenté et décrémenté, pas plus. Pas d'addition ou de soustraction pour gérer des cadres de pile. Là encore, c'est la solution de l'incrémenteur séparé qui est retenue. Pour économiser des transistors, il n'y a qu'un seul incrémenteur partagé pour les deux. ==Les architectures à accumulateur à registres d'indice== Les architectures à accumulateur décrites dans la section précédente sont capables de faire de l'adressage indirect, mais n'incluent pas les modes d'adressage base + indice et absolus indicés, qui prennent une adresse et y ajoute un indice. Il s'agit des toutes premières architectures à accumulateur, comme les premiers ordinateurs IBM ou le fameux PDP-8. Mais par la suite, les processeurs à accumulateurs ont inclus un support des modes d'adressages indicés, grâce à des '''registres d'indice'''. ===Les registres d'indice=== Les registres d'indice stockent des indices de tableaux. Ils permettaient de supporter deux modes d'adressage : * Le '''mode d'adressage absolu indicé''' où une adresse fixe est additionnée à un indice variable. L'adresse fixe est intégrée dans l'instruction (adressage absolu), l'indice est dans un registre d'indice. * Le '''mode d'adressage base + indice''', où l'adresse est dans l'accumulateur et l'indice dans le registre d'indice. Les processeurs à accumulateur supportaient souvent des variantes des modes d'adressage précédents, où le registre d'indice était automatiquement incrémenté ou décrémenté à chaque utilisation. Au départ, ces processeurs n'utilisaient qu'un seul registre d'indice qui se comportait comme un second accumulateur spécialisé dans les calculs d'adresses mémoire. Le processeur supportait de nouvelles instructions qui utilisaient ce registre d'indice de façon implicite. Mais avec le temps, les processeurs finirent par incorporer plusieurs de ces registres. Les instructions de lecture ou d'écriture devaient alors préciser quel registre d'indice utiliser, en précisant un nom de registre d'indice, un numéro de registre d'indice. Il faut préciser que les registres d'indice ont une taille bien plus petite que l'accumulateur. Ils mémorisent des indices codés sur 16 bits ou moins, alors que l'accumulateur faisait typiquement 36 à 48 bits, parfois plus. La taille classique sur les anciens ''mainframes'' était de 15 bits, parfois moins. Il n'était pas rare de tomber sur des registres d'indice de 8 ou 9 bits. Leur petite taille rendait leur implémentation matérielle peu couteuse. Et c'est ce qui explique qu'ils étaient préférés à l'usage d'un second accumulateur. Un exemple est le cas du processeur Motorola 6809, un processeur à accumulateur qui contient deux registres d'indices nommés X et Y. L'accumulateur est noté D et fait 16 bits, il peut être parfois géré comme deux accumulateurs séparés A et B de 8 bits chacun. Il contenait aussi deux pointeurs de pile, l'un pour les programmes, l'autre pour le système d'exploitation, ainsi qu'un ''program counter''. Le registre de page était utilisé pour l'adressage absolu, comme vu dans le chapitre sur les modes d'adressage. [[File:6809 Internal Registers.svg|centre|vignette|upright=2|6809 Internal Registers]] Les processeurs IBM avaient autrefois plusieurs registres d'indice. Par exemple, l'IBM 704 avait trois registres d'indice de 15 bits. Leur contenu était soustrait de l'adresse absolue. Une instruction pouvait utiliser plusieurs registres d'indice pour adresser son opérande. Toute instruction utilisait trois bits pour sélectionner les registres d'indice utilisés. Fait assez original, lorsque plusieurs registres d'indice sont sélectionnés, le processeur n'additionne pas les trois registres à l'adresse de base. À la place, il fait un OU bit à bit entre les registres d'indice sélectionnés, et additionne le résultat à l'adresse. Les processeurs IBM à accumulateur ont fait ça sur toute la gamme IBM 700/7000, pour des raisons de compatibilité. Les processeurs suivants avaient 7 registres d'indices, mais conservaient les trois bits pour adresser les registres d'indices. Ils pouvaient fonctionner dans deux modes. Le premier mode est plus intuitif : les trois bits précisent un registre d'indice parmi les 7, qui est additionné avec l'adresse absolue. La valeur zéro indique qu'aucun registre d'indice n'est utilisé, ce qui explique qu'il y a 7 registres d'indice et non 8. Un second mode, compatible avec l'IBM 704, fait un OU logique entre les registres d'indice sélectionnés. Seuls les trois premiers registres d'indices peuvent être sélectionnés dans ce mode. Il y a deux instructions pour changer de mode : une pour passer en mode compatible, l'autre pour le quitter pour l'autre mode. Quelques rares processeurs à registres généraux ont utilisés des registres d'indice, en plus des registres généraux. Ce qui fait l'association que nous avons faite entre registres d'indice et architectures à accumulateur est imparfait, bien que solide sur le principe. Un exemple d'architecture de ce type sont les architectures de la série UNIVAC 1100/2200. Ils disposaient de 128 registres, qui étaient mappés en mémoire à partir de l'adresse mémoire 0, la majorité étant inaccessibles par le programmeur. Ils regroupaient 12 registres accumulateurs, 11 registres d'indice et 4 registres hybrides qui pouvaient servir soit de registre d'indice, soit de registres accumulateurs. ===La micro-architecture des architectures à accumulateur avec registres d'indice=== La présence de registres d'indice modifie grandement l'implémentation du processeur. En effet, il faut rajouter un banc de registre pour les registres d'indice. Le banc de registre est monoport, car on a besoin de lire ou d'écrire un indice à la fois. Et il faut aussi potentiellement rajouter de quoi faire les calculs d'adresse. Deux solutions sont possibles : une ALU dédiée aux calculs d'adresse, une seule ALU pour toutes les opérations. Dans le premier cas, il y a une ALU séparée associée aux registres d'indice. L'ALU et les registres d'indice sont placés en sortie du séquenceur, en-dehors du chemin de données, la sortie de l'ALU est directement connectée au bus d'adresse. L'unité de calcul d'adresse peut être utilisée pour incrémenter le ''program counter''. Un défaut de cette approche est qu'elle ne gère pas l'adresse indirect à registre. [[File:Chemin de données sans support des pointeurs, avec adressage absolu indicé.png|centre|vignette|upright=2|Chemin de données sans support des pointeurs, avec adressage absolu indicé]] Une autre option utilise un bus interne, qui interconnecte tout le chemin de données. Dans sa version la plus simple, il est relié à l'accumulateur, l'unité de calcul, le banc de registre d'indice et le bus de données. Avec cette solution, l'ALU est utilisé à la fois pour calculer les adresses et pour les instructions de calcul. En reliant le bus interne au bus d'adresse à travers un multiplexeur, on gère naturellement les adressages indirects. [[File:Architecture à accumulateur avec registres associés.png|centre|vignette|upright=2.5|Architecture à accumulateur avec registres associés]] Il faut noter que sur les architectures Von Neumann, le séquenceur est relié à ce bus interne. En effet, charger une instruction demande de passer par le bus mémoire, donc par l’intermédiaire de ce bus internet. Le ''program counter'' est envoyé sur ce bus pour lire l'instruction, puis l'instruction lue est recopiée dans le registre d'instruction. Le chargement d'une instruction est donc géré comme une lecture des plus classiques. De plus, cela permet d'incrémenter le ''program counter'' au niveau de l'unité de calcul entière. Le ''program counter'' est envoyé sur le bus interne, incrémenté par l'ALU, puis le résultat est recopié dans le ''program counter'' via le bus interne. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] ==Les processeurs bi-accumulateurs : le Motorola 6800== Le Motorola 6800 était un processeur 8 bits qui gérait des adresses de 16 bits. Il contenait deux accumulateurs nommés A et B, de 8 bits chacun. Il disposait aussi d'un registre d'indice, d'un pointeur de pile et d'un ''program counter'', tous les trois de 16 bits. Le registre d'état regroupait 6 bits, qu'on ne détaillera pas ici. [[File:MC6800 Processor Diagram.png|centre|vignette|upright=2|Interface et registres du MC6800.]] La présence des deux accumulateurs impactait surtout les instructions dyadiques. Les instructions monadiques avaient juste à préciser où se trouvait l'opérande : soit en RAM, soit dans le premier accumulateur, soit dans le second. Pour les opérations dyadiques, la gestion était totalement différente. En théorie, le premier opérande est dans un accumulateur, soit A, soit B. La seconde opérande vient soit de l'autre accumulateur, soit de la mémoire RAM. Et selon les instructions, tout variait. Pour l'addition, il y avait trois instructions. Les deux premières additionnaient un opérande provenant de la mémoire avec un accumulateur. L'instruction ADDA sélectionnait le premier accumulateur, l'instruction ADDB sélectionnait le second accumulateur. Mais une troisième instruction, l’instruction ABA, permettait d'additionner le contenu des deux accumulateurs. Pour les autres opérations, il n'était pas possible d'utiliser les deux accumulateurs en même temps. La seule possibilité était de faire une opération entre un accumulateur et un opérande venant de la mémoire. Toutes les instructions étaient en double, avec une copie par accumulateur. Par exemple, l'instruction ANDA faisait un ET entre l’accumulateur A et l'opérande mémoire, l'instruction ANDB faisait pareil avec l'accumulateur B. ==Les architectures hybrides registres-accumulateur== Il a existé quelques architectures qui étaient des hybrides entre architectures à accumulateur et architecture à registre. Elles sont apparues assez tôt, dès les années 50. Par exemple, le Bull Gamma 3 était un ordinateur de type ''mainframe'' qui disposait d'un accumulateur accompagné de registres généraux. Et c'était à une époque où les ordinateurs étaient intégralement construits avec des tubes à vides et autres mémoires spécialisées. Mais ces architectures sont restées assez confidentielles pendant les années 50 à 80. Par la suite, elles ont eu un regain de popularité durant les années 80-90. Elles ont alors servit de transition entre architectures à accumulateur proprement dites, et architectures à registres. Elles avaient un accumulateur unique couplé à un banc de registres généraux. Par exemple, les processeurs Intel 8 bits disposaient de 7 registres de 8 bits nommés A, B, C, D, E, F, H, L, SP. Ils correspondent respectivement à : * l'accumulateur A ; * six registres nommés B, C, D, E, H et L ; * le registre d'état F ; * le pointeur de pile SP. Sur ces processeurs, les instructions dyadiques devaient mettre leur premier opérande dans l'accumulateur, la seconde provenait soit des registres, soit de la RAM, soit d'une constante immédiate. Les opérations monadiques pouvaient lire leur opérande depuis l'accumulateur, les autres registres ou la RAM, tout était permis. Les registres d'indices disparaissaient sur ces architectures, en théorie. Les registres généraux pouvaient être utilisés comme registre d'indice ou pour stocker des opérandes, ils étaient assez versatiles pour servir de registres d'indices. La présence de registres a de nombreux avantages, comparé aux architectures à accumulateur pures. Les instructions arithmétiques sont plus rapide, lire un registre étant plus rapide qu'un accès RAM. Les performances sont donc augmentées. De plus, les instructions arithmétiques utilisant ces registres sont plus courtes : pas besoin d'encoder une adresse mémoire, un nom de registre suffit. Vu que les processeurs de l’époque avaient des instructions de taille variable, cela améliorait la densité de code. La microarchitecture de ces processeurs est très similaire à celle d'un processeur avec des registres d'indices. La seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Le banc de registre est systématiquement monoport, car il n'avait aucune raison d'être multiport. Pour les instructions dyadiques, seules à lire deux opérandes, il ne servait que pour la seconde opérande, la première était lue depuis l'accumulateur. Les processeurs hybrides registre-accumulateur se classent en deux types principaux : ceux qui ont un seul bus interne, et ceux qui en ont deux. Le premier cas est identique à celui vu précédemment pour les architectures à accumulateur avec registres d'indice, à la seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Afin de gérer l'adressage indirect à registre, le bus interne est connecté aux deux registres d’interfaçage mémoire. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] Notons que cela permet aussi d'implémenter facilement les branchements indirects, car le bus interne permet d'échanger des adresses entre ''program counter'' et banc de registre. De même, il est possible d'utiliser l'ALU pour gérer les branchements indirects., en plus de l'utiliser pour incrémenter le ''program counter''. [[File:Single bus organization.jpg|centre|vignette|upright=2|Single bus organization]] Une autre solution utilisait deux bus internes : un connecté au bus de données, un autre relié au bus d'adresse. Le bus de commande mémoire était lui commandé par le séquenceur, l'unité de contrôle. L'intermédiaire entre ces deux bus était le banc de registre, ainsi que les autres registres. Le banc de registre était connecté aux deux bus interne, avec un port de lecture relié au bus d'adresse, un port de lecture-écriture relié au bus de données. Le port de lecture était utilisé pour l'adressage indirect, l'autre l'était pour le reste. [[File:Proz1-e.png|centre|vignette|upright=2|Intérieur d'un processeur.]] L'organisation à deux bus simplifiait la gestion du ''program counter'' et le chargement des instructions. Le ''program counter'' était soit séparé du banc de registre, soit placé dans le banc de registre. Les deux solutions étaient utilisés, tout dépend du processeur. Il faut noter que si le ''program counter'' est intégré au banc de registres, alors la microarchitecture du processeur est bien plus simple. L'envoi du ''program counter'' sur le bus d'adresse utilise le port de lecture relié au bus d'adresse, qui sert aussi pour l'adressage indirect. L'économie de circuits, sans compter la simplicité d'implémentation que cela implique, explique sans doute que la technique a été utilisée sur quelques processeurs anciens. Le ''program counter'' était généralement incrémenté par l'ALU, ce qui explique qu'il soit connecté au bus interne pour les données. La connexion est aussi utile pour gérer les branchements indirects, qui copient un registre dans le ''program counter'', ainsi que les branchements relatifs (addition dans l'ALU), voire les branchements directs (l'adresse vers laquelle brancher est envoyée en entrée de l'ALU et propagée en sortie avec une opération ''pass through''). [[File:Connexion du program counter sur les bus avec PC dans le banc de registres.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC dans le banc de registres]] ===Les registres d'interruption avec un processeur hybride-accumulateur : l'exemple du Z80=== Un exemple de processeur registre-accumulateur à deux bus interne est le Z80, un processeur fortement inspiré des CPU Intel 8 bits. Il a un jeu d'instruction similaire, mais a diverses améliorations par rapport au design original. Notamment, le processeur a des registres séparés pour les interruptions. Sur le Z80, les registres généraux sont dupliqués avec 6 registres pour les interruptions et 6 registres pour les programmes autres. Leur copie pour les interruptions sont nommées B', C', D', E', H', L'. Les 12 registres sont placés dans le banc de registre, ce qui implique que le fenêtrage de registres est utilisé pour gérer la séparation entre registre d'interruption et normaux. Il faut noter que l'accumulateur et le registre d'état sont aussi dupliqués, leurs copies étant nommées A' et F'. Mais leur duplication se fait autrement que par fenêtrage de registre. En plus des registres précédents, le Z80 incorporait deux registres d'indice nommés X et Y, ainsi qu'un pointeur de pile SP et un ''program counter'' PC. Ils n'étaient pas dupliqués pour les interruptions. Les registres d'indice étaient reliés à une unité de calcul d'adresse. L'unité de calcul d'adresse prenait deux opérandes : un indice, et une adresse mémoire provenant soit du banc de registre, soit de l'accumulateur. En clair, l'unité de calcul d'adresse faisait le lien entre les deux bus internet : le bus de données interne en entrée, le bus d'adresse en sortie. À l'intérieur du processeur, tous les registres étaient regroupés dans un banc de registre unique, sauf les accumulateurs, les registres d'état et le ''program counter''. Bien que ce ne soit pas indiqué sur le schéma ci-dessous, le ''program counter'' est séparé du banc de registre, alors que le pointeur de pile est dedans. Le compteur IR est lui associé au ''program counter'', il est sortit du banc de registre. Le Z80 utilise lui aussi un incrémenteur séparé de l'ALU, qui est utilisé pour mettre à jour le ''program counter'', le pointeur de pile et un compteur de rafraichissement mémoire nommé IR sur le Z80 (pour rappel, le rafraichissement mémoire demande de balayer la mémoire d'adresse en adresse et été fait par le CPU à l'époque). De plus, il est utilisé pour les instructions INC et DEC qui incrémentent une opérande de 16 bits obtenue en combinant deux registres de 8 bits. En clair, l'incrémenteur du ''program counter'' a été réutilisé de beaucoup de manières originales. [[File:Z80 arch.svg|centre|vignette|upright=3|Microarchitecture du Z80.]] Le Z80 incorporait des instructions pour échanger le contenu des deux ensembles de registres, accumulateur inclus. Elles permettaient d'utiliser les registres d'interruption pour les programmes et réciproquement. En clair, cela doublait le nombre de registres si les interruptions n'étaient pas utilisées. * L'instruction EXX échangeait les deux fenêtres de registres généraux : les registres B, C, D, E, H et L devenaient les registres B', C', D', E', H' et L' et inversement. * L'instruction EX échangeait l'accumulateur et le registre d'état : les registres A,F devenait A',F' et inversement. Le fenêtrage de registre était modifié par l'instruction EXX, qui échangeait les deux fenêtres de registres. Pour l'implémenter, une bascule était ajouté au processeur, appelons-la la bascule INT. Elle était relié au bus d'adresse du banc de registre, dont elle mémorisait le bit de poids fort. L'instruction EXX inversait la valeur de la bascule INT. Il est aussi possible d'échanger le contenu des registres D,E et H,L avec une instruction dédiée, ce qui est là encore fait par deux bascules : une pour les registres D,E et une autre pour les registres H,L. Pour l'accumulateur et le registre d'état, le choix entre registre normal et registre d'interruption se faisait là encore par une seconde bascule appelée la bascule A. La bascule est reliée à un multiplexeur et un démultiplexeur, qui permet de choisir quel accumulateur relier à l'unité de calcul. L'instruction EX inverse le contenu de la bascule A. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=L'unité de contrôle | prevText=L'unité de contrôle | next=Les processeurs 8 bits et moins | nextText=Les processeurs 8 bits et moins }} </noinclude> e47cwmmrstmrrycko4024mwj3ayq5b9 744177 744176 2025-06-05T17:24:53Z Mewtow 31375 /* Les architectures hybrides registres-accumulateur */ 744177 wikitext text/x-wiki Les architectures que nous avons vu précédemment dans ce cours disposent de registres pour les données, en plus du pointeur de pile, d'un ''program counter'', et de quelques autres. Elles sont appelées des '''architectures à registres''', terme qui trahit bien le fait qu'elles ont des registres généraux ou spécialisés pour stocker temporairement des données. Et si on leur a donné un nom, c'est parce qu'il existe des architectures qui ne sont pas dans cette catégorie. Il en existe plusieurs types, mais ce chapitre va se concentrer sur les '''architectures à accumulateur'''. [[File:Isaccumulator.png|vignette|Architecture à accumulateur.]] Les architectures à accumulateur sont centrées autour d'un registre architectural appelé l''''accumulateur'''. Il est utilisé pour toutes les opérations arithmétiques dyadiques, où il sert à la fois de source et de destination. Toutes les instructions dyadiques sont de type ''load-op'' : une opérande est lue depuis l'accumulateur, le second opérande est lu depuis la mémoire RAM, le résultat de l'instruction est automatiquement mémorisé dans l'accumulateur. Les instructions monadiques peuvent utiliser un opérande dans l'accumulateur, ou dans la mémoire RAM, les deux sont théoriquement possibles. La conséquence est que le nombre d'accès mémoire est drastiquement diminué : de 3 par instructions sur une architecture mémoire-mémoire, on passe à seulement un avec un accumulateur. Les opérations dyadiques ont besoin d'un seul accès mémoire pour lire la seconde opérande, les opérations monadique en font aussi un seul pour lire leur unique opérande. {|class="wikitable" |- ! Classe d'architecture ! Nombre d'accès mémoire par opération dyadique |- |- ! Architecture à accumulateur | Un accès mémoire par instruction, pour lire la seconde opérande |- ! Architecture à registres | Zéro si les opérandes sont dans les registres, un pour les opérations ''load-op'', LOAD et STORE. |} ==Le jeu d'instruction des architectures à accumulateur sans registres d'indice== L'accumulateur est adressé grâce au mode d'adressage implicite, de même que le résultat de l'opération. Par contre, les autres opérandes sont localisés avec d'autres modes d'adressage, et lues en mémoire RAM. Le résultat ainsi qu'un des opérandes sont adressés de façon implicite car dans l'accumulateur, seule la seconde opérande étant adressée directement. Grâce à l'accumulateur, une instruction ne fait qu'un seul accès mémoire maximum, ce qui rend le processeur très facile à implémenter. ===Les registres des anciennes architectures à accumulateur=== [[File:IBM 701console.jpg|vignette|IBM 701, console extérieure.]] Les architectures à accumulateur étaient communes dans les années 50-60. A l'époque, les ordinateurs étaient gigantesques, ils prenaient une pièce de bâtiment entière dans le pire des cas, une armoire entière dans le meilleur. Les ordinateurs de l'époque étaient surtout utilisés pour du calcul scientifique ou des tâches d’ingénierie demandant beaucoup de calcul, rarement pour de la compatibilité. Les nombres flottants n'étaient pas encore apparus. A la place, les ordinateurs de l'époque géraient des nombres entiers de grande taille, de 30 bits ou plus. En conséquence, l'accumulateur faisait facilement 30 à 60 bits. Par exemple, les ordinateurs de la Série scientifique IBM 700/7000 géraient des entiers de 36 bits, l’accumulateur faisait 38 bits : 36 bits plus deux bits pour les débordements. Au passage, de tels processeurs utilisaient l'adressage par mot, et non par byte. Historiquement, les premières architectures à accumulateur ne contenaient aucun autre registre que l'accumulateur. Ce n'est que dans les années 60 que de nombreuses architectures à accumulateur ont ajouté un second '''registre pour les multiplication/divisions'''. Un exemple est celui de l'IBM 701, qui incorporait un registre accumulateur de 38 bits et un registre multiplieur de 36 bits. Le registre mémorise le multiplieur lors d'une opération de multiplication. Il mémorise donc un opérande, pas le résultat. Il peut aussi décaler le multiplieur vers la droite/gauche, ce qui est utile pour exécuter la multiplication. C'est ce qui est fait sur l'IBM 7094. Une autre possibilité est que ce registre mémorise une partie du résultat de l'opération. Pour rappel, le résultat d'une multiplication/division est codé sur deux fois de bits que ses opérandes. Par exemple, multipliez deux opérandes de 30 bits, vous obtiendrez un résultat de 60 bits. Les 30 bits de poids faible du résultat vont dans l'accumulateur, les 30 bits de poids fort vont dans ce second registre. Les architectures à accumulateur parfois un '''registre pour le pointeur de pile''', utilisé pour gérer les fonctions/procédures. Les architectures à accumulateurs supportaient une pile d'adresse de retour, souvent une pile d'appel. Mais pour cela, il fallait mémoriser le pointeur de pile dans le processeur, ce qui demandait un registre dédié. ===L'adressage indirect avec l'accumulateur=== Les instructions LOAD et STORE existent bel et bien sur les architectures à accumulateur, mais n'ont pas les mêmes modes d'adressages. L'instruction LOAD copie une donnée de la RAM vers l'accumulateur, l'instruction STORE copie l'accumulateur dans une adresse. Les deux instructions n'ont pas besoin d'adresser l'accumulateur, qui est adressé de manière implicite, juste de préciser l'adresse à lire/écrire. Les architectures à accumulateur supportaient souvent le mode d'adressage indirect mémoire. Un exemple est celui des ordinateurs Data General Nova, qui sont des architectures à accumulateur et qui supportaient ce mode d'adressage. Les deux instructions LOAD et STORE existaient en deux versions, distinguées par un bit d'indirection. Si ce bit est à 0 dans l'opcode, alors l'instruction utilise le mode d'adressage absolu normal : l'adresse intégrée dans l'instruction est celle de la donnée. Mais s'il est à 1, alors l'adresse intégrée dans l'instruction est celle du pointeur. Cependant, la présence de l'accumulateur permettait d'utiliser l'adressage indirect à registre, pour gérer les pointeurs. Pour rappel, avec le mode d'adressage indirect à registre, l'adresse à lire/écrire est dans un registre. Ici, l'adresse à lire/écrire est prise dans l'accumulateur, seul registre disponible pour. L'adressage indirect est plus simple à implémenter pour l'instruction LOAD, car elle prend un seul opérande : l'adresse à lire. L'adresse à lire est placée dans l'accumulateur, la donnée lue est elle aussi chargée dans l'accumulateur. Pour l'instruction STORE, il faut fournir deux opérandes, l'adresse et la donnée à écrire, ce qui peut poser problème. Mais au pire, il est toujours possible d'utiliser l'adressage absolu ou indirect mémoire : l'adresse est dans l'instruction, la donnée à écrire dans l'accumulateur. ===L'encodage des instructions=== Sur une architecture à accumulateur l'encodage d'une instruction dyadique est assez simple, vu que l'accumulateur est adressé implicitement. La seconde opérande est localisée soit par une adresse mémoire (adressage absolu), soit est une constante (adressage immédiat). L'adresse mémoire est généralement assez longue, plus que l'opcode. {|class="wikitable" |+ Encodage d'une instruction dyadique |- ! rowspan="2" | Opcode | Adresse mémoire (adressage absolu) |- | Constante (adressage immédiat) |} L'encodage d'une instruction monadique est similaire. Si l'opérande est lue depuis la mémoire RAM, alors l'instruction est encodée comme une instruction dyadique. Il en est de même pour les instructions qui copient une constante dans l'accumulateur. Par contre, si l'opérande est dans l'accumulateur, alors il y a juste besoin d'encoder l'opcode. La majorité des instructions a besoin de préciser une adresse, rares sont celles qui s'en passent. Au vu de cet encodage, les architectures à accumulateur sont qualifiées d''''architectures à une adresse''' par abus de langage. Il est intéressant de contraster leur encodage avec les architectures à registres. Les architectures à registre doivent encoder deux opérandes en plus de l'opcode, avec éventuellement où enregistrer le résultat sur les architectures 3-adresses. Par contre, les opérandes sont généralement des noms de registre, ce qui prend moins de place qu'une adresse mémoire. A la rigueur, les instructions avec une constante immédiate prennent un peu plus de place, car elles doivent encoder un nom de registre en plus de la constante et de l'opcode. Les instructions ''load-op'' des processeurs CISC sont un peu dans le même cas, sauf qu'il faut remplacer la constante par une adresse, qui a généralement la même taille. Les instructions sont donc en moyenne plus courte sur les processeurs à registre, du fait de la présence de registres. ===Annexe : les toutes premières architectures à accumulateur : le Manchester Baby=== [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] Les architectures à accumulateurs sont apparues dès les débuts de l'informatique. Le tout premier ordinateur à programme enregistré en mémoire, le ''Manchester Baby'', était une architecture à accumulateur. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 adresses, fabriquée avec des tubes Williams (abordés dans une annexe à la fin du cours). Chaque adresse mémorisait 32 bits, qui pouvaient encoder soit un nombre, soit une instruction. Le programme devait tenir dans la RAM, avec une instruction par adresse maximum, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 bits d'adresse servait à indiquer où se trouvent la seconde opérande en RAM, les 16 restants sont inutilisés. En théorie, les 12 bits d'adresse permettaient d'adresser 4096 adresses, mais seules 32 étaient réellement présentes. Le processeur avait un registre accumulateur de 32 bits, un ''program counter'' et un registre d'instruction. Il intégrait un additionneur dédié au ''program counter'', mais l'ALU n'avait pas d'additionneur. En conséquence, il ne gérait pas l'addition. A la place, il gérait la soustraction. Il pouvait cependant émuler l'addition à partir d'une soustraction. La soustraction était utilisée pour calculer le complément d'une opérande, et soustraire le complément revient à additionner. L'ALU était une ALU sérielle, à savoir qu'elle faisait les soustractions bit par bit. Le processeur supportait 7 instructions au total : la soustraction, des instructions de branchement et d'accès mémoire, rien d'autre. Les instructions de branchement utilisaient des modes d'adressage très particuliers, qu'on ne retrouve pas sur les ordinateurs modernes. Les branchements inconditionnels utilisaient une forme d'adressage mémoire indirect, pas les adressages usuels pour les branchements. Il n'y avait pas de branchements conditionnels, mais une ''SKIP instruction''. {|class="wikitable" |- ! SUB | Soustrait l'opérande mémoire de l'accumulateur. |- ! CMP | Skippe l'instruction suivante si l'accumulateur a une valeur négative. |- ! JMP | Branchement indirect mémoire. : * L'adresse de destination est lue depuis la mémoire. * L'adresse lue est intégrée dans l'instruction via adressage absolu. |- ! JRP | Branchement relatif indirect. * Lit une opérande depuis la mémoire, l'adresse est intégrée dans l'instruction via adressage absolu. * Additionne l'opérande lue au ''program counter''. |- ! LDN | Instruction LOAD. La donnée lue est inversée lors de la lecture, l'accumulateur contient le complément à deux de la donnée lue après la lecture. |- ! STO | Instruction STORE |- ! STOP | Éteint l'ordinateur. |} Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. Le Manchester Baby était un prototype, mais il avait été pensé pour être étendu, notamment afin d'avoir plus de mémoire. C'est pour cela que ses adresses étaient codées sur 12 bits, malgré sa mémoire de seulement 32 mots. Le plan initial, à savoir utiliser une RAM de 4096 mots, a cependant été abandonné pour la Manchester Mark 1. A la place, la RAM a gardé la même taille, à savoir 32 nombres, mais a été complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique. Le tambour magnétique contenait 40 pages, chacune ayant la même taille que la RAM. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. Le processeur gérait maintenant l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. De plus, il intégrait deux registres dédiés aux multiplications : un pour le multiplicande, un autre pour le multiplieur. Ils étaient nommés D et R et étaient regroupés dans un seul tube Williams noté M. Cependant, les multiplications étaient réalisées en enchainant une série d'additions, dans l'additionneur-soustracteur. C'était là encore une architecture à accumulateur, sauf qu'elle intégrait aussi des registres d'indice. Les registres d'indices étaient au nom de deux et étaient notés B0 et B1. Lors du chargement d'une instruction, un registre d'indice était sélectionné grâce à un bit de l'instruction. Le contenu de ce registre d'indice était additionné à l'instruction , l'adresse encodée dedans pour être précis, et le résultat était envoyé sur le bus mémoire. La microarchitecture de la machine est illustrée ci-dessous. Elle a une ALU unique capable de faire plusieurs opérations, qui sont représentées dans des rectangles séparés. Les cercles dans le schéma suivant sont des tubes Williams, des écrans CRT modifiés de manière à servir de mémoire DRAM, dont le fonctionnement est détaillée dans le chapitre sur les mémoires historiques. Un tube Williams implémente un banc de registre complet, c'est à dire un groupe de 2 à 10, registres. L'accumulateur est noté A, les deux registres de multiplication sont regroupés dans le tube Williams M, les registres d'indice sont dans le tube noté B. Le tube Williams C regroupe le ''program counter'' et le registre d'instruction. L'additionneur sert à incrémenter le ''program counter'', mais aussi pour les branchements relatifs. La statistation est le nom donné au séquenceur, à l'unité de contrôle, décodeur d'instruction inclus. [[File:MM1Schematic French.svg|centre|vignette|upright=2.5|Architecture de la Manchester Mark 1.]] ==La micro-architecture des architectures à accumulateur sans registres d'indice== L'organisation interne d'une architecture à accumulateur est très différente de celle des processeurs à registre. Elle est plus ou moins la même pour tous ces processeurs, le point important étant que le chemin de données se résume à une ALU, un registre accumulateur et le bus de données. L'ALU est reliée au registre accumulateur, ainsi qu'au bus de données pour lire la seconde opérande, comme illustré ci-dessous. [[File:Accumulator.png|centre|vignette|upright=2|Accumulateur.]] ===L'unité de calcul et l'accumulateur=== Pour simplifier l'implémentation, le résultat est mémorisé dans un registre en sortie de l'unité de calcul. La raison est qu'on ne veut pas altérer l'accumulateur tant que le résultat final n'est pas totalement calculé. Rappelons que l'ALU ne fournit pas un résultat d'un seul bloc, mais que certains bits arrivent avant les autres, typiquement les bits de poids faible. Si le résultat était écrit dans l'accumulateur directement, il écraserait des bits de l’opérande en cours d'utilisation, ce qui fausserait le résultat. [[File:Accumulateur avec registre de sortie.png|centre|vignette|upright=2|Accumulateur avec registre de sortie]] Une autre solution utilisait un registre entre l'accumulateur et l'unité de calcul, appelé l’'''''accumulator latch'''''. Il remplace le registre en sortie de l'ALU, dans le sens où il permet d'écrire dans l'accumulateur sans effacer l'opérande, pendant que l’opération est en cours dans l'ALU. L'accumulateur est copié dans l’''accumulator latch'', avant que l'ALU démarre ses calculs. L'opérande est donc maintenue même si on commence à écrire le résultat dans l'accumulateur. Sur le 8085 d'Intel, l’''accumulator latch'' peut être initialisé avec une constante prédéfinie, ce qui permet d'implémenter certaines instructions très facilement. Par exemple, il peut être initialisé à 0, ce qui permet d'implémenter les instructions MOV et INC (incrémentation). Un MOV est équivalent à faire un OU entre le registre lu et 0. Une instruction INC initialise l'entrée de retenue de l'unité de calcul à 1, puis ajoute 0. La décrémentation est implémentée de la même manière, sauf que l’''accumulator latch'' est initialisé à -2 pour compenser l'entrée de retenue à 1. De plus, pour supporter les conversion de décimal à BCD, l’''accumulator latch'' peut être initialisé avec les constantes 0x00, 0x06, 0x60, or 0x66. L'''accumulator latch'' est relié à divers fils de commande provenant de l'unité de contrôle, qui décide quelle valeur d'initialisation utiliser en fonction de l'instruction décodée. [[File:Accumulator latch.png|centre|vignette|upright=2|Accumulator latch]] [[File:Chemin de données à un seul bus.png|vignette|Chemin de données à un seul bus]] De même, la seconde opérande, celle lue sur le bus de données, est mémorisée dans un registre en amont de l'ALU. C'était notamment très utile si le processeur utilisait une ALU plus courte que les opérandes, avec par exemple une ALU 4 bits pour un CPU 8 bits. Les anciens processeurs à accumulateur de type ''mainframe'' utilisaient des opérandes de grande taille, du genre 36 ou 48 bits, ce qui avait des conséquences sur l'unité de calcul utilisée, ainsi que sur la communication avec la mémoire. Il arrivait que de tels processeurs utilisaient des ALU sérielles, ou du moins octet-sérielles, plutôt qu'une véritable ALU 36 bits. Nous verrons aussi que c'est très utile sur les processeurs à accumulateur avec un bus interne unique, dans la suite du chapitre. ===La micro-architecture des architectures à accumulateur avec instructions LOAD/STORE=== Nous venons de voir comment est implémenté l'unité de calcul et l'accumulateur, et comment le tout est relié au bus de données. Mais cela ne permet que d'avoir un processeur à accumulateur rudimentaire, qui ne gére que des instructions arithmétiques et logiques. Il faut aussi gérer le cas des opérations LOAD/STORE et des modes d'adressages associés, mais c'est le séquenceur qui s'en occupe. Avec l'adressage absolu, les instructions LOAD et STORE ne font que connecter l'accumulateur au bus de données. L'instruction STORE nécessite de connecter l'accumulateur au bus de données, de manière à ce que le transfert des données se fasse de l'accumulateur vers le bus de données. L'instruction LOAD s'implémente de la même manière, sauf que le sens de transfert est inversé. Cependant, il existe une optimisation qui permet d'implémenter l'instruction LOAD sans ajouter de circuits. Pour cela, il suffit que l'unité de calcul gére les opérations ''pass through'', à savoir des opérations qui se contentent de recopier un opérande sur la sortie. Ici, l'idée est de recopier l'opérande provenant du bus de données. [[File:Architecture à accumulateur, microarchitecture.png|centre|vignette|upright=2|Architecture à accumulateur, microarchitecture]] Pour gérer nativement l'adressage indirect à registre, il suffit de connecter l'accumulateur au bus d'adresse. Le plus simple est d'ajouter un multiplexeur, comme illustré ci-dessous. La donnée lue est copiée dans l'accumulateur, ce qui fait qu'il vaut mieux utiliser un registre d’interfaçage, l'accumulateur n'étant pas utilisable à la fois pour le bus d'adresse et de données. [[File:Adressage indirect sur une architecture à accumulateur.png|centre|vignette|upright=2|Adressage indirect sur une architecture à accumulateur]] Pour finir, voyons comment le pointeur de pile et le ''program counter'' sont implémentés. Les architectures à accumulateur ont souvent des adresses de taille différente des données, ce qui fait qu'il vaut mieux utiliser un circuit incrémenteur dédié pour incrémenter le ''program counter'', plutôt que de l'incrémenter via l'unité de calcul. Les architectures à accumulateur ont parfois un pointeur de pile, qui gère une pile d'adresse de retour, pas une vraie pile d'appel. Aussi, le pointeur de pile est censé être incrémenté et décrémenté, pas plus. Pas d'addition ou de soustraction pour gérer des cadres de pile. Là encore, c'est la solution de l'incrémenteur séparé qui est retenue. Pour économiser des transistors, il n'y a qu'un seul incrémenteur partagé pour les deux. ==Les architectures à accumulateur à registres d'indice== Les architectures à accumulateur décrites dans la section précédente sont capables de faire de l'adressage indirect, mais n'incluent pas les modes d'adressage base + indice et absolus indicés, qui prennent une adresse et y ajoute un indice. Il s'agit des toutes premières architectures à accumulateur, comme les premiers ordinateurs IBM ou le fameux PDP-8. Mais par la suite, les processeurs à accumulateurs ont inclus un support des modes d'adressages indicés, grâce à des '''registres d'indice'''. ===Les registres d'indice=== Les registres d'indice stockent des indices de tableaux. Ils permettaient de supporter deux modes d'adressage : * Le '''mode d'adressage absolu indicé''' où une adresse fixe est additionnée à un indice variable. L'adresse fixe est intégrée dans l'instruction (adressage absolu), l'indice est dans un registre d'indice. * Le '''mode d'adressage base + indice''', où l'adresse est dans l'accumulateur et l'indice dans le registre d'indice. Les processeurs à accumulateur supportaient souvent des variantes des modes d'adressage précédents, où le registre d'indice était automatiquement incrémenté ou décrémenté à chaque utilisation. Au départ, ces processeurs n'utilisaient qu'un seul registre d'indice qui se comportait comme un second accumulateur spécialisé dans les calculs d'adresses mémoire. Le processeur supportait de nouvelles instructions qui utilisaient ce registre d'indice de façon implicite. Mais avec le temps, les processeurs finirent par incorporer plusieurs de ces registres. Les instructions de lecture ou d'écriture devaient alors préciser quel registre d'indice utiliser, en précisant un nom de registre d'indice, un numéro de registre d'indice. Il faut préciser que les registres d'indice ont une taille bien plus petite que l'accumulateur. Ils mémorisent des indices codés sur 16 bits ou moins, alors que l'accumulateur faisait typiquement 36 à 48 bits, parfois plus. La taille classique sur les anciens ''mainframes'' était de 15 bits, parfois moins. Il n'était pas rare de tomber sur des registres d'indice de 8 ou 9 bits. Leur petite taille rendait leur implémentation matérielle peu couteuse. Et c'est ce qui explique qu'ils étaient préférés à l'usage d'un second accumulateur. Un exemple est le cas du processeur Motorola 6809, un processeur à accumulateur qui contient deux registres d'indices nommés X et Y. L'accumulateur est noté D et fait 16 bits, il peut être parfois géré comme deux accumulateurs séparés A et B de 8 bits chacun. Il contenait aussi deux pointeurs de pile, l'un pour les programmes, l'autre pour le système d'exploitation, ainsi qu'un ''program counter''. Le registre de page était utilisé pour l'adressage absolu, comme vu dans le chapitre sur les modes d'adressage. [[File:6809 Internal Registers.svg|centre|vignette|upright=2|6809 Internal Registers]] Les processeurs IBM avaient autrefois plusieurs registres d'indice. Par exemple, l'IBM 704 avait trois registres d'indice de 15 bits. Leur contenu était soustrait de l'adresse absolue. Une instruction pouvait utiliser plusieurs registres d'indice pour adresser son opérande. Toute instruction utilisait trois bits pour sélectionner les registres d'indice utilisés. Fait assez original, lorsque plusieurs registres d'indice sont sélectionnés, le processeur n'additionne pas les trois registres à l'adresse de base. À la place, il fait un OU bit à bit entre les registres d'indice sélectionnés, et additionne le résultat à l'adresse. Les processeurs IBM à accumulateur ont fait ça sur toute la gamme IBM 700/7000, pour des raisons de compatibilité. Les processeurs suivants avaient 7 registres d'indices, mais conservaient les trois bits pour adresser les registres d'indices. Ils pouvaient fonctionner dans deux modes. Le premier mode est plus intuitif : les trois bits précisent un registre d'indice parmi les 7, qui est additionné avec l'adresse absolue. La valeur zéro indique qu'aucun registre d'indice n'est utilisé, ce qui explique qu'il y a 7 registres d'indice et non 8. Un second mode, compatible avec l'IBM 704, fait un OU logique entre les registres d'indice sélectionnés. Seuls les trois premiers registres d'indices peuvent être sélectionnés dans ce mode. Il y a deux instructions pour changer de mode : une pour passer en mode compatible, l'autre pour le quitter pour l'autre mode. Quelques rares processeurs à registres généraux ont utilisés des registres d'indice, en plus des registres généraux. Ce qui fait l'association que nous avons faite entre registres d'indice et architectures à accumulateur est imparfait, bien que solide sur le principe. Un exemple d'architecture de ce type sont les architectures de la série UNIVAC 1100/2200. Ils disposaient de 128 registres, qui étaient mappés en mémoire à partir de l'adresse mémoire 0, la majorité étant inaccessibles par le programmeur. Ils regroupaient 12 registres accumulateurs, 11 registres d'indice et 4 registres hybrides qui pouvaient servir soit de registre d'indice, soit de registres accumulateurs. ===La micro-architecture des architectures à accumulateur avec registres d'indice=== La présence de registres d'indice modifie grandement l'implémentation du processeur. En effet, il faut rajouter un banc de registre pour les registres d'indice. Le banc de registre est monoport, car on a besoin de lire ou d'écrire un indice à la fois. Et il faut aussi potentiellement rajouter de quoi faire les calculs d'adresse. Deux solutions sont possibles : une ALU dédiée aux calculs d'adresse, une seule ALU pour toutes les opérations. Dans le premier cas, il y a une ALU séparée associée aux registres d'indice. L'ALU et les registres d'indice sont placés en sortie du séquenceur, en-dehors du chemin de données, la sortie de l'ALU est directement connectée au bus d'adresse. L'unité de calcul d'adresse peut être utilisée pour incrémenter le ''program counter''. Un défaut de cette approche est qu'elle ne gère pas l'adresse indirect à registre. [[File:Chemin de données sans support des pointeurs, avec adressage absolu indicé.png|centre|vignette|upright=2|Chemin de données sans support des pointeurs, avec adressage absolu indicé]] Une autre option utilise un bus interne, qui interconnecte tout le chemin de données. Dans sa version la plus simple, il est relié à l'accumulateur, l'unité de calcul, le banc de registre d'indice et le bus de données. Avec cette solution, l'ALU est utilisé à la fois pour calculer les adresses et pour les instructions de calcul. En reliant le bus interne au bus d'adresse à travers un multiplexeur, on gère naturellement les adressages indirects. [[File:Architecture à accumulateur avec registres associés.png|centre|vignette|upright=2.5|Architecture à accumulateur avec registres associés]] Il faut noter que sur les architectures Von Neumann, le séquenceur est relié à ce bus interne. En effet, charger une instruction demande de passer par le bus mémoire, donc par l’intermédiaire de ce bus internet. Le ''program counter'' est envoyé sur ce bus pour lire l'instruction, puis l'instruction lue est recopiée dans le registre d'instruction. Le chargement d'une instruction est donc géré comme une lecture des plus classiques. De plus, cela permet d'incrémenter le ''program counter'' au niveau de l'unité de calcul entière. Le ''program counter'' est envoyé sur le bus interne, incrémenté par l'ALU, puis le résultat est recopié dans le ''program counter'' via le bus interne. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] ==Les processeurs bi-accumulateurs : le Motorola 6800== Le Motorola 6800 était un processeur 8 bits qui gérait des adresses de 16 bits. Il contenait deux accumulateurs nommés A et B, de 8 bits chacun. Il disposait aussi d'un registre d'indice, d'un pointeur de pile et d'un ''program counter'', tous les trois de 16 bits. Le registre d'état regroupait 6 bits, qu'on ne détaillera pas ici. [[File:MC6800 Processor Diagram.png|centre|vignette|upright=2|Interface et registres du MC6800.]] La présence des deux accumulateurs impactait surtout les instructions dyadiques. Les instructions monadiques avaient juste à préciser où se trouvait l'opérande : soit en RAM, soit dans le premier accumulateur, soit dans le second. Pour les opérations dyadiques, la gestion était totalement différente. En théorie, le premier opérande est dans un accumulateur, soit A, soit B. La seconde opérande vient soit de l'autre accumulateur, soit de la mémoire RAM. Et selon les instructions, tout variait. Pour l'addition, il y avait trois instructions. Les deux premières additionnaient un opérande provenant de la mémoire avec un accumulateur. L'instruction ADDA sélectionnait le premier accumulateur, l'instruction ADDB sélectionnait le second accumulateur. Mais une troisième instruction, l’instruction ABA, permettait d'additionner le contenu des deux accumulateurs. Pour les autres opérations, il n'était pas possible d'utiliser les deux accumulateurs en même temps. La seule possibilité était de faire une opération entre un accumulateur et un opérande venant de la mémoire. Toutes les instructions étaient en double, avec une copie par accumulateur. Par exemple, l'instruction ANDA faisait un ET entre l’accumulateur A et l'opérande mémoire, l'instruction ANDB faisait pareil avec l'accumulateur B. ==Les architectures hybrides registres-accumulateur== Il a existé quelques architectures qui étaient des hybrides entre architectures à accumulateur et architecture à registre. Elles sont apparues assez tôt, dès les années 50. Par exemple, le Bull Gamma 3 était un ordinateur de type ''mainframe'' qui disposait d'un accumulateur accompagné de registres généraux. Et c'était à une époque où les ordinateurs étaient intégralement construits avec des tubes à vides et autres mémoires spécialisées. Mais ces architectures sont restées assez confidentielles pendant les années 50 à 80. Par la suite, elles ont eu un regain de popularité durant les années 80-90. Elles ont alors servit de transition entre architectures à accumulateur proprement dites, et architectures à registres. Elles avaient un accumulateur unique couplé à un banc de registres généraux. Par exemple, les processeurs Intel 8 bits disposaient de 7 registres de 8 bits nommés A, B, C, D, E, F, H, L, SP. Ils correspondent respectivement à : * l'accumulateur A ; * six registres nommés B, C, D, E, H et L ; * le registre d'état F ; * le pointeur de pile SP. Sur ces processeurs, les instructions dyadiques devaient mettre leur premier opérande dans l'accumulateur, la seconde provenait soit des registres, soit de la RAM, soit d'une constante immédiate. Les opérations monadiques pouvaient lire leur opérande depuis l'accumulateur, les autres registres ou la RAM, tout était permis. Les registres d'indices disparaissaient sur ces architectures, en théorie. Les registres généraux pouvaient être utilisés comme registre d'indice ou pour stocker des opérandes, ils étaient assez versatiles pour servir de registres d'indices. La présence de registres a de nombreux avantages, comparé aux architectures à accumulateur pures. Les instructions arithmétiques sont plus rapide, lire un registre étant plus rapide qu'un accès RAM. Les performances sont donc augmentées. De plus, les instructions arithmétiques utilisant ces registres sont plus courtes : pas besoin d'encoder une adresse mémoire, un nom de registre suffit. Vu que les processeurs de l’époque avaient des instructions de taille variable, cela améliorait la densité de code. ===La micro-architecture des processeurs hybrides registres-accumulateur=== La micro-architecture de ces processeurs est très similaire à celle d'un processeur avec des registres d'indices. La seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Le banc de registre est systématiquement monoport, car il n'avait aucune raison d'être multiport. Pour les instructions dyadiques, seules à lire deux opérandes, il ne servait que pour la seconde opérande, la première était lue depuis l'accumulateur. Les processeurs hybrides registre-accumulateur se classent en deux types principaux : ceux qui ont un seul bus interne, et ceux qui en ont deux. Le premier cas est identique à celui vu précédemment pour les architectures à accumulateur avec registres d'indice, à la seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Afin de gérer l'adressage indirect à registre, le bus interne est connecté aux deux registres d’interfaçage mémoire. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] Notons que cela permet aussi d'implémenter facilement les branchements indirects, car le bus interne permet d'échanger des adresses entre ''program counter'' et banc de registre. De même, il est possible d'utiliser l'ALU pour gérer les branchements indirects., en plus de l'utiliser pour incrémenter le ''program counter''. [[File:Single bus organization.jpg|centre|vignette|upright=2|Single bus organization]] Une autre solution utilisait deux bus internes : un connecté au bus de données, un autre relié au bus d'adresse. Le bus de commande mémoire était lui commandé par le séquenceur, l'unité de contrôle. L'intermédiaire entre ces deux bus était le banc de registre, ainsi que les autres registres. Le banc de registre était connecté aux deux bus interne, avec un port de lecture relié au bus d'adresse, un port de lecture-écriture relié au bus de données. Le port de lecture était utilisé pour l'adressage indirect, l'autre l'était pour le reste. [[File:Proz1-e.png|centre|vignette|upright=2|Intérieur d'un processeur.]] L'organisation à deux bus simplifiait la gestion du ''program counter'' et le chargement des instructions. Le ''program counter'' était soit séparé du banc de registre, soit placé dans le banc de registre. Les deux solutions étaient utilisés, tout dépend du processeur. Il faut noter que si le ''program counter'' est intégré au banc de registres, alors la microarchitecture du processeur est bien plus simple. L'envoi du ''program counter'' sur le bus d'adresse utilise le port de lecture relié au bus d'adresse, qui sert aussi pour l'adressage indirect. L'économie de circuits, sans compter la simplicité d'implémentation que cela implique, explique sans doute que la technique a été utilisée sur quelques processeurs anciens. Le ''program counter'' était généralement incrémenté par l'ALU, ce qui explique qu'il soit connecté au bus interne pour les données. La connexion est aussi utile pour gérer les branchements indirects, qui copient un registre dans le ''program counter'', ainsi que les branchements relatifs (addition dans l'ALU), voire les branchements directs (l'adresse vers laquelle brancher est envoyée en entrée de l'ALU et propagée en sortie avec une opération ''pass through''). [[File:Connexion du program counter sur les bus avec PC dans le banc de registres.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC dans le banc de registres]] ===Les registres d'interruption avec un processeur hybride-accumulateur : l'exemple du Z80=== Un exemple de processeur registre-accumulateur à deux bus interne est le Z80, un processeur fortement inspiré des CPU Intel 8 bits. Il a un jeu d'instruction similaire, mais a diverses améliorations par rapport au design original. Notamment, le processeur a des registres séparés pour les interruptions. Sur le Z80, les registres généraux sont dupliqués avec 6 registres pour les interruptions et 6 registres pour les programmes autres. Leur copie pour les interruptions sont nommées B', C', D', E', H', L'. Les 12 registres sont placés dans le banc de registre, ce qui implique que le fenêtrage de registres est utilisé pour gérer la séparation entre registre d'interruption et normaux. Il faut noter que l'accumulateur et le registre d'état sont aussi dupliqués, leurs copies étant nommées A' et F'. Mais leur duplication se fait autrement que par fenêtrage de registre. En plus des registres précédents, le Z80 incorporait deux registres d'indice nommés X et Y, ainsi qu'un pointeur de pile SP et un ''program counter'' PC. Ils n'étaient pas dupliqués pour les interruptions. Les registres d'indice étaient reliés à une unité de calcul d'adresse. L'unité de calcul d'adresse prenait deux opérandes : un indice, et une adresse mémoire provenant soit du banc de registre, soit de l'accumulateur. En clair, l'unité de calcul d'adresse faisait le lien entre les deux bus internet : le bus de données interne en entrée, le bus d'adresse en sortie. À l'intérieur du processeur, tous les registres étaient regroupés dans un banc de registre unique, sauf les accumulateurs, les registres d'état et le ''program counter''. Bien que ce ne soit pas indiqué sur le schéma ci-dessous, le ''program counter'' est séparé du banc de registre, alors que le pointeur de pile est dedans. Le compteur IR est lui associé au ''program counter'', il est sortit du banc de registre. Le Z80 utilise lui aussi un incrémenteur séparé de l'ALU, qui est utilisé pour mettre à jour le ''program counter'', le pointeur de pile et un compteur de rafraichissement mémoire nommé IR sur le Z80 (pour rappel, le rafraichissement mémoire demande de balayer la mémoire d'adresse en adresse et été fait par le CPU à l'époque). De plus, il est utilisé pour les instructions INC et DEC qui incrémentent une opérande de 16 bits obtenue en combinant deux registres de 8 bits. En clair, l'incrémenteur du ''program counter'' a été réutilisé de beaucoup de manières originales. [[File:Z80 arch.svg|centre|vignette|upright=3|Microarchitecture du Z80.]] Le Z80 incorporait des instructions pour échanger le contenu des deux ensembles de registres, accumulateur inclus. Elles permettaient d'utiliser les registres d'interruption pour les programmes et réciproquement. En clair, cela doublait le nombre de registres si les interruptions n'étaient pas utilisées. * L'instruction EXX échangeait les deux fenêtres de registres généraux : les registres B, C, D, E, H et L devenaient les registres B', C', D', E', H' et L' et inversement. * L'instruction EX échangeait l'accumulateur et le registre d'état : les registres A,F devenait A',F' et inversement. Le fenêtrage de registre était modifié par l'instruction EXX, qui échangeait les deux fenêtres de registres. Pour l'implémenter, une bascule était ajouté au processeur, appelons-la la bascule INT. Elle était relié au bus d'adresse du banc de registre, dont elle mémorisait le bit de poids fort. L'instruction EXX inversait la valeur de la bascule INT. Il est aussi possible d'échanger le contenu des registres D,E et H,L avec une instruction dédiée, ce qui est là encore fait par deux bascules : une pour les registres D,E et une autre pour les registres H,L. Pour l'accumulateur et le registre d'état, le choix entre registre normal et registre d'interruption se faisait là encore par une seconde bascule appelée la bascule A. La bascule est reliée à un multiplexeur et un démultiplexeur, qui permet de choisir quel accumulateur relier à l'unité de calcul. L'instruction EX inverse le contenu de la bascule A. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=L'unité de contrôle | prevText=L'unité de contrôle | next=Les processeurs 8 bits et moins | nextText=Les processeurs 8 bits et moins }} </noinclude> aw6l0rv958lfk8aun8v93i5nr4pijsk 744179 744177 2025-06-05T17:43:32Z Mewtow 31375 /* Les architectures hybrides registres-accumulateur */ 744179 wikitext text/x-wiki Les architectures que nous avons vu précédemment dans ce cours disposent de registres pour les données, en plus du pointeur de pile, d'un ''program counter'', et de quelques autres. Elles sont appelées des '''architectures à registres''', terme qui trahit bien le fait qu'elles ont des registres généraux ou spécialisés pour stocker temporairement des données. Et si on leur a donné un nom, c'est parce qu'il existe des architectures qui ne sont pas dans cette catégorie. Il en existe plusieurs types, mais ce chapitre va se concentrer sur les '''architectures à accumulateur'''. [[File:Isaccumulator.png|vignette|Architecture à accumulateur.]] Les architectures à accumulateur sont centrées autour d'un registre architectural appelé l''''accumulateur'''. Il est utilisé pour toutes les opérations arithmétiques dyadiques, où il sert à la fois de source et de destination. Toutes les instructions dyadiques sont de type ''load-op'' : une opérande est lue depuis l'accumulateur, le second opérande est lu depuis la mémoire RAM, le résultat de l'instruction est automatiquement mémorisé dans l'accumulateur. Les instructions monadiques peuvent utiliser un opérande dans l'accumulateur, ou dans la mémoire RAM, les deux sont théoriquement possibles. La conséquence est que le nombre d'accès mémoire est drastiquement diminué : de 3 par instructions sur une architecture mémoire-mémoire, on passe à seulement un avec un accumulateur. Les opérations dyadiques ont besoin d'un seul accès mémoire pour lire la seconde opérande, les opérations monadique en font aussi un seul pour lire leur unique opérande. {|class="wikitable" |- ! Classe d'architecture ! Nombre d'accès mémoire par opération dyadique |- |- ! Architecture à accumulateur | Un accès mémoire par instruction, pour lire la seconde opérande |- ! Architecture à registres | Zéro si les opérandes sont dans les registres, un pour les opérations ''load-op'', LOAD et STORE. |} ==Le jeu d'instruction des architectures à accumulateur sans registres d'indice== L'accumulateur est adressé grâce au mode d'adressage implicite, de même que le résultat de l'opération. Par contre, les autres opérandes sont localisés avec d'autres modes d'adressage, et lues en mémoire RAM. Le résultat ainsi qu'un des opérandes sont adressés de façon implicite car dans l'accumulateur, seule la seconde opérande étant adressée directement. Grâce à l'accumulateur, une instruction ne fait qu'un seul accès mémoire maximum, ce qui rend le processeur très facile à implémenter. ===Les registres des anciennes architectures à accumulateur=== [[File:IBM 701console.jpg|vignette|IBM 701, console extérieure.]] Les architectures à accumulateur étaient communes dans les années 50-60. A l'époque, les ordinateurs étaient gigantesques, ils prenaient une pièce de bâtiment entière dans le pire des cas, une armoire entière dans le meilleur. Les ordinateurs de l'époque étaient surtout utilisés pour du calcul scientifique ou des tâches d’ingénierie demandant beaucoup de calcul, rarement pour de la compatibilité. Les nombres flottants n'étaient pas encore apparus. A la place, les ordinateurs de l'époque géraient des nombres entiers de grande taille, de 30 bits ou plus. En conséquence, l'accumulateur faisait facilement 30 à 60 bits. Par exemple, les ordinateurs de la Série scientifique IBM 700/7000 géraient des entiers de 36 bits, l’accumulateur faisait 38 bits : 36 bits plus deux bits pour les débordements. Au passage, de tels processeurs utilisaient l'adressage par mot, et non par byte. Historiquement, les premières architectures à accumulateur ne contenaient aucun autre registre que l'accumulateur. Ce n'est que dans les années 60 que de nombreuses architectures à accumulateur ont ajouté un second '''registre pour les multiplication/divisions'''. Un exemple est celui de l'IBM 701, qui incorporait un registre accumulateur de 38 bits et un registre multiplieur de 36 bits. Le registre mémorise le multiplieur lors d'une opération de multiplication. Il mémorise donc un opérande, pas le résultat. Il peut aussi décaler le multiplieur vers la droite/gauche, ce qui est utile pour exécuter la multiplication. C'est ce qui est fait sur l'IBM 7094. Une autre possibilité est que ce registre mémorise une partie du résultat de l'opération. Pour rappel, le résultat d'une multiplication/division est codé sur deux fois de bits que ses opérandes. Par exemple, multipliez deux opérandes de 30 bits, vous obtiendrez un résultat de 60 bits. Les 30 bits de poids faible du résultat vont dans l'accumulateur, les 30 bits de poids fort vont dans ce second registre. Les architectures à accumulateur parfois un '''registre pour le pointeur de pile''', utilisé pour gérer les fonctions/procédures. Les architectures à accumulateurs supportaient une pile d'adresse de retour, souvent une pile d'appel. Mais pour cela, il fallait mémoriser le pointeur de pile dans le processeur, ce qui demandait un registre dédié. ===L'adressage indirect avec l'accumulateur=== Les instructions LOAD et STORE existent bel et bien sur les architectures à accumulateur, mais n'ont pas les mêmes modes d'adressages. L'instruction LOAD copie une donnée de la RAM vers l'accumulateur, l'instruction STORE copie l'accumulateur dans une adresse. Les deux instructions n'ont pas besoin d'adresser l'accumulateur, qui est adressé de manière implicite, juste de préciser l'adresse à lire/écrire. Les architectures à accumulateur supportaient souvent le mode d'adressage indirect mémoire. Un exemple est celui des ordinateurs Data General Nova, qui sont des architectures à accumulateur et qui supportaient ce mode d'adressage. Les deux instructions LOAD et STORE existaient en deux versions, distinguées par un bit d'indirection. Si ce bit est à 0 dans l'opcode, alors l'instruction utilise le mode d'adressage absolu normal : l'adresse intégrée dans l'instruction est celle de la donnée. Mais s'il est à 1, alors l'adresse intégrée dans l'instruction est celle du pointeur. Cependant, la présence de l'accumulateur permettait d'utiliser l'adressage indirect à registre, pour gérer les pointeurs. Pour rappel, avec le mode d'adressage indirect à registre, l'adresse à lire/écrire est dans un registre. Ici, l'adresse à lire/écrire est prise dans l'accumulateur, seul registre disponible pour. L'adressage indirect est plus simple à implémenter pour l'instruction LOAD, car elle prend un seul opérande : l'adresse à lire. L'adresse à lire est placée dans l'accumulateur, la donnée lue est elle aussi chargée dans l'accumulateur. Pour l'instruction STORE, il faut fournir deux opérandes, l'adresse et la donnée à écrire, ce qui peut poser problème. Mais au pire, il est toujours possible d'utiliser l'adressage absolu ou indirect mémoire : l'adresse est dans l'instruction, la donnée à écrire dans l'accumulateur. ===L'encodage des instructions=== Sur une architecture à accumulateur l'encodage d'une instruction dyadique est assez simple, vu que l'accumulateur est adressé implicitement. La seconde opérande est localisée soit par une adresse mémoire (adressage absolu), soit est une constante (adressage immédiat). L'adresse mémoire est généralement assez longue, plus que l'opcode. {|class="wikitable" |+ Encodage d'une instruction dyadique |- ! rowspan="2" | Opcode | Adresse mémoire (adressage absolu) |- | Constante (adressage immédiat) |} L'encodage d'une instruction monadique est similaire. Si l'opérande est lue depuis la mémoire RAM, alors l'instruction est encodée comme une instruction dyadique. Il en est de même pour les instructions qui copient une constante dans l'accumulateur. Par contre, si l'opérande est dans l'accumulateur, alors il y a juste besoin d'encoder l'opcode. La majorité des instructions a besoin de préciser une adresse, rares sont celles qui s'en passent. Au vu de cet encodage, les architectures à accumulateur sont qualifiées d''''architectures à une adresse''' par abus de langage. Il est intéressant de contraster leur encodage avec les architectures à registres. Les architectures à registre doivent encoder deux opérandes en plus de l'opcode, avec éventuellement où enregistrer le résultat sur les architectures 3-adresses. Par contre, les opérandes sont généralement des noms de registre, ce qui prend moins de place qu'une adresse mémoire. A la rigueur, les instructions avec une constante immédiate prennent un peu plus de place, car elles doivent encoder un nom de registre en plus de la constante et de l'opcode. Les instructions ''load-op'' des processeurs CISC sont un peu dans le même cas, sauf qu'il faut remplacer la constante par une adresse, qui a généralement la même taille. Les instructions sont donc en moyenne plus courte sur les processeurs à registre, du fait de la présence de registres. ===Annexe : les toutes premières architectures à accumulateur : le Manchester Baby=== [[File:BabyArchitecture.png|vignette|Architecture de la Manchester Baby.]] Les architectures à accumulateurs sont apparues dès les débuts de l'informatique. Le tout premier ordinateur à programme enregistré en mémoire, le ''Manchester Baby'', était une architecture à accumulateur. Niveau interface, l'ordinateur avait une console avec 32 boutons, des interrupteurs et un écran de sortie sur lequel afficher les résultats. A l'intérieur, il y avait un processeur et une RAM de 32 adresses, fabriquée avec des tubes Williams (abordés dans une annexe à la fin du cours). Chaque adresse mémorisait 32 bits, qui pouvaient encoder soit un nombre, soit une instruction. Le programme devait tenir dans la RAM, avec une instruction par adresse maximum, ce qui limitait les programmes à 32 instructions maximum. Une instruction prenait donc 32 bits, 3 indiquaient quelle opération utiliser, 12 bits d'adresse servait à indiquer où se trouvent la seconde opérande en RAM, les 16 restants sont inutilisés. En théorie, les 12 bits d'adresse permettaient d'adresser 4096 adresses, mais seules 32 étaient réellement présentes. Le processeur avait un registre accumulateur de 32 bits, un ''program counter'' et un registre d'instruction. Il intégrait un additionneur dédié au ''program counter'', mais l'ALU n'avait pas d'additionneur. En conséquence, il ne gérait pas l'addition. A la place, il gérait la soustraction. Il pouvait cependant émuler l'addition à partir d'une soustraction. La soustraction était utilisée pour calculer le complément d'une opérande, et soustraire le complément revient à additionner. L'ALU était une ALU sérielle, à savoir qu'elle faisait les soustractions bit par bit. Le processeur supportait 7 instructions au total : la soustraction, des instructions de branchement et d'accès mémoire, rien d'autre. Les instructions de branchement utilisaient des modes d'adressage très particuliers, qu'on ne retrouve pas sur les ordinateurs modernes. Les branchements inconditionnels utilisaient une forme d'adressage mémoire indirect, pas les adressages usuels pour les branchements. Il n'y avait pas de branchements conditionnels, mais une ''SKIP instruction''. {|class="wikitable" |- ! SUB | Soustrait l'opérande mémoire de l'accumulateur. |- ! CMP | Skippe l'instruction suivante si l'accumulateur a une valeur négative. |- ! JMP | Branchement indirect mémoire. : * L'adresse de destination est lue depuis la mémoire. * L'adresse lue est intégrée dans l'instruction via adressage absolu. |- ! JRP | Branchement relatif indirect. * Lit une opérande depuis la mémoire, l'adresse est intégrée dans l'instruction via adressage absolu. * Additionne l'opérande lue au ''program counter''. |- ! LDN | Instruction LOAD. La donnée lue est inversée lors de la lecture, l'accumulateur contient le complément à deux de la donnée lue après la lecture. |- ! STO | Instruction STORE |- ! STOP | Éteint l'ordinateur. |} Le Manchester Mark 1 était une amélioration du Manchester Baby. Il utilisait 4500 tubes à vide. Le Manchester Baby était un prototype, mais il avait été pensé pour être étendu, notamment afin d'avoir plus de mémoire. C'est pour cela que ses adresses étaient codées sur 12 bits, malgré sa mémoire de seulement 32 mots. Le plan initial, à savoir utiliser une RAM de 4096 mots, a cependant été abandonné pour la Manchester Mark 1. A la place, la RAM a gardé la même taille, à savoir 32 nombres, mais a été complémentée par l’ancêtre du disque dur magnétique, à savoir un tambour magnétique. Le tambour magnétique contenait 40 pages, chacune ayant la même taille que la RAM. L'ordinateur gérait des nombres de 40 bits, mais les instructions étaient codées sur 20 bits. Le processeur gérait maintenant l'addition et quelques opérations logiques (ET et OU), en plus de la soustraction et de la comparaison. De plus, il intégrait deux registres dédiés aux multiplications : un pour le multiplicande, un autre pour le multiplieur. Ils étaient nommés D et R et étaient regroupés dans un seul tube Williams noté M. Cependant, les multiplications étaient réalisées en enchainant une série d'additions, dans l'additionneur-soustracteur. C'était là encore une architecture à accumulateur, sauf qu'elle intégrait aussi des registres d'indice. Les registres d'indices étaient au nom de deux et étaient notés B0 et B1. Lors du chargement d'une instruction, un registre d'indice était sélectionné grâce à un bit de l'instruction. Le contenu de ce registre d'indice était additionné à l'instruction , l'adresse encodée dedans pour être précis, et le résultat était envoyé sur le bus mémoire. La microarchitecture de la machine est illustrée ci-dessous. Elle a une ALU unique capable de faire plusieurs opérations, qui sont représentées dans des rectangles séparés. Les cercles dans le schéma suivant sont des tubes Williams, des écrans CRT modifiés de manière à servir de mémoire DRAM, dont le fonctionnement est détaillée dans le chapitre sur les mémoires historiques. Un tube Williams implémente un banc de registre complet, c'est à dire un groupe de 2 à 10, registres. L'accumulateur est noté A, les deux registres de multiplication sont regroupés dans le tube Williams M, les registres d'indice sont dans le tube noté B. Le tube Williams C regroupe le ''program counter'' et le registre d'instruction. L'additionneur sert à incrémenter le ''program counter'', mais aussi pour les branchements relatifs. La statistation est le nom donné au séquenceur, à l'unité de contrôle, décodeur d'instruction inclus. [[File:MM1Schematic French.svg|centre|vignette|upright=2.5|Architecture de la Manchester Mark 1.]] ==La micro-architecture des architectures à accumulateur sans registres d'indice== L'organisation interne d'une architecture à accumulateur est très différente de celle des processeurs à registre. Elle est plus ou moins la même pour tous ces processeurs, le point important étant que le chemin de données se résume à une ALU, un registre accumulateur et le bus de données. L'ALU est reliée au registre accumulateur, ainsi qu'au bus de données pour lire la seconde opérande, comme illustré ci-dessous. [[File:Accumulator.png|centre|vignette|upright=2|Accumulateur.]] ===L'unité de calcul et l'accumulateur=== Pour simplifier l'implémentation, le résultat est mémorisé dans un registre en sortie de l'unité de calcul. La raison est qu'on ne veut pas altérer l'accumulateur tant que le résultat final n'est pas totalement calculé. Rappelons que l'ALU ne fournit pas un résultat d'un seul bloc, mais que certains bits arrivent avant les autres, typiquement les bits de poids faible. Si le résultat était écrit dans l'accumulateur directement, il écraserait des bits de l’opérande en cours d'utilisation, ce qui fausserait le résultat. [[File:Accumulateur avec registre de sortie.png|centre|vignette|upright=2|Accumulateur avec registre de sortie]] Une autre solution utilisait un registre entre l'accumulateur et l'unité de calcul, appelé l’'''''accumulator latch'''''. Il remplace le registre en sortie de l'ALU, dans le sens où il permet d'écrire dans l'accumulateur sans effacer l'opérande, pendant que l’opération est en cours dans l'ALU. L'accumulateur est copié dans l’''accumulator latch'', avant que l'ALU démarre ses calculs. L'opérande est donc maintenue même si on commence à écrire le résultat dans l'accumulateur. Sur le 8085 d'Intel, l’''accumulator latch'' peut être initialisé avec une constante prédéfinie, ce qui permet d'implémenter certaines instructions très facilement. Par exemple, il peut être initialisé à 0, ce qui permet d'implémenter les instructions MOV et INC (incrémentation). Un MOV est équivalent à faire un OU entre le registre lu et 0. Une instruction INC initialise l'entrée de retenue de l'unité de calcul à 1, puis ajoute 0. La décrémentation est implémentée de la même manière, sauf que l’''accumulator latch'' est initialisé à -2 pour compenser l'entrée de retenue à 1. De plus, pour supporter les conversion de décimal à BCD, l’''accumulator latch'' peut être initialisé avec les constantes 0x00, 0x06, 0x60, or 0x66. L'''accumulator latch'' est relié à divers fils de commande provenant de l'unité de contrôle, qui décide quelle valeur d'initialisation utiliser en fonction de l'instruction décodée. [[File:Accumulator latch.png|centre|vignette|upright=2|Accumulator latch]] [[File:Chemin de données à un seul bus.png|vignette|Chemin de données à un seul bus]] De même, la seconde opérande, celle lue sur le bus de données, est mémorisée dans un registre en amont de l'ALU. C'était notamment très utile si le processeur utilisait une ALU plus courte que les opérandes, avec par exemple une ALU 4 bits pour un CPU 8 bits. Les anciens processeurs à accumulateur de type ''mainframe'' utilisaient des opérandes de grande taille, du genre 36 ou 48 bits, ce qui avait des conséquences sur l'unité de calcul utilisée, ainsi que sur la communication avec la mémoire. Il arrivait que de tels processeurs utilisaient des ALU sérielles, ou du moins octet-sérielles, plutôt qu'une véritable ALU 36 bits. Nous verrons aussi que c'est très utile sur les processeurs à accumulateur avec un bus interne unique, dans la suite du chapitre. ===La micro-architecture des architectures à accumulateur avec instructions LOAD/STORE=== Nous venons de voir comment est implémenté l'unité de calcul et l'accumulateur, et comment le tout est relié au bus de données. Mais cela ne permet que d'avoir un processeur à accumulateur rudimentaire, qui ne gére que des instructions arithmétiques et logiques. Il faut aussi gérer le cas des opérations LOAD/STORE et des modes d'adressages associés, mais c'est le séquenceur qui s'en occupe. Avec l'adressage absolu, les instructions LOAD et STORE ne font que connecter l'accumulateur au bus de données. L'instruction STORE nécessite de connecter l'accumulateur au bus de données, de manière à ce que le transfert des données se fasse de l'accumulateur vers le bus de données. L'instruction LOAD s'implémente de la même manière, sauf que le sens de transfert est inversé. Cependant, il existe une optimisation qui permet d'implémenter l'instruction LOAD sans ajouter de circuits. Pour cela, il suffit que l'unité de calcul gére les opérations ''pass through'', à savoir des opérations qui se contentent de recopier un opérande sur la sortie. Ici, l'idée est de recopier l'opérande provenant du bus de données. [[File:Architecture à accumulateur, microarchitecture.png|centre|vignette|upright=2|Architecture à accumulateur, microarchitecture]] Pour gérer nativement l'adressage indirect à registre, il suffit de connecter l'accumulateur au bus d'adresse. Le plus simple est d'ajouter un multiplexeur, comme illustré ci-dessous. La donnée lue est copiée dans l'accumulateur, ce qui fait qu'il vaut mieux utiliser un registre d’interfaçage, l'accumulateur n'étant pas utilisable à la fois pour le bus d'adresse et de données. [[File:Adressage indirect sur une architecture à accumulateur.png|centre|vignette|upright=2|Adressage indirect sur une architecture à accumulateur]] Pour finir, voyons comment le pointeur de pile et le ''program counter'' sont implémentés. Les architectures à accumulateur ont souvent des adresses de taille différente des données, ce qui fait qu'il vaut mieux utiliser un circuit incrémenteur dédié pour incrémenter le ''program counter'', plutôt que de l'incrémenter via l'unité de calcul. Les architectures à accumulateur ont parfois un pointeur de pile, qui gère une pile d'adresse de retour, pas une vraie pile d'appel. Aussi, le pointeur de pile est censé être incrémenté et décrémenté, pas plus. Pas d'addition ou de soustraction pour gérer des cadres de pile. Là encore, c'est la solution de l'incrémenteur séparé qui est retenue. Pour économiser des transistors, il n'y a qu'un seul incrémenteur partagé pour les deux. ==Les architectures à accumulateur à registres d'indice== Les architectures à accumulateur décrites dans la section précédente sont capables de faire de l'adressage indirect, mais n'incluent pas les modes d'adressage base + indice et absolus indicés, qui prennent une adresse et y ajoute un indice. Il s'agit des toutes premières architectures à accumulateur, comme les premiers ordinateurs IBM ou le fameux PDP-8. Mais par la suite, les processeurs à accumulateurs ont inclus un support des modes d'adressages indicés, grâce à des '''registres d'indice'''. ===Les registres d'indice=== Les registres d'indice stockent des indices de tableaux. Ils permettaient de supporter deux modes d'adressage : * Le '''mode d'adressage absolu indicé''' où une adresse fixe est additionnée à un indice variable. L'adresse fixe est intégrée dans l'instruction (adressage absolu), l'indice est dans un registre d'indice. * Le '''mode d'adressage base + indice''', où l'adresse est dans l'accumulateur et l'indice dans le registre d'indice. Les processeurs à accumulateur supportaient souvent des variantes des modes d'adressage précédents, où le registre d'indice était automatiquement incrémenté ou décrémenté à chaque utilisation. Au départ, ces processeurs n'utilisaient qu'un seul registre d'indice qui se comportait comme un second accumulateur spécialisé dans les calculs d'adresses mémoire. Le processeur supportait de nouvelles instructions qui utilisaient ce registre d'indice de façon implicite. Mais avec le temps, les processeurs finirent par incorporer plusieurs de ces registres. Les instructions de lecture ou d'écriture devaient alors préciser quel registre d'indice utiliser, en précisant un nom de registre d'indice, un numéro de registre d'indice. Il faut préciser que les registres d'indice ont une taille bien plus petite que l'accumulateur. Ils mémorisent des indices codés sur 16 bits ou moins, alors que l'accumulateur faisait typiquement 36 à 48 bits, parfois plus. La taille classique sur les anciens ''mainframes'' était de 15 bits, parfois moins. Il n'était pas rare de tomber sur des registres d'indice de 8 ou 9 bits. Leur petite taille rendait leur implémentation matérielle peu couteuse. Et c'est ce qui explique qu'ils étaient préférés à l'usage d'un second accumulateur. Un exemple est le cas du processeur Motorola 6809, un processeur à accumulateur qui contient deux registres d'indices nommés X et Y. L'accumulateur est noté D et fait 16 bits, il peut être parfois géré comme deux accumulateurs séparés A et B de 8 bits chacun. Il contenait aussi deux pointeurs de pile, l'un pour les programmes, l'autre pour le système d'exploitation, ainsi qu'un ''program counter''. Le registre de page était utilisé pour l'adressage absolu, comme vu dans le chapitre sur les modes d'adressage. [[File:6809 Internal Registers.svg|centre|vignette|upright=2|6809 Internal Registers]] Les processeurs IBM avaient autrefois plusieurs registres d'indice. Par exemple, l'IBM 704 avait trois registres d'indice de 15 bits. Leur contenu était soustrait de l'adresse absolue. Une instruction pouvait utiliser plusieurs registres d'indice pour adresser son opérande. Toute instruction utilisait trois bits pour sélectionner les registres d'indice utilisés. Fait assez original, lorsque plusieurs registres d'indice sont sélectionnés, le processeur n'additionne pas les trois registres à l'adresse de base. À la place, il fait un OU bit à bit entre les registres d'indice sélectionnés, et additionne le résultat à l'adresse. Les processeurs IBM à accumulateur ont fait ça sur toute la gamme IBM 700/7000, pour des raisons de compatibilité. Les processeurs suivants avaient 7 registres d'indices, mais conservaient les trois bits pour adresser les registres d'indices. Ils pouvaient fonctionner dans deux modes. Le premier mode est plus intuitif : les trois bits précisent un registre d'indice parmi les 7, qui est additionné avec l'adresse absolue. La valeur zéro indique qu'aucun registre d'indice n'est utilisé, ce qui explique qu'il y a 7 registres d'indice et non 8. Un second mode, compatible avec l'IBM 704, fait un OU logique entre les registres d'indice sélectionnés. Seuls les trois premiers registres d'indices peuvent être sélectionnés dans ce mode. Il y a deux instructions pour changer de mode : une pour passer en mode compatible, l'autre pour le quitter pour l'autre mode. Quelques rares processeurs à registres généraux ont utilisés des registres d'indice, en plus des registres généraux. Ce qui fait l'association que nous avons faite entre registres d'indice et architectures à accumulateur est imparfait, bien que solide sur le principe. Un exemple d'architecture de ce type sont les architectures de la série UNIVAC 1100/2200. Ils disposaient de 128 registres, qui étaient mappés en mémoire à partir de l'adresse mémoire 0, la majorité étant inaccessibles par le programmeur. Ils regroupaient 12 registres accumulateurs, 11 registres d'indice et 4 registres hybrides qui pouvaient servir soit de registre d'indice, soit de registres accumulateurs. ===La micro-architecture des architectures à accumulateur avec registres d'indice=== La présence de registres d'indice modifie grandement l'implémentation du processeur. En effet, il faut rajouter un banc de registre pour les registres d'indice. Le banc de registre est monoport, car on a besoin de lire ou d'écrire un indice à la fois. Et il faut aussi potentiellement rajouter de quoi faire les calculs d'adresse. Deux solutions sont possibles : une ALU dédiée aux calculs d'adresse, une seule ALU pour toutes les opérations. Dans le premier cas, il y a une ALU séparée associée aux registres d'indice. L'ALU et les registres d'indice sont placés en sortie du séquenceur, en-dehors du chemin de données, la sortie de l'ALU est directement connectée au bus d'adresse. L'unité de calcul d'adresse peut être utilisée pour incrémenter le ''program counter''. Un défaut de cette approche est qu'elle ne gère pas l'adresse indirect à registre. [[File:Chemin de données sans support des pointeurs, avec adressage absolu indicé.png|centre|vignette|upright=2|Chemin de données sans support des pointeurs, avec adressage absolu indicé]] Une autre option utilise un bus interne, qui interconnecte tout le chemin de données. Dans sa version la plus simple, il est relié à l'accumulateur, l'unité de calcul, le banc de registre d'indice et le bus de données. Avec cette solution, l'ALU est utilisé à la fois pour calculer les adresses et pour les instructions de calcul. En reliant le bus interne au bus d'adresse à travers un multiplexeur, on gère naturellement les adressages indirects. [[File:Architecture à accumulateur avec registres associés.png|centre|vignette|upright=2.5|Architecture à accumulateur avec registres associés]] Il faut noter que sur les architectures Von Neumann, le séquenceur est relié à ce bus interne. En effet, charger une instruction demande de passer par le bus mémoire, donc par l’intermédiaire de ce bus internet. Le ''program counter'' est envoyé sur ce bus pour lire l'instruction, puis l'instruction lue est recopiée dans le registre d'instruction. Le chargement d'une instruction est donc géré comme une lecture des plus classiques. De plus, cela permet d'incrémenter le ''program counter'' au niveau de l'unité de calcul entière. Le ''program counter'' est envoyé sur le bus interne, incrémenté par l'ALU, puis le résultat est recopié dans le ''program counter'' via le bus interne. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] ==Les processeurs bi-accumulateurs : le Motorola 6800== Le Motorola 6800 était un processeur 8 bits qui gérait des adresses de 16 bits. Il contenait deux accumulateurs nommés A et B, de 8 bits chacun. Il disposait aussi d'un registre d'indice, d'un pointeur de pile et d'un ''program counter'', tous les trois de 16 bits. Le registre d'état regroupait 6 bits, qu'on ne détaillera pas ici. [[File:MC6800 Processor Diagram.png|centre|vignette|upright=2|Interface et registres du MC6800.]] La présence des deux accumulateurs impactait surtout les instructions dyadiques. Les instructions monadiques avaient juste à préciser où se trouvait l'opérande : soit en RAM, soit dans le premier accumulateur, soit dans le second. Pour les opérations dyadiques, la gestion était totalement différente. En théorie, le premier opérande est dans un accumulateur, soit A, soit B. La seconde opérande vient soit de l'autre accumulateur, soit de la mémoire RAM. Et selon les instructions, tout variait. Pour l'addition, il y avait trois instructions. Les deux premières additionnaient un opérande provenant de la mémoire avec un accumulateur. L'instruction ADDA sélectionnait le premier accumulateur, l'instruction ADDB sélectionnait le second accumulateur. Mais une troisième instruction, l’instruction ABA, permettait d'additionner le contenu des deux accumulateurs. Pour les autres opérations, il n'était pas possible d'utiliser les deux accumulateurs en même temps. La seule possibilité était de faire une opération entre un accumulateur et un opérande venant de la mémoire. Toutes les instructions étaient en double, avec une copie par accumulateur. Par exemple, l'instruction ANDA faisait un ET entre l’accumulateur A et l'opérande mémoire, l'instruction ANDB faisait pareil avec l'accumulateur B. ==Les architectures hybrides registres-accumulateur== Il a existé quelques architectures qui étaient des hybrides entre architectures à accumulateur et architecture à registre. Elles avaient un accumulateur unique, couplé à un banc de registres généraux. D'autres registres étaient souvent présents, comme un registre d'état, des registres pour la pile, etc. Elles sont apparues assez tôt, dès les années 50. Et c'était à une époque où les ordinateurs étaient intégralement construits avec des tubes à vides et autres mémoires spécialisées. Par exemple, le Bull Gamma 3 était un ordinateur de type ''mainframe'' qui disposait de deux accumulateurs, de 5 registres généraux, de deux registres pour la pile, d'un registre à décalage utilisé pour les opérations arithmétiques et BCD, et d'un registre d'état rudimentaire de deux bits (un bit de signe, un bit pour les résultats de comparaison). Mais ces architectures sont restées assez confidentielles pendant les années 50 à 80. Par la suite, elles ont eu un regain de popularité durant les années 80-90. Elles ont alors servit de transition entre architectures à accumulateur proprement dites, et architectures à registres. Par exemple, les processeurs Intel 8 bits disposaient de 7 registres de 8 bits nommés A, B, C, D, E, F, H, L, SP. Ils correspondent respectivement à : * l'accumulateur A ; * six registres nommés B, C, D, E, H et L ; * le registre d'état F ; * le pointeur de pile SP. Sur ces processeurs, les instructions dyadiques devaient mettre leur premier opérande dans l'accumulateur, la seconde provenait soit des registres, soit de la RAM, soit d'une constante immédiate. Les opérations monadiques pouvaient lire leur opérande depuis l'accumulateur, les autres registres ou la RAM, tout était permis. Les registres d'indices disparaissaient sur ces architectures, en théorie. Les registres généraux pouvaient être utilisés comme registre d'indice ou pour stocker des opérandes, ils étaient assez versatiles pour servir de registres d'indices. La présence de registres a de nombreux avantages, comparé aux architectures à accumulateur pures. Les instructions arithmétiques sont plus rapide, lire un registre étant plus rapide qu'un accès RAM. Les performances sont donc augmentées. De plus, les instructions arithmétiques utilisant ces registres sont plus courtes : pas besoin d'encoder une adresse mémoire, un nom de registre suffit. Vu que les processeurs de l’époque avaient des instructions de taille variable, cela améliorait la densité de code. ===La micro-architecture des processeurs hybrides registres-accumulateur=== La micro-architecture de ces processeurs est très similaire à celle d'un processeur avec des registres d'indices. La seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Le banc de registre est systématiquement monoport, car il n'avait aucune raison d'être multiport. Pour les instructions dyadiques, seules à lire deux opérandes, il ne servait que pour la seconde opérande, la première était lue depuis l'accumulateur. Les processeurs hybrides registre-accumulateur se classent en deux types principaux : ceux qui ont un seul bus interne, et ceux qui en ont deux. Le premier cas est identique à celui vu précédemment pour les architectures à accumulateur avec registres d'indice, à la seule différence est que le banc de registre contient des registres généraux et non des registres d'indices. Afin de gérer l'adressage indirect à registre, le bus interne est connecté aux deux registres d’interfaçage mémoire. [[File:Architecture à accumulateur avec bus unique de type Von Neumann.png|centre|vignette|upright=2|Architecture à accumulateur avec bus unique de type Von Neumann]] Notons que cela permet aussi d'implémenter facilement les branchements indirects, car le bus interne permet d'échanger des adresses entre ''program counter'' et banc de registre. De même, il est possible d'utiliser l'ALU pour gérer les branchements indirects., en plus de l'utiliser pour incrémenter le ''program counter''. [[File:Single bus organization.jpg|centre|vignette|upright=2|Single bus organization]] Une autre solution utilisait deux bus internes : un connecté au bus de données, un autre relié au bus d'adresse. Le bus de commande mémoire était lui commandé par le séquenceur, l'unité de contrôle. L'intermédiaire entre ces deux bus était le banc de registre, ainsi que les autres registres. Le banc de registre était connecté aux deux bus interne, avec un port de lecture relié au bus d'adresse, un port de lecture-écriture relié au bus de données. Le port de lecture était utilisé pour l'adressage indirect, l'autre l'était pour le reste. [[File:Proz1-e.png|centre|vignette|upright=2|Intérieur d'un processeur.]] L'organisation à deux bus simplifiait la gestion du ''program counter'' et le chargement des instructions. Le ''program counter'' était soit séparé du banc de registre, soit placé dans le banc de registre. Les deux solutions étaient utilisés, tout dépend du processeur. Il faut noter que si le ''program counter'' est intégré au banc de registres, alors la microarchitecture du processeur est bien plus simple. L'envoi du ''program counter'' sur le bus d'adresse utilise le port de lecture relié au bus d'adresse, qui sert aussi pour l'adressage indirect. L'économie de circuits, sans compter la simplicité d'implémentation que cela implique, explique sans doute que la technique a été utilisée sur quelques processeurs anciens. Le ''program counter'' était généralement incrémenté par l'ALU, ce qui explique qu'il soit connecté au bus interne pour les données. La connexion est aussi utile pour gérer les branchements indirects, qui copient un registre dans le ''program counter'', ainsi que les branchements relatifs (addition dans l'ALU), voire les branchements directs (l'adresse vers laquelle brancher est envoyée en entrée de l'ALU et propagée en sortie avec une opération ''pass through''). [[File:Connexion du program counter sur les bus avec PC dans le banc de registres.png|centre|vignette|upright=2|Connexion du program counter sur les bus avec PC dans le banc de registres]] ===Les registres d'interruption avec un processeur hybride-accumulateur : l'exemple du Z80=== Un exemple de processeur registre-accumulateur à deux bus interne est le Z80, un processeur fortement inspiré des CPU Intel 8 bits. Il a un jeu d'instruction similaire, mais a diverses améliorations par rapport au design original. Notamment, le processeur a des registres séparés pour les interruptions. Sur le Z80, les registres généraux sont dupliqués avec 6 registres pour les interruptions et 6 registres pour les programmes autres. Leur copie pour les interruptions sont nommées B', C', D', E', H', L'. Les 12 registres sont placés dans le banc de registre, ce qui implique que le fenêtrage de registres est utilisé pour gérer la séparation entre registre d'interruption et normaux. Il faut noter que l'accumulateur et le registre d'état sont aussi dupliqués, leurs copies étant nommées A' et F'. Mais leur duplication se fait autrement que par fenêtrage de registre. En plus des registres précédents, le Z80 incorporait deux registres d'indice nommés X et Y, ainsi qu'un pointeur de pile SP et un ''program counter'' PC. Ils n'étaient pas dupliqués pour les interruptions. Les registres d'indice étaient reliés à une unité de calcul d'adresse. L'unité de calcul d'adresse prenait deux opérandes : un indice, et une adresse mémoire provenant soit du banc de registre, soit de l'accumulateur. En clair, l'unité de calcul d'adresse faisait le lien entre les deux bus internet : le bus de données interne en entrée, le bus d'adresse en sortie. À l'intérieur du processeur, tous les registres étaient regroupés dans un banc de registre unique, sauf les accumulateurs, les registres d'état et le ''program counter''. Bien que ce ne soit pas indiqué sur le schéma ci-dessous, le ''program counter'' est séparé du banc de registre, alors que le pointeur de pile est dedans. Le compteur IR est lui associé au ''program counter'', il est sortit du banc de registre. Le Z80 utilise lui aussi un incrémenteur séparé de l'ALU, qui est utilisé pour mettre à jour le ''program counter'', le pointeur de pile et un compteur de rafraichissement mémoire nommé IR sur le Z80 (pour rappel, le rafraichissement mémoire demande de balayer la mémoire d'adresse en adresse et été fait par le CPU à l'époque). De plus, il est utilisé pour les instructions INC et DEC qui incrémentent une opérande de 16 bits obtenue en combinant deux registres de 8 bits. En clair, l'incrémenteur du ''program counter'' a été réutilisé de beaucoup de manières originales. [[File:Z80 arch.svg|centre|vignette|upright=3|Microarchitecture du Z80.]] Le Z80 incorporait des instructions pour échanger le contenu des deux ensembles de registres, accumulateur inclus. Elles permettaient d'utiliser les registres d'interruption pour les programmes et réciproquement. En clair, cela doublait le nombre de registres si les interruptions n'étaient pas utilisées. * L'instruction EXX échangeait les deux fenêtres de registres généraux : les registres B, C, D, E, H et L devenaient les registres B', C', D', E', H' et L' et inversement. * L'instruction EX échangeait l'accumulateur et le registre d'état : les registres A,F devenait A',F' et inversement. Le fenêtrage de registre était modifié par l'instruction EXX, qui échangeait les deux fenêtres de registres. Pour l'implémenter, une bascule était ajouté au processeur, appelons-la la bascule INT. Elle était relié au bus d'adresse du banc de registre, dont elle mémorisait le bit de poids fort. L'instruction EXX inversait la valeur de la bascule INT. Il est aussi possible d'échanger le contenu des registres D,E et H,L avec une instruction dédiée, ce qui est là encore fait par deux bascules : une pour les registres D,E et une autre pour les registres H,L. Pour l'accumulateur et le registre d'état, le choix entre registre normal et registre d'interruption se faisait là encore par une seconde bascule appelée la bascule A. La bascule est reliée à un multiplexeur et un démultiplexeur, qui permet de choisir quel accumulateur relier à l'unité de calcul. L'instruction EX inverse le contenu de la bascule A. <noinclude> {{NavChapitre | book=Fonctionnement d'un ordinateur | prev=L'unité de contrôle | prevText=L'unité de contrôle | next=Les processeurs 8 bits et moins | nextText=Les processeurs 8 bits et moins }} </noinclude> hjcrof2knyzbju4xvjy6hxg9kbc5r35 Astrologie/L'interprétation d'un thème astral/Astrologie dynamique/révolution solaire 0 82413 744051 743775 2025-06-03T16:15:39Z Kad'Astres 30330 + Cat 744051 wikitext text/x-wiki La révolution solaire est un outil astrologique utilisé pour analyser les tendances, événements et dynamiques personnelles d'une année à venir, en se basant sur le retour du Soleil à sa position exacte (en degré, minute, et seconde) qu’il occupait au moment de la naissance. L’interprétation se fait en combinant plusieurs éléments : :1. Ascendant de révolution solaire :Donne le ton général de l’année : votre attitude, comment vous êtes perçu·e, votre manière d’agir. :2. Planètes dans les maisons :Montre où se concentreront les énergies. :Exemple : Mars en Maison 6 = dynamisme au travail, mais attention au stress. :3. Aspects planétaires dans la révolution :Révèlent les tensions ou harmonies spécifiques de l’année. :4. Superposition avec le thème natal :On compare la révolution solaire avec le thème natal pour voir comment les événements de l’année s’insèrent dans votre chemin de vie global. :5. Maître de l’Ascendant :Son placement et ses aspects sont cruciaux : il colore la direction de l’année. [[Catégorie:Astrologie]] dezuw3m4qr80f6fn021zj1awttmc5vw Astrologie/L'interprétation d'un thème astral/Astrologie dynamique/directions secondaires 0 82414 744049 743774 2025-06-03T16:14:24Z Kad'Astres 30330 + Cat 744049 wikitext text/x-wiki Il existe deux méthodes principales pour calculer les directions secondaires, aussi appelées progressions secondaires : la progression des planètes par rapport aux positions natales et la création d'un nouveau thème progressé. [[Catégorie:Astrologie]] 56t83q7t3quosat9oixeywah0sx8qbx Astrologie/L'interprétation d'un thème astral/Astrologie dynamique/transit 0 82415 744050 743776 2025-06-03T16:15:03Z Kad'Astres 30330 + Cat 744050 wikitext text/x-wiki Un transit se produit lorsque les positions actuelles des planètes (dans le ciel) forment un aspect (comme une conjonction, un carré, une opposition, etc.) avec les positions des planètes, ou des points sensibles, du thème astral de naissance. [[Catégorie:Astrologie]] tigs4sruzgtcnuufg3c0oo0o2n8mz4i Astrologie/Préliminaires astronomiques/La mesure du temps/Calcul du temps sidéral à partir de l'heure légale 0 82416 744048 743944 2025-06-03T16:12:02Z Kad'Astres 30330 + Cat 744048 wikitext text/x-wiki On utilise l'équation du temps pour convertir le temps des horloges (temps solaire moyen) en temps apparent. Puis on convertit le temps solaire vrai en temps sidéral. [[Catégorie:Astrologie]] ngly8bujginorvplr60ppwpcoqmq23q 744067 744048 2025-06-03T18:59:01Z Kad'Astres 30330 744067 wikitext text/x-wiki {{SI|refonte totale}} On utilise l'équation du temps pour convertir le temps des horloges (temps solaire moyen) en temps apparent. Puis on convertit le temps solaire vrai en temps sidéral. [[Catégorie:Astrologie]] gvgx38mixh3ut5thlxzh8xrrm3p3kqp 744071 744067 2025-06-03T19:13:39Z Kad'Astres 30330 Contenu remplacé par « {{SI|refonte totale}} » 744071 wikitext text/x-wiki {{SI|refonte totale}} ehonxiv34l7r9zetnh7ih45v7soi8vy Neurosciences/La barrière hémato-encéphalique 0 82423 744031 743941 2025-06-03T13:35:48Z Mewtow 31375 /* L'entrée du fer dans le cerveau */ 744031 wikitext text/x-wiki Le cerveau est séparé de la circulation sanguine, par une '''barrière hémato-encéphalique''' qui isole le cerveau du reste du corps. Elle est présente sur tous les vaisseaux sanguins cérébraux, ou presque. Les molécules sanguines ne peuvent pas toutes passer à travers la barrière hémato-encéphalique : si certaines le peuvent, d'autres ne le peuvent pas. On dit que la barrière hémato-encéphalique a une '''perméabilité sélective'''. C'est d'ailleurs la raison d'être de la barrière hémato-encéphalique : empêcher le passage de "molécules nuisibles" à travers les capillaires, pour éviter qu'elles passent dans le cerveau. Les ions (calcium, potassium, sodium, et autres) ne peuvent pas traverser cette barrière, leur concentration étant importante pour le bon fonctionnement des potentiels d'action. D'autres molécules importantes, comme le glucose ou d'autres nutriments, peuvent la traverser. Beaucoup de médicaments ne peuvent pas passer la barrière hémato-encéphalique, ce qui est parfois un avantage, parfois un défaut. C'est un défaut si la molécule a le potentiel d'agir positivement sur le cerveau, mais que la barrière hémato-encéphalique lui empêche d'rentrer. Par exemple, imaginons qu'on découvre une molécule thérapeutique qui permettrait d'augmenter la neurogenèse (la fabrication de nouveaux neurones). Si elle passait à travers la barrière hémato-encéphalique, elle pourrait soigner des maladies comme Alzheimer. Mais elle ne servirait à rien si elle ne pouvait pas rentrer dans le cerveau ! À l'inverse, ce peut être un avantage dans certains cas. Par exemple, une molécule noradrénergique utilisée pour traiter les troubles du rythme cardiaque ne devrait, idéalement, pas agir sur le cerveau. Si elle ne passe pas à travers la barrière hémato-encéphalique, tout va pour le mieux : la molécule n'agira pas sur le cerveau, ce qui fait des effets secondaires d'évités. Par contre, si ce n'est pas le cas, cela pourrait causer des effets secondaires neurologiques ou psychiatriques assez graves. : Avant de poursuivre, sachez que nous utiliserons souvent l'abréviation, BHE pour désigner la barrière hémato-encéphalique. ==La barrière hémato-encéphalique : les capillaires cérébraux== La barrière hémato-encéphalique se situe au niveau des vaisseaux sanguins du système nerveux, à quelques exceptions. Les exceptions en question sont des vaisseaux où la barrière hémato-encéphalique n'existe pas, mais ils sont très rares. Pour être précis, les vaisseaux sanguins protégés par la barrière hémato-encéphalique sont les capillaires, à savoir les petits vaisseaux suffisamment fins pour laisser passer de l'oxygène, du CO2, des nutriments, quelques petites molécules. Les capillaires ne doivent pas être confondus avec les artères et les veines, des vaisseaux plus gros. La différence principale est que les capillaires sont composés d'une unique couche de cellules jointes, juxtaposées les unes à côté des autres (l'ensemble forme ce qu'on appelle un épithélium). Les artères ajoutent plusieurs couches en plus de l'épithélium, dont une couche de muscles qui aident à contracter ou dilater l'artère, et un second épithélium qui enveloppe l'artère. Même chose pour les veines, avec cependant des couches en plus. Les artères et veines du système nerveux ne sont pas différentes de celles trouvées dans le reste du corps. Par contre, les capillaires cérébraux sont totalement différents sur deux points. ===Des capillaires continus protégés par des astrocytes=== La barrière hémato-encéphalique est formée par deux choses : le vaisseaux capillaire lui-mêmes, et une couche protectrice d'astrocytes tout autour. La première barrière est liée au fait que les capillaires du système nerveux central sont moins étanches que les capillaires normaux. La seconde barrière est formée par les astrocytes, qui entourent les vaisseau sanguins. [[File:Blood brain barrier.png|centre|vignette|upright=2|Barrière hémato-encéphalique.]] Les capillaires peuvent se classer en trois types, suivant la manière dont l’épithélium est formé : capillaires sinusoïdaux, fenêtrés et continus. La différence est que les deux sont perclus de trous, mais pas le dernier. Dans les '''capillaires sinusoïdaux''', les cellules de l'épithélium sont liées les unes aux autres, grâce à des espèces de crochets moléculaires, mais d'une manière assez lâche. Les crochets attachent les cellules à leurs voisines, mais laissent des espaces entre les cellules, qui peut prendre la forme de fentes. Cela permet de laisser des cellules comme des globules blancs et des globule rouges, des grosses protéines, mais ils peuvent aussi malheureusement laisser passer les virus et quelques toxines. [[File:202104 Sinusoidal capillary.svg|centre|vignette|upright=1|Capillaires sinusoïdal.]] Les capillaires fenêtrés et continus ont des cellules collées les unes aux autres par des jonctions communicantes, les mêmes que celles qui servent pour les synapses électriques. Elles sont beaucoup plus nombreuses que les crochets moléculaires des capillaires normaux, ce qui colle mieux les cellules du capillaire. En conséquence, les espaces entre cellules n'existent pas, ce qui ne permet pas de laisser passer des cellules, virus ou protéines. Mais par contre, les '''capillaires fenêtrés''' ont des pores qui traversent les cellules du vaisseaux sanguin et permettent de laisser passer de grosses molécules, comme des protéines, mais aussi des virus et autres bactéries de petite taille. [[File:202104 Fenestrated capillary.svg|centre|vignette|upright=1|Capillaires fenêtré.]] Les '''capillaires continus''' ne laissent ni espace entre cellules, ni pore, ni quoique ce soit. En conséquence, ils sont vraiment imperméables, au point qu'ils fournissent une première barrière contre les agressions extérieures, notamment contre les virus, les bactéries ou les toxines de grande taille. De tel capillaires ne se trouvent qu'en deux endroits : les muscles squelettiques, et le système nerveux. La première barrière hémato-encéphalique est le fait que tous les capillaires du système nerveux sont des capillaires continus. [[File:202104 Continuous capillary.svg|centre|vignette|upright=1|Capillaires continu.]] Ensuite, la seconde couche est formée par les astrocytes qui entourent les vaisseaux. Plus précisément, les capillaires cérébraux ne sont pas entourés de muscles, comme leurs congénères, mais sont recouverts par des astrocytes et des péricytes. Le tout forme une double couche : une première couche formé par le vaisseau sanguin, une seconde couche formée par astrocytes. Une molécule qui souhaite passer cette barrière doit donc travers plus d'obstacles qu'ailleurs. La protection est meilleure comparé à la paroi d'un vaisseau sanguin, les membranes astrocytaires faisant office de renforcement. [[File:Blood Brain Barrier.jpg|centre|vignette|upright=2.0|Barrière hémato-encéphalique]] ===Les espaces périvasculaires/de Virchow–Robin=== Outre la barrière hémato-encéphalique, certains vaisseaux sanguins cérébraux sont entourés par un manchon rempli de fluide : l''''espace périvasculaire''', aussi appelé ''espace de Virchow–Robin''. Ils sont surtout présents sur les vaisseaux des méninges, dans les couches situées sous l'arachnoïde et la pie-mère. Mais on en trouve aussi autour des vaisseaux des ganglions de la base et de quelques autres vaisseaux. Le cas le plus important est de loin les vaisseaux qui alimentent les organes circumventriculaires, à savoir des aires cérébrales qui ne sont pas protégées par la barrière hémato-encéphalique, sans doute pour assurer leur protection immunologique. On en trouve aussi en dehors du cerveau, dans le foie, le thymus et quelques autres organes, mais ceci est une autre histoire... Les espaces périvasculaires possèdent des fonctions variées, qui vont de l'immunité à la régulation du transfert d'ions et de solutés. Ils servent, entre autres, de protection immunologique. Preuve en est la présence d'un grand nombre de globules blancs, surtout lors d'infections : lymphocytes T et B, monocytes, etc. Mais leur rôle principal est la régulation des échanges de fluide avec le cerveau, de permettre un échange sang<->cerveau aisé des solutés, ions et autres petites molécules solubles. ==Le passage des molécules à travers la barrière hémato-encéphalique : généralités== La barrière hémato-encéphalique est donc composée des capillaires sanguins du cerveau, parfois recouvert par une couche d'astrocytes. Les cellules des capillaires sanguins sont appelées des '''cellules endothéliales'''. Les molécules doivent donc traverser une couche de cellules endothéliales, pour ensuite être absorbée par les astrocytes qui s'occupent de métaboliser ce qui doit l'être. La traversée d'une cellule endothéliale demande que la molécule traverse la membrane de cette cellule deux fois : une fois pour le passage sang->cellule endothéliale, une seconde fois pour sortir de la cellule endothéliale et rentrer dans le cerveau. Il y a donc deux passages à travers une membrane cellulaire, et cela nous amène à parler plus en détail des membranes cellulaires. Il existe divers mécanismes qui permettent à des molécules de traverser les membranes cellulaires des cellules endothéliales. Les mécanismes sont résumés dans le schéma ci-dessous. Nous allons les détailler un par un dans ce qui suit, mais les images devraient vous donner une petite idée de comment fonctionnent ces mécanismes. [[File:Blood-brain barrier transport en.png|centre|vignette|upright=2.5|Mécanismes de transport à travers la barrière hémato-encéphalique.]] Les mécanismes en question peuvent se classer en deux types. Les mécanismes de '''transport passifs''' utilisent un gradient de concentration, ce qui permet de faire passer une molécule d'un endroit où elle est très concentrée vers un endroit où elle l'est moins. Ils ne consomment pas d'énergie. A l'inverse, les mécanismes de '''transport actif''' consomment de l'énergie sous forme d'ATP, mais sont capables d'aller contre un gradient de concentration. Pour donner un exemple, les pompes ioniques sont des mécanismes de transport actif, les canaux ioniques sont du transport passif. Il existe une sorte d'équivalent mais pour les molécules plus grosses. ===La diffusion simple et le transport paracellualire=== Les deux mécanismes de transport les plus simples sont le transport paracellulaire et la diffusion simple. Avec ceux deux-là, de très petites molécules peuvent passer la BHE directement, en suivant un gradient de concentration, sans rencontrer d'obstacle digne de ce nom. La BHE est naturellement perméable pour ces petites molécules. Ce sont donc des mécanismes de transport passif. Le premier est le '''transport paracellulaire''', où les molécules passent entre les cellules endothéliales des capillaires sanguins. Les cellules endothéliales sont certes collées les unes au autres, mais pas parfaitement. Il reste toujours quelques espaces qui peuvent laisser passer de petites molécules. Le terme paracellulaire est assez parlant : para- pour dire à côté, et cellulaire. Cependant, dans le cerveau, ce mécanisme de transport est rendu impossible. Les capillaires sanguins sont continus, il n'y a pas d'espace entre les cellules endothéliales. Les cellules endothéliales sont collées les unes au autres grâce à des jonctions communicantes et autres jonctions cellulaires, qui ne laissent presque pas d'espace libre. En conséquence, le transport paracellulaire est empêché, ce qui en fait un premier mécanisme de protection, une première barrière hémato-encéphalique. Les molécules du sang doivent donc traverser les cellules endothéliales, pas passer à côté. Le second mécanisme de transport passif est la '''diffusion simple'''. Avec elle, une molécule passe à travers la barrière hémato-encéphalique sans rencontrer d'obstacles, comme dans du beurre, sans recourir à des canaux ioniques ni quoique ce soit d'équivalent. [[File:Scheme simple diffusion in cell membrane-fr.svg|centre|vignette|upright=2|Diffusion simple.]] Pour comprendre quelles molécules peuvent traverser ainsi, faisons un rappel rapide sur les membranes cellulaires, ainsi que sur les molécules hydrophobes et hydrophiles. Les molécules sont souvent classés en molécules hydrophiles (attirées par l'eau) et hydrophobes (repoussées par l'eau). Le caractère hydrophile et hydrophobe est lié à des interactions électriques avec les molécules d'eau. Les molécules hydrophiles sont généralement polaires, avec une charge positive à un côté de la molécule et un côté négatif de l'autre. Par contre, les molécules hydrophobe sont généralement neutres. Les molécules hydrophiles se dissolvent très bien dans l'eau, alors que les molécules hydrophobes ne se dissolvent pas, et cela n'a rien de surprenant. Par contre, le caractère hydrophobe/hydrophile a aussi un impact sur la dissolution dans des graisses, les lipides. Les molécules hydrophobes sont généralement liposolubles, ce qui veut dire qu'elles se dissolvent dans les graisses, les lipides. A l'inverse, les molécules hydrophiles ne se dissolvent pas dans les graisses. Et il se trouve que la membrane cellulaire est composée d'une double couche de lipides ! Chaque molécule de lipide a une tête hydrophile (attirée par l'eau), et une queue hydrophobe (qui est repoussée par l'eau). La membrane a donc un cœur hydrophobe et un extérieur hydrophile. Les molécules hydrophiles ne traversent pas le cœur hydrophobe, car elles ne se dissolvent pas dans les lipides. Par contre, les molécules hydrophobes traversent la membrane cellulaire sans trop de soucis. La traversée d'une membrane cellulaire n'est donc pas la même entre une molécule hydrophobe et une molécule hydrophile. [[File:Fluid Mosaic.svg|centre|vignette|upright=2|Membrane cellaulaire.]] La diffusion simple n'est donc possible que si la molécule peut se dissoudre dans la membrane cellulaire, donc se dissoudre dans des lipides. En clair, c'est limité aux molécules hydrophobes, liposolubles. De plus, les molécules doivent être assez petites, les grosses molécules ne peuvent pas traverser facilement. Une molécule plus grosse que la membrane aura du mal à se dissoudre dedans. Pour résumer : diffusion simple possible seulement pour les molécules hydrophobes assez petites. L'exemple le plus simple est celui de l'oxygène. Les gaz dissous dans le sang traversent presque tous la BHE : oxygène, mais aussi CO2, azote, etc. Mais cela concerne aussi des molécules. Par exemple, l'éthanol (l'alcool) traverse les membranes cellulaire sans aucun problème, y compris la BHE. Comme autre exemple, les stéroïdes traversent les membranes cellulaires sans problèmes, et cela vaut aussi bien pour les hormones sexuelles que le cortisol. Hormones sexuelles et cortisol rentrent dans le cerveau sans problème, ils traversent la barrière hémato-encéphalique. Par contre, des molécules importantes ne passent pas diffusion libre : l'eau, le glucose, les acides aminés, les protéines, les ions. Vous avez bien lu : l'eau ne traverse pas les membranes cellulaires. Et c'est évident, car l'eau est hydrophile. Le glucose est aussi concerné car il se dissous bien dans l'eau, et vous pouvez le constater en mettant du sucre dans de l'eau. Les ions sont naturellement dissous dans l'eau, donc hydrophiles. Les acides aminés et protéines sont soit trop gros, soit trop hydrophiles pour traverser la membrane cellulaire. Les molécules hydrophiles ne peuvent pas traverser les membranes cellulaires avec la diffusion simple, pas plus que les très grosses molécules. Les ions sont concernés, car les ions étant par nature dissous dans l'eau, ils sont hydrophiles. Les molécules hydrophiles doivent donc traverser les membranes cellulaires par un autre mécanisme. Voyons lesquels. ===Les transporteurs transmembranaires=== Les molécules hydrophiles peuvent traverser les membranes cellulaires grâce à des protéines transmembranaires, à savoir qui traversent la membrane cellulaire de part en part. Une partie de ces protéines transmembranaires permettent à une molécule de traverser la membrane cellulaire, d'où leur nom de '''transporteurs transmembranaires''', simplifié en transporteurs. Nous avons déjà vu des transporteurs transmembranaires dans ce cours : les pompes et canaux ioniques en sont ! Ce sont juste des transporteurs spécialisées dans le transport des ions, comme on aurait pu le deviner. Les petites et grosses molécules utilisent des transporteurs différents des canaux et pompes ioniques, mais qui fonctionnent sur le même principe. Il existe des '''transporteurs actifs''', qui demandent de l'énergie sous forme d'ATP pour fonctionner. Ils peuvent fonctionner même en l'absence de gradient de concentration, voire fonctionner même si le gradient de concentration est défavorable. La plupart des transporteurs actifs de la BHE visent à rejeter des molécules indésirables dans le sang. Par exemple, de nombreuses pompes ioniques visent à rejeter des ions dans le sang. Si ces ions rentrent dans la cellule endothéliale, ils seront rejetés par ces pompes. Les pompes en question portent des noms assez complexes, la plus connue étant ceux de la famille des ''Organo anion transporters''. Et il existe aussi des pompes non-ioniques, pour des molécules indésirables plus grosses. Un exemple est celui de la ''Glycoprotéine P'', qui empeche de nombreux médicaments de traverser la BHE, sans compter qu'elle rejette aussi de nombreuses molécules organiques. Si les transporteurs actifs sont des pompes qui rejettent des molécules dans le sang, d'autres transporteurs servent au contraire à faciliter l'entrée de molécules dans le cerveau. La plupart sont des '''transporteurs passifs''', à savoir qu'ils demandent un gradient de concentration pour fonctionner. Ils servent en quelque sorte de sas d'entrée, qui permet aux molécules de traverser la membrane si le gradient de concentration est favorable. Les molécules suivent le gradient de concentration et vont vers la zone la moins concentrée, mais seulement si le sas d'entrée/transporteur est ouvert. En quelque sorte, ce sont l'équivalent des canaux ioniques ouvert/fermés mais pour les grosses molécules. Pour distinguer ce mécanisme de transport de la diffusion simple, on dit que les canaux ioniques et transporteurs font de la '''diffusion facilitée''', dans le sens où le transporteur/canal ionique facilite la traversée de la membrane. Le processus d'entrée via un transporteur se fait en quelques étapes. Pour commencer, la molécule va se lier au transporteur, de la même manière qu'un neurotransmetteur se lie à son récepteur. Suite à cette liaison, le transporteur va être déstabilisé par diverses interactions électriques avec la molécule. Il va changer de forme et se reconfigurer. Cette reconfiguration fait que la molécule, auparavant sur la face extérieure, se retrouve sur la face intérieure de la membrane cellulaire. Enfin, la molécule se détache : elle a traversé la membrane. [[File:Scheme facilitated diffusion in cell membrane-fr.svg|centre|vignette|upright=2.5|Diffusion facilitée : canal ionique à gauche, transporteurs à droite.]] Les transporteurs servent de portes d'entrées qui permettent le passage des molécules à travers une membrane cellulaire. En conséquence, ils sont finement régulés de manière à ne laisser les molécules qu'avec parcimonie, suffisamment pour ne pas avoir de déficience cérébrale, mais pas assez pour perturber le fonctionnement cérébral. Par exemple, le passage des ions est sévèrement contrôlé, afin de protéger le cerveau des variations de concentration ionique du sang. Par exemple, suite à un repas trop salé, la concentration intracérébrale en sodium doit rester la même, le sodium ne doit pas traverser la barrière-hémato-encéphalique. A l'inverse, lors d'un manque de sodium intra-cérébral, la barrière hémato-encéphalique laissera passer ces ions sodium. La régulation de l'équilibre ionique du cerveau est assez simple : il suffit d'ouvrir ou de fermer des canaux ioniques selon les besoins. ===Le transport vésiculaire=== Il existe aussi un dernier mode de transport, appelé le '''transport vésiculaire''', qui est particulièrement adapté au transport de grosses molécules. Avec lui, les molécules peuvent traverser une cellule endothéliale en un seul passage, sans avoir à traverser de membrane cellulaire proprement dit. Les molécules sont transportées à travers la barrière hémato-encéphalique dans un sac de lipides appelé une vésicule. La vésicule se forme par invagination de la membrane cellulaire, qui se replie sur elle-même pour former une vésicule. La vésicule traverse alors la cellule endothéliale, puis se colle sur la membrane de l'autre côté. Elle fusionne alors avec la membrane, avec l'aide d'un paquet d'enzymes. La fusion relâche le contenu de la vésicule dans le milieu ambiant, dans le cerveau. [[File:Vesicle Budding, Motility and Fusion.jpg|centre|vignette|upright=2|Transport par vésicules intra-cellulaires. La vésicule se forme à gauche par invagination de la membrane cellulaire, la vésicule traverse la cellule, puis fusionne avec la membrane de l'autre côté.]] ==L'entrée des molécules dans le cerveau : quelques exemples== La BHE laisse passer certaines molécules via l'intermédiaire de transporteurs, du transport vésiculaire et de la diffusion simple. Outre les canaux ioniques, la BHE dispose de transporteurs passifs pour le glucose, mais aussi pour l'eau (des aquaporines), ainsi que pour les acides aminés essentiels. Dans ce qui va suivre, nous allons voir quelques exemples, en étudiant le cas du cuivre et du fer. L'exemple du cuivre aide à faire comprendre comment les transporteurs permettent de faire passer des molécules du sang au cerveau. L'exemple du fer est un cas particulier qui mélange transporteurs et transport vésiculaire. ===L'entrée du cuivre dans le cerveau=== Le premier exemple, que nous allons voir en détail, est le transport du cuivre. Pour rappel, pour traverser la barrière hémato-encéphalique, il faut traverser deux membranes cellulaires : celle entre le sang et la cellule du capillaire sanguin, celle entre le capillaire sanguin et le cerveau. Pour cela, le cuivre a deux transporteurs Le premier permet au cuivre de passer du sang à l'intérieur des cellules des vaisseaux sanguins, il porte le nom de ''High affinity copper uptake protein 1'', aussi appelé CTR1. Le second est le transporteur ATP7A, qui émet le cuivre dans le cerveau. Les mêmes transporteurs permettent au cuivre de rentrer dans les neurones et les cellules gliales. Les deux expriment des transporteurs CTR1 pour faire entrer le cuivre dans les neurones/astrocytes/oligodendrocytes/autres. En cas d'excès de cuivre dans le cerveau, l'excès est éliminé dans le liquide cérébrospinal ou dans le sang. Les cellules qui font la barrière entre cerveau et méninges disposent pour cela d'un transporteur dédié, le ATP7B, qui émet du cuivre dans le liquide cérébrospinal. Le cuivre en excès dans le liquide cérébrospinal est lui émis dans le sang, grâce là encore avec un transporteur ATP7A situés dans les cellules des vaisseaux sanguins. [[File:Metabolisme cerebral du cuivre.png|centre|vignette|upright=2.5|Métabolisme cérébral du cuivre]] ===L'entrée du fer dans le cerveau=== Comme pour le cuivre, bien qu'étant un ion simple, l'entrée du fer dans le cerveau ne passe pas par des canaux ioniques ou pompes. La raison est qu'il n'y a presque pas d'ion fer isolés, dissous dans le sang. Le fer absorbé par l'intestin est immédiatement capturé par une molécule de transport, appelée la '''transferrine'''. Elle capture le fer libre, le transporte dans le sang et le relâche au niveau des tissus qui en ont besoin. Il faut noter que l'on distingue l'apo-transferrine et l'holo-transferrine, la première étant de la transferrine seule, l'autre étant de la transferrine qui a capturé du fer. L'apo- et l'holo-transferrine n'ont pas la même forme tridimensionnelle, ce qui a des conséquences. La transferrine entre dans le cerveau via transport vésiculaire. L'holo-transferrine sanguine se fixe sur des récepteurs à la transferrine, présents à la surface des cellules endothéliales. La fixation sur ces récepteurs entraine l'internalisation de la molécule d'holo-transferrine, la formation de la vésicule. Seule l'holo-transferrine se lie aux transporteurs des cellules endothéliales, pas l'apo-transferrine, pour des raisons de conformation tridimensionnelle. Ensuite, la vésicule traverse la cellule endothéliale, puis fusionne avec sa membrane de l'autre côté de la cellule, ce qui relâche la transferrine et le fer dans le cerveau. Ce transport vésiculaire basique est la première voie d'entrée du fer dans le cerveau, mais c'est la moins importante en pratique. En effet, il s'agit d'une voie directe, passive, sans mécanisme de régulation poussé. Mais le cerveau a des besoins en fer qui doivent être sérieusement régulés, pour éviter tout excès de Fer. Rappelons en effet qu'un excès de fer est toxique pour les cellules, neurones et cellules gliales comprises. Pour cela, la barrière hémato-encéphalique dispose d'autres moyens de transport du fer, qui sont régulables. Outre le transport vésiculaire simple, il existe deux autres voies de transport, qui permettent au fer de traverser la barrière hématoencéphalique. Les deux commencent de la même manière : la transferrine est internalisée dans une vésicule. Sauf que le Fer en excès est extrait des vésicules. L'extraction du Fer se fait en deux étapes : la première détache le fer de la transferrine dans la vésicule, la seconde le fait sortir de la vésicule à travers un "canal ionique" appelé le DMT1, inséré à la surface de la vésicule. La vésicule est alors renvoyée vers la paroi du vaisseau sanguin et fusionne avec, le récepteur de la transferrine est ainsi recyclé. Le Fer extrait de la vésicule est du fer dissous dans la cellule endothéliale. Il peut alors subir deux voies de transfert différentes. La première passe par une protéine de transport membranaire qui relâche le Fer dans le cerveau, qui agit un petit peu comme un "canal ionique". La protéine en question s'appelle la '''ferroportine''', elle est présente dans le cerveau, dans les intestins et d'autres cellules. Il faut noter que le Fer transporté par la ferroportine est toujours un ion <math>Fe^{2+}</math> et non les autres formes ioniques (<math>Fe^{3+}</math> ou <math>Fe^{+}</math>). C'est le contraire de la transferrine qui capture des ions <math>Fe^{3+}</math>. L'action de la ferroportine est régulée par une molécule appelée l''''hepcidine''', qui a plusieurs actions. Premièrement, elle "ouvre" ou "ferme" le "canal ionique" de la ferroportine. Deuxièmement, elle peut détruire les molécules de ferroportine en les marquant comme prête pour dégradation dans les lysosomes. Elle régule ainsi l'entrée du fer à ce qui est utile au cerveau : s'il subit un excès de Fer, il produira de l'hepcidine pour "désactiver" la ferroportine et séquestrer le fer dans les cellules endothéliales. La production de l'hepcidine cérébrale est le fait des astrocytes. Une seconde voie séquestre le fer en excès dans la cellule endothéliale, pour être relâché en cas de besoin. Pour cela, les réserves de fer sont stockées dans une molécule appelée la '''ferritine''', une molécule de ferritine pouvant capturer près de 5000 atomes de fer. Pour relâcher le fer, la ferritine est internalisée dans une seconde vésicule, qui fusionne avec la membrane. Les cellules endothéliales ont donc des réserves de fer sous forme de ferritine, qu'elles peuvent relâcher dans le cerveau si le besoin s'en fait sentir. Les mécanismes pour ce faire sont encore mal connus. Le fer est alors absorbé par un astrocyte. Les trois voies posibles sont résumées dans le schéma ci-dessous. [[File:Fer et barrière hemato-encéphalique.png|centre|vignette|upright=3|Fer et barrière hemato-encéphalique]] ===L'entrée du manganèse dans le cerveau=== Le cas du manganèse est assez similaire à celui du fer. Le manganèse est important pour le métabolisme général e la plupart des cellules. Mais il doit être présent en petites quantités, de fortes quantités pouvant être toxiques. Aussi, comme le fer et le cuivre, son entrée dans le cerveau est fortement régulée. L'entrée du manganèse dans le cerveau est presque identique à celle du fer. Le manganèse est transporté par la transferrine, comme le fer, et passe à travers le transporteur DMT1 et la ferroportine. Il traverse la barrière hémato-encéphalique par l'intermédiaire des voies d'entrée du fer, donc. Par contre, la barrière hémato-encéphalique dispose aussi de pompes ioniques qui expulsent le manganèse en trop dans le sang. Précisément, la pompe qui expulse le manganèse en trop dans le sang est la protéine SLC30A10. Le manganèse s'accumule dans le cerveau aux mêmes endroits que le fer : dans les ganglions de la base. Les effets d'une intoxication au manganèse sont donc similaire à ceux d'un excès cérébral de fer : syndrome parkinsonien, autres troubles moteurs comme des dystonies. Une intoxication en manganèse est généralement lié à une exposition professionnelle, mais il existe de rares maladies génétiques liées à des mutations de la protéine SLC30A10 qui entrainent un excès cérébral en manganèse. <noinclude> {{NavChapitre | book=Neurosciences | prev=L'activité électrique du cerveau | prevText=L'activité électrique du cerveau | next=Le métabolisme cérébral | nextText=Le métabolisme cérébral }}{{autocat}} </noinclude> sq186nhdjsdszwk8ea99ckj9l54lf9c 744032 744031 2025-06-03T13:40:24Z Mewtow 31375 /* L'entrée des molécules dans le cerveau : quelques exemples */ 744032 wikitext text/x-wiki Le cerveau est séparé de la circulation sanguine, par une '''barrière hémato-encéphalique''' qui isole le cerveau du reste du corps. Elle est présente sur tous les vaisseaux sanguins cérébraux, ou presque. Les molécules sanguines ne peuvent pas toutes passer à travers la barrière hémato-encéphalique : si certaines le peuvent, d'autres ne le peuvent pas. On dit que la barrière hémato-encéphalique a une '''perméabilité sélective'''. C'est d'ailleurs la raison d'être de la barrière hémato-encéphalique : empêcher le passage de "molécules nuisibles" à travers les capillaires, pour éviter qu'elles passent dans le cerveau. Les ions (calcium, potassium, sodium, et autres) ne peuvent pas traverser cette barrière, leur concentration étant importante pour le bon fonctionnement des potentiels d'action. D'autres molécules importantes, comme le glucose ou d'autres nutriments, peuvent la traverser. Beaucoup de médicaments ne peuvent pas passer la barrière hémato-encéphalique, ce qui est parfois un avantage, parfois un défaut. C'est un défaut si la molécule a le potentiel d'agir positivement sur le cerveau, mais que la barrière hémato-encéphalique lui empêche d'rentrer. Par exemple, imaginons qu'on découvre une molécule thérapeutique qui permettrait d'augmenter la neurogenèse (la fabrication de nouveaux neurones). Si elle passait à travers la barrière hémato-encéphalique, elle pourrait soigner des maladies comme Alzheimer. Mais elle ne servirait à rien si elle ne pouvait pas rentrer dans le cerveau ! À l'inverse, ce peut être un avantage dans certains cas. Par exemple, une molécule noradrénergique utilisée pour traiter les troubles du rythme cardiaque ne devrait, idéalement, pas agir sur le cerveau. Si elle ne passe pas à travers la barrière hémato-encéphalique, tout va pour le mieux : la molécule n'agira pas sur le cerveau, ce qui fait des effets secondaires d'évités. Par contre, si ce n'est pas le cas, cela pourrait causer des effets secondaires neurologiques ou psychiatriques assez graves. : Avant de poursuivre, sachez que nous utiliserons souvent l'abréviation, BHE pour désigner la barrière hémato-encéphalique. ==La barrière hémato-encéphalique : les capillaires cérébraux== La barrière hémato-encéphalique se situe au niveau des vaisseaux sanguins du système nerveux, à quelques exceptions. Les exceptions en question sont des vaisseaux où la barrière hémato-encéphalique n'existe pas, mais ils sont très rares. Pour être précis, les vaisseaux sanguins protégés par la barrière hémato-encéphalique sont les capillaires, à savoir les petits vaisseaux suffisamment fins pour laisser passer de l'oxygène, du CO2, des nutriments, quelques petites molécules. Les capillaires ne doivent pas être confondus avec les artères et les veines, des vaisseaux plus gros. La différence principale est que les capillaires sont composés d'une unique couche de cellules jointes, juxtaposées les unes à côté des autres (l'ensemble forme ce qu'on appelle un épithélium). Les artères ajoutent plusieurs couches en plus de l'épithélium, dont une couche de muscles qui aident à contracter ou dilater l'artère, et un second épithélium qui enveloppe l'artère. Même chose pour les veines, avec cependant des couches en plus. Les artères et veines du système nerveux ne sont pas différentes de celles trouvées dans le reste du corps. Par contre, les capillaires cérébraux sont totalement différents sur deux points. ===Des capillaires continus protégés par des astrocytes=== La barrière hémato-encéphalique est formée par deux choses : le vaisseaux capillaire lui-mêmes, et une couche protectrice d'astrocytes tout autour. La première barrière est liée au fait que les capillaires du système nerveux central sont moins étanches que les capillaires normaux. La seconde barrière est formée par les astrocytes, qui entourent les vaisseau sanguins. [[File:Blood brain barrier.png|centre|vignette|upright=2|Barrière hémato-encéphalique.]] Les capillaires peuvent se classer en trois types, suivant la manière dont l’épithélium est formé : capillaires sinusoïdaux, fenêtrés et continus. La différence est que les deux sont perclus de trous, mais pas le dernier. Dans les '''capillaires sinusoïdaux''', les cellules de l'épithélium sont liées les unes aux autres, grâce à des espèces de crochets moléculaires, mais d'une manière assez lâche. Les crochets attachent les cellules à leurs voisines, mais laissent des espaces entre les cellules, qui peut prendre la forme de fentes. Cela permet de laisser des cellules comme des globules blancs et des globule rouges, des grosses protéines, mais ils peuvent aussi malheureusement laisser passer les virus et quelques toxines. [[File:202104 Sinusoidal capillary.svg|centre|vignette|upright=1|Capillaires sinusoïdal.]] Les capillaires fenêtrés et continus ont des cellules collées les unes aux autres par des jonctions communicantes, les mêmes que celles qui servent pour les synapses électriques. Elles sont beaucoup plus nombreuses que les crochets moléculaires des capillaires normaux, ce qui colle mieux les cellules du capillaire. En conséquence, les espaces entre cellules n'existent pas, ce qui ne permet pas de laisser passer des cellules, virus ou protéines. Mais par contre, les '''capillaires fenêtrés''' ont des pores qui traversent les cellules du vaisseaux sanguin et permettent de laisser passer de grosses molécules, comme des protéines, mais aussi des virus et autres bactéries de petite taille. [[File:202104 Fenestrated capillary.svg|centre|vignette|upright=1|Capillaires fenêtré.]] Les '''capillaires continus''' ne laissent ni espace entre cellules, ni pore, ni quoique ce soit. En conséquence, ils sont vraiment imperméables, au point qu'ils fournissent une première barrière contre les agressions extérieures, notamment contre les virus, les bactéries ou les toxines de grande taille. De tel capillaires ne se trouvent qu'en deux endroits : les muscles squelettiques, et le système nerveux. La première barrière hémato-encéphalique est le fait que tous les capillaires du système nerveux sont des capillaires continus. [[File:202104 Continuous capillary.svg|centre|vignette|upright=1|Capillaires continu.]] Ensuite, la seconde couche est formée par les astrocytes qui entourent les vaisseaux. Plus précisément, les capillaires cérébraux ne sont pas entourés de muscles, comme leurs congénères, mais sont recouverts par des astrocytes et des péricytes. Le tout forme une double couche : une première couche formé par le vaisseau sanguin, une seconde couche formée par astrocytes. Une molécule qui souhaite passer cette barrière doit donc travers plus d'obstacles qu'ailleurs. La protection est meilleure comparé à la paroi d'un vaisseau sanguin, les membranes astrocytaires faisant office de renforcement. [[File:Blood Brain Barrier.jpg|centre|vignette|upright=2.0|Barrière hémato-encéphalique]] ===Les espaces périvasculaires/de Virchow–Robin=== Outre la barrière hémato-encéphalique, certains vaisseaux sanguins cérébraux sont entourés par un manchon rempli de fluide : l''''espace périvasculaire''', aussi appelé ''espace de Virchow–Robin''. Ils sont surtout présents sur les vaisseaux des méninges, dans les couches situées sous l'arachnoïde et la pie-mère. Mais on en trouve aussi autour des vaisseaux des ganglions de la base et de quelques autres vaisseaux. Le cas le plus important est de loin les vaisseaux qui alimentent les organes circumventriculaires, à savoir des aires cérébrales qui ne sont pas protégées par la barrière hémato-encéphalique, sans doute pour assurer leur protection immunologique. On en trouve aussi en dehors du cerveau, dans le foie, le thymus et quelques autres organes, mais ceci est une autre histoire... Les espaces périvasculaires possèdent des fonctions variées, qui vont de l'immunité à la régulation du transfert d'ions et de solutés. Ils servent, entre autres, de protection immunologique. Preuve en est la présence d'un grand nombre de globules blancs, surtout lors d'infections : lymphocytes T et B, monocytes, etc. Mais leur rôle principal est la régulation des échanges de fluide avec le cerveau, de permettre un échange sang<->cerveau aisé des solutés, ions et autres petites molécules solubles. ==Le passage des molécules à travers la barrière hémato-encéphalique : généralités== La barrière hémato-encéphalique est donc composée des capillaires sanguins du cerveau, parfois recouvert par une couche d'astrocytes. Les cellules des capillaires sanguins sont appelées des '''cellules endothéliales'''. Les molécules doivent donc traverser une couche de cellules endothéliales, pour ensuite être absorbée par les astrocytes qui s'occupent de métaboliser ce qui doit l'être. La traversée d'une cellule endothéliale demande que la molécule traverse la membrane de cette cellule deux fois : une fois pour le passage sang->cellule endothéliale, une seconde fois pour sortir de la cellule endothéliale et rentrer dans le cerveau. Il y a donc deux passages à travers une membrane cellulaire, et cela nous amène à parler plus en détail des membranes cellulaires. Il existe divers mécanismes qui permettent à des molécules de traverser les membranes cellulaires des cellules endothéliales. Les mécanismes sont résumés dans le schéma ci-dessous. Nous allons les détailler un par un dans ce qui suit, mais les images devraient vous donner une petite idée de comment fonctionnent ces mécanismes. [[File:Blood-brain barrier transport en.png|centre|vignette|upright=2.5|Mécanismes de transport à travers la barrière hémato-encéphalique.]] Les mécanismes en question peuvent se classer en deux types. Les mécanismes de '''transport passifs''' utilisent un gradient de concentration, ce qui permet de faire passer une molécule d'un endroit où elle est très concentrée vers un endroit où elle l'est moins. Ils ne consomment pas d'énergie. A l'inverse, les mécanismes de '''transport actif''' consomment de l'énergie sous forme d'ATP, mais sont capables d'aller contre un gradient de concentration. Pour donner un exemple, les pompes ioniques sont des mécanismes de transport actif, les canaux ioniques sont du transport passif. Il existe une sorte d'équivalent mais pour les molécules plus grosses. ===La diffusion simple et le transport paracellualire=== Les deux mécanismes de transport les plus simples sont le transport paracellulaire et la diffusion simple. Avec ceux deux-là, de très petites molécules peuvent passer la BHE directement, en suivant un gradient de concentration, sans rencontrer d'obstacle digne de ce nom. La BHE est naturellement perméable pour ces petites molécules. Ce sont donc des mécanismes de transport passif. Le premier est le '''transport paracellulaire''', où les molécules passent entre les cellules endothéliales des capillaires sanguins. Les cellules endothéliales sont certes collées les unes au autres, mais pas parfaitement. Il reste toujours quelques espaces qui peuvent laisser passer de petites molécules. Le terme paracellulaire est assez parlant : para- pour dire à côté, et cellulaire. Cependant, dans le cerveau, ce mécanisme de transport est rendu impossible. Les capillaires sanguins sont continus, il n'y a pas d'espace entre les cellules endothéliales. Les cellules endothéliales sont collées les unes au autres grâce à des jonctions communicantes et autres jonctions cellulaires, qui ne laissent presque pas d'espace libre. En conséquence, le transport paracellulaire est empêché, ce qui en fait un premier mécanisme de protection, une première barrière hémato-encéphalique. Les molécules du sang doivent donc traverser les cellules endothéliales, pas passer à côté. Le second mécanisme de transport passif est la '''diffusion simple'''. Avec elle, une molécule passe à travers la barrière hémato-encéphalique sans rencontrer d'obstacles, comme dans du beurre, sans recourir à des canaux ioniques ni quoique ce soit d'équivalent. [[File:Scheme simple diffusion in cell membrane-fr.svg|centre|vignette|upright=2|Diffusion simple.]] Pour comprendre quelles molécules peuvent traverser ainsi, faisons un rappel rapide sur les membranes cellulaires, ainsi que sur les molécules hydrophobes et hydrophiles. Les molécules sont souvent classés en molécules hydrophiles (attirées par l'eau) et hydrophobes (repoussées par l'eau). Le caractère hydrophile et hydrophobe est lié à des interactions électriques avec les molécules d'eau. Les molécules hydrophiles sont généralement polaires, avec une charge positive à un côté de la molécule et un côté négatif de l'autre. Par contre, les molécules hydrophobe sont généralement neutres. Les molécules hydrophiles se dissolvent très bien dans l'eau, alors que les molécules hydrophobes ne se dissolvent pas, et cela n'a rien de surprenant. Par contre, le caractère hydrophobe/hydrophile a aussi un impact sur la dissolution dans des graisses, les lipides. Les molécules hydrophobes sont généralement liposolubles, ce qui veut dire qu'elles se dissolvent dans les graisses, les lipides. A l'inverse, les molécules hydrophiles ne se dissolvent pas dans les graisses. Et il se trouve que la membrane cellulaire est composée d'une double couche de lipides ! Chaque molécule de lipide a une tête hydrophile (attirée par l'eau), et une queue hydrophobe (qui est repoussée par l'eau). La membrane a donc un cœur hydrophobe et un extérieur hydrophile. Les molécules hydrophiles ne traversent pas le cœur hydrophobe, car elles ne se dissolvent pas dans les lipides. Par contre, les molécules hydrophobes traversent la membrane cellulaire sans trop de soucis. La traversée d'une membrane cellulaire n'est donc pas la même entre une molécule hydrophobe et une molécule hydrophile. [[File:Fluid Mosaic.svg|centre|vignette|upright=2|Membrane cellaulaire.]] La diffusion simple n'est donc possible que si la molécule peut se dissoudre dans la membrane cellulaire, donc se dissoudre dans des lipides. En clair, c'est limité aux molécules hydrophobes, liposolubles. De plus, les molécules doivent être assez petites, les grosses molécules ne peuvent pas traverser facilement. Une molécule plus grosse que la membrane aura du mal à se dissoudre dedans. Pour résumer : diffusion simple possible seulement pour les molécules hydrophobes assez petites. L'exemple le plus simple est celui de l'oxygène. Les gaz dissous dans le sang traversent presque tous la BHE : oxygène, mais aussi CO2, azote, etc. Mais cela concerne aussi des molécules. Par exemple, l'éthanol (l'alcool) traverse les membranes cellulaire sans aucun problème, y compris la BHE. Comme autre exemple, les stéroïdes traversent les membranes cellulaires sans problèmes, et cela vaut aussi bien pour les hormones sexuelles que le cortisol. Hormones sexuelles et cortisol rentrent dans le cerveau sans problème, ils traversent la barrière hémato-encéphalique. Par contre, des molécules importantes ne passent pas diffusion libre : l'eau, le glucose, les acides aminés, les protéines, les ions. Vous avez bien lu : l'eau ne traverse pas les membranes cellulaires. Et c'est évident, car l'eau est hydrophile. Le glucose est aussi concerné car il se dissous bien dans l'eau, et vous pouvez le constater en mettant du sucre dans de l'eau. Les ions sont naturellement dissous dans l'eau, donc hydrophiles. Les acides aminés et protéines sont soit trop gros, soit trop hydrophiles pour traverser la membrane cellulaire. Les molécules hydrophiles ne peuvent pas traverser les membranes cellulaires avec la diffusion simple, pas plus que les très grosses molécules. Les ions sont concernés, car les ions étant par nature dissous dans l'eau, ils sont hydrophiles. Les molécules hydrophiles doivent donc traverser les membranes cellulaires par un autre mécanisme. Voyons lesquels. ===Les transporteurs transmembranaires=== Les molécules hydrophiles peuvent traverser les membranes cellulaires grâce à des protéines transmembranaires, à savoir qui traversent la membrane cellulaire de part en part. Une partie de ces protéines transmembranaires permettent à une molécule de traverser la membrane cellulaire, d'où leur nom de '''transporteurs transmembranaires''', simplifié en transporteurs. Nous avons déjà vu des transporteurs transmembranaires dans ce cours : les pompes et canaux ioniques en sont ! Ce sont juste des transporteurs spécialisées dans le transport des ions, comme on aurait pu le deviner. Les petites et grosses molécules utilisent des transporteurs différents des canaux et pompes ioniques, mais qui fonctionnent sur le même principe. Il existe des '''transporteurs actifs''', qui demandent de l'énergie sous forme d'ATP pour fonctionner. Ils peuvent fonctionner même en l'absence de gradient de concentration, voire fonctionner même si le gradient de concentration est défavorable. La plupart des transporteurs actifs de la BHE visent à rejeter des molécules indésirables dans le sang. Par exemple, de nombreuses pompes ioniques visent à rejeter des ions dans le sang. Si ces ions rentrent dans la cellule endothéliale, ils seront rejetés par ces pompes. Les pompes en question portent des noms assez complexes, la plus connue étant ceux de la famille des ''Organo anion transporters''. Et il existe aussi des pompes non-ioniques, pour des molécules indésirables plus grosses. Un exemple est celui de la ''Glycoprotéine P'', qui empeche de nombreux médicaments de traverser la BHE, sans compter qu'elle rejette aussi de nombreuses molécules organiques. Si les transporteurs actifs sont des pompes qui rejettent des molécules dans le sang, d'autres transporteurs servent au contraire à faciliter l'entrée de molécules dans le cerveau. La plupart sont des '''transporteurs passifs''', à savoir qu'ils demandent un gradient de concentration pour fonctionner. Ils servent en quelque sorte de sas d'entrée, qui permet aux molécules de traverser la membrane si le gradient de concentration est favorable. Les molécules suivent le gradient de concentration et vont vers la zone la moins concentrée, mais seulement si le sas d'entrée/transporteur est ouvert. En quelque sorte, ce sont l'équivalent des canaux ioniques ouvert/fermés mais pour les grosses molécules. Pour distinguer ce mécanisme de transport de la diffusion simple, on dit que les canaux ioniques et transporteurs font de la '''diffusion facilitée''', dans le sens où le transporteur/canal ionique facilite la traversée de la membrane. Le processus d'entrée via un transporteur se fait en quelques étapes. Pour commencer, la molécule va se lier au transporteur, de la même manière qu'un neurotransmetteur se lie à son récepteur. Suite à cette liaison, le transporteur va être déstabilisé par diverses interactions électriques avec la molécule. Il va changer de forme et se reconfigurer. Cette reconfiguration fait que la molécule, auparavant sur la face extérieure, se retrouve sur la face intérieure de la membrane cellulaire. Enfin, la molécule se détache : elle a traversé la membrane. [[File:Scheme facilitated diffusion in cell membrane-fr.svg|centre|vignette|upright=2.5|Diffusion facilitée : canal ionique à gauche, transporteurs à droite.]] Les transporteurs servent de portes d'entrées qui permettent le passage des molécules à travers une membrane cellulaire. En conséquence, ils sont finement régulés de manière à ne laisser les molécules qu'avec parcimonie, suffisamment pour ne pas avoir de déficience cérébrale, mais pas assez pour perturber le fonctionnement cérébral. Par exemple, le passage des ions est sévèrement contrôlé, afin de protéger le cerveau des variations de concentration ionique du sang. Par exemple, suite à un repas trop salé, la concentration intracérébrale en sodium doit rester la même, le sodium ne doit pas traverser la barrière-hémato-encéphalique. A l'inverse, lors d'un manque de sodium intra-cérébral, la barrière hémato-encéphalique laissera passer ces ions sodium. La régulation de l'équilibre ionique du cerveau est assez simple : il suffit d'ouvrir ou de fermer des canaux ioniques selon les besoins. ===Le transport vésiculaire=== Il existe aussi un dernier mode de transport, appelé le '''transport vésiculaire''', qui est particulièrement adapté au transport de grosses molécules. Avec lui, les molécules peuvent traverser une cellule endothéliale en un seul passage, sans avoir à traverser de membrane cellulaire proprement dit. Les molécules sont transportées à travers la barrière hémato-encéphalique dans un sac de lipides appelé une vésicule. La vésicule se forme par invagination de la membrane cellulaire, qui se replie sur elle-même pour former une vésicule. La vésicule traverse alors la cellule endothéliale, puis se colle sur la membrane de l'autre côté. Elle fusionne alors avec la membrane, avec l'aide d'un paquet d'enzymes. La fusion relâche le contenu de la vésicule dans le milieu ambiant, dans le cerveau. [[File:Vesicle Budding, Motility and Fusion.jpg|centre|vignette|upright=2|Transport par vésicules intra-cellulaires. La vésicule se forme à gauche par invagination de la membrane cellulaire, la vésicule traverse la cellule, puis fusionne avec la membrane de l'autre côté.]] ==L'entrée des molécules dans le cerveau : quelques exemples== La BHE laisse passer certaines molécules via l'intermédiaire de transporteurs, du transport vésiculaire et de la diffusion simple. Outre les canaux ioniques, la BHE dispose de transporteurs passifs pour le glucose, mais aussi pour l'eau (des aquaporines), ainsi que pour les acides aminés essentiels. Dans ce qui va suivre, nous allons voir quelques exemples, en étudiant le cas du cuivre et du fer. L'exemple du cuivre aide à faire comprendre comment les transporteurs permettent de faire passer des molécules du sang au cerveau. L'exemple du fer est un cas particulier qui mélange transporteurs et transport vésiculaire. ===L'entrée du cuivre dans le cerveau=== Le premier exemple, que nous allons voir en détail, est le transport du cuivre. Pour rappel, pour traverser la barrière hémato-encéphalique, il faut traverser deux membranes cellulaires : celle entre le sang et la cellule du capillaire sanguin, celle entre le capillaire sanguin et le cerveau. Pour cela, le cuivre a deux transporteurs Le premier permet au cuivre de passer du sang à l'intérieur des cellules des vaisseaux sanguins, il porte le nom de ''High affinity copper uptake protein 1'', aussi appelé CTR1. Le second est le transporteur ATP7A, qui émet le cuivre dans le cerveau. Les mêmes transporteurs permettent au cuivre de rentrer dans les neurones et les cellules gliales. Les deux expriment des transporteurs CTR1 pour faire entrer le cuivre dans les neurones/astrocytes/oligodendrocytes/autres. En cas d'excès de cuivre dans le cerveau, l'excès est éliminé dans le liquide cérébrospinal ou dans le sang. Les cellules qui font la barrière entre cerveau et méninges disposent pour cela d'un transporteur dédié, le ATP7B, qui émet du cuivre dans le liquide cérébrospinal. Le cuivre en excès dans le liquide cérébrospinal est lui émis dans le sang, grâce là encore avec un transporteur ATP7A situés dans les cellules des vaisseaux sanguins. [[File:Metabolisme cerebral du cuivre.png|centre|vignette|upright=2.5|Métabolisme cérébral du cuivre]] ===L'entrée du fer dans le cerveau=== Comme pour le cuivre, bien qu'étant un ion simple, l'entrée du fer dans le cerveau ne passe pas par des canaux ioniques ou pompes. La raison est qu'il n'y a presque pas d'ion fer isolés, dissous dans le sang. Le fer absorbé par l'intestin est immédiatement capturé par une molécule de transport, appelée la '''transferrine'''. Elle capture le fer libre, le transporte dans le sang et le relâche au niveau des tissus qui en ont besoin. Il faut noter que l'on distingue l'apo-transferrine et l'holo-transferrine, la première étant de la transferrine seule, l'autre étant de la transferrine qui a capturé du fer. L'apo- et l'holo-transferrine n'ont pas la même forme tridimensionnelle, ce qui a des conséquences. La transferrine entre dans le cerveau via transport vésiculaire. L'holo-transferrine sanguine se fixe sur des récepteurs à la transferrine, présents à la surface des cellules endothéliales. La fixation sur ces récepteurs entraine l'internalisation de la molécule d'holo-transferrine, la formation de la vésicule. Seule l'holo-transferrine se lie aux transporteurs des cellules endothéliales, pas l'apo-transferrine, pour des raisons de conformation tridimensionnelle. Ensuite, la vésicule traverse la cellule endothéliale, puis fusionne avec sa membrane de l'autre côté de la cellule, ce qui relâche la transferrine et le fer dans le cerveau. Ce transport vésiculaire basique est la première voie d'entrée du fer dans le cerveau, mais c'est la moins importante en pratique. En effet, il s'agit d'une voie directe, passive, sans mécanisme de régulation poussé. Mais le cerveau a des besoins en fer qui doivent être sérieusement régulés, pour éviter tout excès de Fer. Rappelons en effet qu'un excès de fer est toxique pour les cellules, neurones et cellules gliales comprises. Pour cela, la barrière hémato-encéphalique dispose d'autres moyens de transport du fer, qui sont régulables. Outre le transport vésiculaire simple, il existe deux autres voies de transport, qui permettent au fer de traverser la barrière hématoencéphalique. Les deux commencent de la même manière : la transferrine est internalisée dans une vésicule. Sauf que le Fer en excès est extrait des vésicules. L'extraction du Fer se fait en deux étapes : la première détache le fer de la transferrine dans la vésicule, la seconde le fait sortir de la vésicule à travers un "canal ionique" appelé le DMT1, inséré à la surface de la vésicule. La vésicule est alors renvoyée vers la paroi du vaisseau sanguin et fusionne avec, le récepteur de la transferrine est ainsi recyclé. Le Fer extrait de la vésicule est du fer dissous dans la cellule endothéliale. Il peut alors subir deux voies de transfert différentes. La première passe par une protéine de transport membranaire qui relâche le Fer dans le cerveau, qui agit un petit peu comme un "canal ionique". La protéine en question s'appelle la '''ferroportine''', elle est présente dans le cerveau, dans les intestins et d'autres cellules. Il faut noter que le Fer transporté par la ferroportine est toujours un ion <math>Fe^{2+}</math> et non les autres formes ioniques (<math>Fe^{3+}</math> ou <math>Fe^{+}</math>). C'est le contraire de la transferrine qui capture des ions <math>Fe^{3+}</math>. L'action de la ferroportine est régulée par une molécule appelée l''''hepcidine''', qui a plusieurs actions. Premièrement, elle "ouvre" ou "ferme" le "canal ionique" de la ferroportine. Deuxièmement, elle peut détruire les molécules de ferroportine en les marquant comme prête pour dégradation dans les lysosomes. Elle régule ainsi l'entrée du fer à ce qui est utile au cerveau : s'il subit un excès de Fer, il produira de l'hepcidine pour "désactiver" la ferroportine et séquestrer le fer dans les cellules endothéliales. La production de l'hepcidine cérébrale est le fait des astrocytes. Une seconde voie séquestre le fer en excès dans la cellule endothéliale, pour être relâché en cas de besoin. Pour cela, les réserves de fer sont stockées dans une molécule appelée la '''ferritine''', une molécule de ferritine pouvant capturer près de 5000 atomes de fer. Pour relâcher le fer, la ferritine est internalisée dans une seconde vésicule, qui fusionne avec la membrane. Les cellules endothéliales ont donc des réserves de fer sous forme de ferritine, qu'elles peuvent relâcher dans le cerveau si le besoin s'en fait sentir. Les mécanismes pour ce faire sont encore mal connus. Le fer est alors absorbé par un astrocyte. Les trois voies posibles sont résumées dans le schéma ci-dessous. [[File:Fer et barrière hemato-encéphalique.png|centre|vignette|upright=3|Fer et barrière hemato-encéphalique]] ===L'entrée du manganèse dans le cerveau=== Le cas du manganèse est assez similaire à celui du fer. Le manganèse est important pour le métabolisme général e la plupart des cellules. Mais il doit être présent en petites quantités, de fortes quantités pouvant être toxiques. Aussi, comme le fer et le cuivre, son entrée dans le cerveau est fortement régulée. L'entrée du manganèse dans le cerveau est presque identique à celle du fer. Le manganèse est transporté par la transferrine, comme le fer, et passe à travers le transporteur DMT1 et la ferroportine. Il traverse la barrière hémato-encéphalique par l'intermédiaire des voies d'entrée du fer, donc. Par contre, la barrière hémato-encéphalique dispose aussi de pompes ioniques qui expulsent le manganèse en trop dans le sang. Précisément, la pompe qui expulse le manganèse en trop dans le sang est la protéine SLC30A10. Le manganèse s'accumule dans le cerveau aux mêmes endroits que le fer : dans les ganglions de la base. Les effets d'une intoxication au manganèse sont donc similaires à ceux d'un excès cérébral de fer : syndrome parkinsonien, autres troubles moteurs comme des dystonies. Une intoxication en manganèse est généralement lié à une exposition professionnelle, mais il existe de rares maladies génétiques liées à des mutations de la protéine SLC30A10 qui entrainent un excès cérébral en manganèse. <noinclude> {{NavChapitre | book=Neurosciences | prev=L'activité électrique du cerveau | prevText=L'activité électrique du cerveau | next=Le métabolisme cérébral | nextText=Le métabolisme cérébral }}{{autocat}} </noinclude> s0vtnlsmgzb9jxl839dn2fi8n3wvab3 Discussion utilisateur:Mo Reivilo 3 82424 744010 2025-06-02T14:53:35Z Fourmidable 92370 Page créée avec « {{Bienvenue}}--~~~~ » 744010 wikitext text/x-wiki {{Bienvenue}}--[[Utilisateur:Fourmidable|Fourmidable]] ([[Discussion utilisateur:Fourmidable|discussion]]) 2 juin 2025 à 16:53 (CEST) 6jjh97f4p3s2r0n8vhqian2ycq316f4 Discussion utilisateur:165.169.239.238 3 82425 744099 2025-06-04T09:23:21Z JackPotte 5426 Page créée avec « {{subst:Test 1}}~~~~ » 744099 wikitext text/x-wiki {|class="WSerieH" class="plainlinks" id="vandale" align="center" style="width:100%;margin-bottom:2em;border:1px solid #8888aa;border-right-width:2px;border-bottom-width:2px;background-color:#f7f8ff;padding:5px;text-align:justify" |- |[[Image:Nuvola apps important.svg|64px|Arrêtez de vandaliser Wikilivres !]] |Bonjour {{BASEPAGENAME}}, Vous avez découvert combien il est facile de modifier Wikilivres. Votre modification a été '''annulée''' en raison de son caractère non constructif. Merci de ne pas réitérer ce genre de contribution. Visitez la [[Aide:Accueil|page d’aide]] afin d’en apprendre plus ou le [[Wikilivres:bac à sable|bac à sable]] afin de faire des tests. |} [[Catégorie:Vandales avertis]][[Utilisateur:JackPotte|JackPotte]] ([[Discussion utilisateur:JackPotte|<span style="color:#FF6600">$</span>♠]]) 4 juin 2025 à 11:23 (CEST) 6zize7qvjeaxo9g2810wzmnw2xv799b