La cloche.

Il y a ceux qui ont lu cette nouvelle devant vous.
Abonnez-vous pour recevoir des articles frais.
E-mail
Nom
Nom de famille
Comment voulez-vous lire la cloche
Sans spam

Saul. 9 septembre 2015 à 13h38

Mise en œuvre de l'architecture multi-filetée moteur de jeu

  • Blog d'Intel
  • Développement de jeu
  • Programmation parallèle
  • Développement de sites Web
  • Transfert

Avec l'avènement des processeurs multicœurs, il était nécessaire de créer un moteur de jeu basé sur une architecture parallèle. L'utilisation de tous les processeurs système - à la fois graphique (GP) et centrale (CPU) - ouvre beaucoup plus d'opportunités par rapport à un moteur à un seul moteur sur la base de GP uniquement. Par exemple, en utilisant plus de cœurs CPU, vous pouvez améliorer les effets visuels, en augmentant le nombre d'objets physiques utilisés dans le jeu, ainsi que d'obtenir un comportement plus réaliste de caractères en mettant en œuvre une intelligence artificielle avancée (AI).
Considérez les caractéristiques de la mise en œuvre de l'architecture multi-threadée du moteur de jeu.

1. Introduction

1.1. Aperçu

L'architecture multi-filetée du moteur de jeu vous permet d'utiliser les capacités de tous les processeurs de plate-forme au maximum. Cela implique un parallèle effectuant divers blocs fonctionnels sur tous les processeurs disponibles. Cependant, il n'est pas si facile de mettre en œuvre un système similaire. Les éléments séparés du moteur de jeu interagissent souvent entre eux, ce qui peut entraîner l'apparition d'erreurs tout en exécutant simultanément. Pour traiter de tels scénarios dans le moteur, des mécanismes de synchronisation de données spéciaux sont fournis qui excluent blocage possible. Il met également en œuvre des méthodes de synchronisation simultanée des données, due au minimum de l'heure d'exécution.

Pour comprendre les matériaux représentés, vous devez bien comprendre les méthodes modernes de création de jeux informatiques, en soutenant la multithreading pour les moteurs de jeu ou pour améliorer la performance des applications dans son ensemble.

2. Statut d'exécution parallèle

L'état d'exécution parallèle est le concept clé de multithreading. Seulement en divisant le moteur de jeu vers des systèmes individuels qui fonctionnent chacun en mode et pratiquement non interagi avec le reste du moteur, on peut obtenir la plus grande efficacité du calcul parallèle et réduire le temps requis pour la synchronisation. Isoler complètement les parties individuelles du moteur, éliminant toutes les ressources communes, n'est pas possible. Toutefois, pour des opérations telles que l'obtention de données sur la position ou l'orientation des objets, des systèmes individuels peuvent utiliser des copies de données locales et non des ressources partagées. Cela vous permet de minimiser la dépendance des données dans différentes parties du moteur. Les notifications sur les modifications apportées aux données générales effectuées par un système distinct sont transmises au gestionnaire d'État, ce qui les place dans la file d'attente. Ceci s'appelle le mode de messagerie. Ce mode suppose qu'en remplissant l'exécution de la tâche, le système moteur reçoit des notifications sur les modifications et met à jour de manière appropriée leurs données internes. Un tel mécanisme permet de réduire considérablement le temps de synchronisation et la dépendance des systèmes les uns des autres.

2.1 états de performance

Pour que l'exécution Etat Manager fonctionne efficacement, il est recommandé de synchroniser des opérations sur une impulsion d'horloge spécifique. Cela permet à tous les systèmes de travailler simultanément. Dans ce cas, la fréquence des horloges ne doit pas nécessairement correspondre au taux de trame. Oui, et la durée de l'horloge peut ne pas dépendre de la fréquence. Il peut être sélectionné de manière à ce qu'une horloge correspond au temps nécessaire pour transmettre une image (quelle que soit sa taille). En d'autres termes, la fréquence ou la durée des horloges détermine la mise en œuvre spécifique du gestionnaire d'état. La figure 1 montre "gratuit" mode étape par étape Travailler dans lequel il n'est pas nécessaire que tous les systèmes remplissent l'exécution de l'opération pour le même tact. Le mode dans lequel tous les systèmes complètent l'exécution des opérations pour une horloge sont appelés mode étape par étape «durs». Il est décrit schématiquement à la figure 2.


Figure 1. Statut de performance en mode libre étape par étape

2.1.1. Mode libre étape par étape
En mode Pas à pas libre, tous les systèmes fonctionnent en continu pour une période de temps prédéterminée requise pour compléter la partie suivante des calculs. Cependant, le nom "libre" ne doit pas être compris littéralement: les systèmes sont synchronisés pas à un moment de temps arbitraire, ils ne sont que "libres" dans le choix du nombre d'horloges requises pour effectuer la prochaine étape.
En règle générale, dans ce mode, il ne suffit pas d'envoyer une simple notification de changement d'état au gestionnaire d'État. Vous devez également transférer les données mises à jour. Cela est dû au fait que le système qui a changé les données générales peut figurer dans l'état d'exécution, tandis qu'un autre système en attente de ces données est déjà prêt à mettre à jour. Dans ce cas, plus de mémoire est requise, car vous devez créer plus de copies de données. Par conséquent, le régime «libre» ne peut pas être considéré comme une solution universelle pour toutes les occasions.
2.1.2. Mode dure pas à pas
Dans ce mode, les tâches de tous les systèmes sont complétées en une horloge. Un tel mécanisme est plus facile à mettre en œuvre et ne nécessite pas le transfert de données mises à jour avec la notification. En effet, si nécessaire, un système peut simplement demander de nouvelles valeurs dans un autre système (bien sûr, à la fin du cycle d'exécution).
En mode sévère, vous pouvez mettre en œuvre un mode de fonctionnement étape par étape pseudo-grade, distribuant le calcul entre différentes étapes. Cela peut notamment être nécessaire pour les calculs de l'AI, où le premier tact est calculé par l'objectif initial "objectif commun", qui est progressivement spécifié aux étapes suivantes.


Figure 2. Statut des performances en mode étape par étape

2.2. Synchronisation des données

L'évolution des données communes par plusieurs systèmes peut entraîner un conflit de changement. Dans ce cas, dans le système de messagerie, il est nécessaire de fournir un algorithme de sélection de la valeur finale correcte. Il existe deux approches principales basées sur les critères suivants.
  • Temps: la valeur finale devient le dernier changement.
  • Priorité: la valeur finale devient la modification apportée par le système avec la plus grande priorité. Si la priorité des systèmes coïncide, vous pouvez également prendre en compte le temps de modification.
Toutes les données obsolètes (selon l'un des critères) peuvent simplement écraser ou exclure de la file d'attente des notifications.
Étant donné que la valeur finale peut dépendre de la procédure de modification, les valeurs relatives des données générales peuvent être très difficiles. Dans de tels cas, les valeurs absolues doivent être utilisées. Ensuite, lors de la mise à jour des données locales, le système peut simplement remplacer les anciennes valeurs neuves. La solution optimale consiste à choisir des valeurs absolues ou relatives en fonction de la situation spécifique. Par exemple, des données générales, telles que la position et l'orientation, doivent avoir des valeurs absolues, car elles sont importantes pour la procédure de modification. Les valeurs relatives peuvent être utilisées, par exemple, pour le système de génération de particules, car toutes les informations sur les particules ne sont stockées que dans elle elle-même.

3. moteur

Lors du développement d'un moteur, l'accent est mis sur la flexibilité nécessaire pour élargir davantage ses fonctionnalités. Cela l'optimisera pour une utilisation dans des conditions de certaines restrictions (par exemple, mémoire).
Le moteur peut être divisé en deux parties: cadres et gestionnaires. Le cadre (voir section 3.1) comprend des parties du jeu, qui sont répliquées pendant le processus d'exécution, qui existe dans plusieurs copies. Il comprend également des éléments impliqués dans la mise en œuvre du cycle de jeu principal. Les gestionnaires (voir section 3.2) sont des objets singletons responsables de l'exécution de la composante logique du jeu.
Vous trouverez ci-dessous un schéma d'un moteur de jeu.


Figure 3. Architecture du moteur général

Veuillez noter que les modules de jeu fonctionnels ou les systèmes ne font pas partie du moteur. Le moteur ne les combine que entre eux, agissant comme un liant. Une organisation modulaire similaire permet de télécharger et de décharger les systèmes selon les besoins.

L'interaction du moteur et des systèmes est effectuée à l'aide d'interfaces. Ils sont mis en œuvre de manière à fournir à l'accès du moteur aux fonctions système et aux systèmes - aux gestionnaires de moteurs.
Le schéma détaillé des moteurs est présenté à l'annexe A, "Déplacement du schéma".

En fait, tous les systèmes sont indépendants de l'autre (voir la section 2, "État de l'exécution simultanée"), c'est-à-dire qu'ils peuvent effectuer des actions en parallèle sans affecter le fonctionnement d'autres systèmes. Toutefois, toute modification des données entraînera certaines difficultés, car les systèmes devront interagir les uns avec les autres. L'échange d'informations entre systèmes est requis dans les cas suivants:

  • informer un autre système de modification de données communes (par exemple, la position ou l'orientation des objets);
  • pour effectuer les fonctions qui ne sont pas disponibles pour ce système (par exemple, le système AI fait référence au système de calcul des propriétés géométriques ou physiques de l'objet pour effectuer un test pour la traversée des rayons).
Dans le premier cas, le gestionnaire d'état décrit dans la section précédente peut être utilisé pour gérer les informations. (Pour plus d'informations sur le gestionnaire d'Etat, reportez-vous à la section 3.2.2, "Directeur de l'État".)
Dans le second cas, il est nécessaire de mettre en place un mécanisme spécial permettant aux services d'un système d'utiliser l'autre. Description complète Ce mécanisme est donné à la section 3.2.3, "gestionnaire de services".

3.1. Freeymvork

Le cadre sert à fusionner tous les éléments du moteur. Il initialise le moteur, à l'exception des gestionnaires, dont les instances sont créées à l'échelle mondiale. Il stocke également les informations sur la scène. Pour obtenir une plus grande flexibilité, la scène est mise en œuvre comme une scène dits universelle, qui contient des objets universels. Ce sont des conteneurs qui combinent diverses parties fonctionnelles de la scène. Pour plus de détails, voir la section 3.1.2.
Le cycle de jeu principal est également mis en œuvre dans le cadre. Il peut être soumis schématiquement comme suit.


Figure 4. Cycle de jeu principal

Le moteur tourne dans l'environnement de la fenêtre, donc dans la première étape du cycle de jeu, vous devez traiter toutes les fenêtres inachevées du système d'exploitation. Si cela n'est pas terminé, le moteur ne répondra pas aux messages du système d'exploitation. Dans la deuxième étape, le planificateur attribue des tâches à l'aide du gestionnaire de tâches. Ce processus est décrit en détail à la section 3.1.1 ci-dessous. Après cela, le gestionnaire d'état (voir section 3.2.2) envoie des informations sur les modifications apportées par les systèmes de machines, auxquelles elle peut affecter. Dans la dernière étape, en fonction du statut d'exécution, le cadre détermine s'il faut compléter ou poursuivre le fonctionnement du moteur, par exemple, d'aller à la scène suivante. Les informations sur l'état du moteur sont stockées au Moyen Manager. Pour plus de détails, voir la section 3.2.4.

3.1.1. Planificateur
Le planificateur génère un signal d'horloge de référence avec une fréquence donnée. Si le mode de test de référence nécessite que l'opération suivante commence immédiatement après avoir terminé la précédente, sans attendre la fin de l'horloge, la fréquence peut être illimitée.
Par un signal d'horloge, le planificateur utilisant le gestionnaire de tâches traduit le système en mode d'exécution. En mode Pas à pas (Section 2.1.1), le planificateur interroge le système pour déterminer le nombre d'horloges qu'il sera nécessaire pour compléter la tâche. Selon les résultats de l'enquête, le planificateur détermine quels systèmes sont prêts à être exécutés et qui complèteront le travail dans une horloge spécifique. Le planificateur peut modifier le nombre d'horloges si un système nécessite plus de temps pour exécuter. En mode étape par étape (section 2.1.2), tous les systèmes commencent et complètent l'exécution de la même horloge. Le planificateur attend donc lorsque tous les systèmes sont terminés.
3.1.2. Scène universelle et objets
La scène et les objets universels sont des conteneurs pour la fonctionnalité mise en œuvre dans d'autres systèmes. Ils sont destinés uniquement à interagir avec le moteur et n'effectuent aucune autre fonctions. Cependant, ils peuvent être étendus pour utiliser des fonctionnalités disponibles pour d'autres systèmes. Cela vous permet d'obtenir une connectivité faible. En effet, la scène universelle et les objets peuvent utiliser les propriétés d'autres systèmes sans leur être liés. C'est cette propriété qui exclut la dépendance des systèmes les uns des autres et leur donne la possibilité de travailler simultanément.
Le diagramme ci-dessous montre l'expansion d'une scène universelle et d'un objet.


Figure 5. Expansion de la scène universelle et de l'objet

Considérons le principe de fonctionnement des extensions dans l'exemple suivant. Supposons que l'extension de la scène universelle universelle de la scène soit élargie pour utiliser l'utilisation de propriétés graphiques, physiques et autres. Dans ce cas, la partie "graphique" de l'expansion sera responsable de l'initialisation de l'affichage et de la mise en œuvre de lois physiques pour les corps solides, telles que la gravité, constitue sa partie "physique". Les scènes contiennent des objets, de sorte que la scène universelle comprendra également plusieurs objets universels. Les objets universels peuvent également être étendus pour être améliorés pour utiliser l'utilisation de propriétés graphiques, physiques et autres. Par exemple, le dessin d'objet à l'écran sera mis en œuvre par des fonctions d'extension graphique et le calcul de l'interaction des corps solides est physique.

Le schéma détaillé de l'interaction du moteur et des systèmes est donné à l'annexe B, le «Schéma d'interaction du moteur».
Il convient de noter que la scène universelle et l'objet universel sont responsables de l'enregistrement de toutes ses "extensions" dans le gestionnaire d'État, de sorte que toutes les extensions puissent recevoir des notifications des modifications apportées par d'autres extensions (c'est-à-dire par d'autres systèmes). À titre d'exemple, vous pouvez citer une extension graphique enregistrée pour obtenir des notifications sur les modifications apportées à la position et à l'orientation effectuées par une expansion physique.
Pour plus de détails sur les composants du système, reportez-vous à la section 5.2, section "Composants système".

3.2. Gestionnaires

Les gestionnaires gèrent les travaux du moteur. Ce sont des objets Singleton, c'est-à-dire que le gestionnaire de chaque type n'est disponible que dans une seule instance. Cela est nécessaire car la duplication des ressources des gestionnaires conduira inévitablement à la redondance et affectera négativement les performances. De plus, les gestionnaires sont responsables de la mise en œuvre de fonctions communes pour tous les systèmes.
3.2.1. Gestionnaire des tâches
Le gestionnaire de tâches est responsable de la gestion des tâches du système dans le pool de flux. Pour assurer une mise à l'échelle N-multiple optimale et éviter les flux inutiles, éliminer les coûts injustifiés pour changer de tâche dans le système d'exploitation, le pool de flux crée un fil sur chaque processeur.

Le planificateur envoie la liste des tâches au gestionnaire de tâches pour l'exécution, ainsi que des informations sur l'achèvement des tâches. Il reçoit ces données de divers systèmes. Chaque système ne reçoit qu'une seule tâche d'exécution. Cette méthode s'appelle une décomposition fonctionnelle. Toutefois, pour le traitement des données, chaque tâche peut être divisée en une quantité arbitraire de sous-tâches (décomposition de données).
Vous trouverez ci-dessous un exemple de la distribution de tâches entre les threads du système quad-core.


Figure 6. Exemple du pool de flux utilisé par le gestionnaire de tâches

En plus du traitement des demandes de planificateur d'accès aux tâches principales, le gestionnaire de tâches peut fonctionner en mode d'initialisation. Il interroge constamment les systèmes de chaque thread de manière à pouvoir initialiser les entrepôts de données locaux nécessaires au travail.
Les conseils pour la mise en œuvre du gestionnaire de tâches sont donnés à l'annexe D, "Conseils pour la mise en œuvre des tâches".

3.2.2. Directeur de l'État
Le gestionnaire de statut fait partie du mécanisme de messagerie. Il suit les modifications et envoie des notifications à ce sujet à tous les systèmes que ces modifications peuvent affecter. Pour ne pas envoyer de notifications inutiles, le gestionnaire d'état stocke des informations sur les systèmes à notifier dans un cas particulier. Ce mécanisme est mis en œuvre sur la base du modèle "Observer" (voir annexe C, "Observer (Modèle de conception)"). Si vous parlez brièvement, ce modèle Il suppose l'utilisation de "observateur", qui est surveillée par toute modification du sujet et le rôle de média entre eux effectue le contrôleur de changement.

Le mécanisme fonctionne comme suit. 1. L'observateur signale le contrôleur de changement (ou responsable de l'État), les modifications apportées aux sujets qu'il souhaite suivre. 2. Le sujet notifie le contrôleur sur toutes ses modifications. 3. Sur le signal-cadre, le contrôleur notifie l'observateur des changements dans le sujet. 4. L'observateur envoie une demande de recevoir des données mises à jour.

Dans le mode d'exécution libre étape par étape (voir section 2.1.1), la mise en œuvre de ce mécanisme est quelque peu compliquée. Premièrement, les données mises à jour devront être envoyées avec la notification de modification. Dans ce mode, l'envoi sur demande n'est pas applicable. En effet, si au moment de la réception de la demande, le système responsable des modifications n'a pas fini d'exécution, il ne sera pas en mesure de fournir des données mises à jour. Deuxièmement, si un système n'est pas encore prêt à obtenir des modifications à la fin de l'horloge, le gestionnaire d'état devra contenir les données modifiées jusqu'à ce que tout le système enregistré pour les obtenir viendra à l'état de préparation.

Dans le cadre, il existe deux directeurs d'État pour cela: gérer les modifications au niveau de la scène et au niveau de l'objet. Habituellement, les messages relatifs aux scènes et aux objets sont indépendants de l'autre, l'utilisation de deux gestionnaires distincts élimine la nécessité de traiter des données inutiles. Mais si dans la scène, il est nécessaire de prendre en compte le statut de tout objet, il peut être enregistré pour obtenir la réception des notifications sur ses modifications.

Pour ne pas effectuer de synchronisation inutile, le gestionnaire d'état génère une file d'attente de notifications de changement séparément pour chaque flux créé par le gestionnaire de tâches. Par conséquent, lors de l'accès à la file d'attente, aucune synchronisation n'est requise. La section 2.2 décrit une méthode pouvant être utilisée pour combiner les files d'attente après exécution.


Figure 7. Notification des modifications internes de l'objet universel

Les notifications de changement ne sont pas nécessaires pour envoyer séquentiellement. Il y a un moyen de poster parallèle. Effectuer une tâche, le système fonctionne avec tous ses objets. Par exemple, comme les objets physiques interagissent les uns avec les autres, le système physique les contrôle pour déplacer, calculer les nouvelles forces, etc. Lors de la réception de notifications, l'objet système n'interagit pas avec d'autres objets de son système. Il interagit avec les extensions associées à elle. Cela signifie que les objets universels sont maintenant indépendants de l'autre et peuvent être mis à jour simultanément. Cette approche n'exclut pas les cas extrêmes qui doivent être pris en compte lors du processus de synchronisation. Cependant, il permet d'utiliser le mode d'exécution parallèle quand il semblait qu'il n'était possible que dans la série.

3.2.3. Directeur des services
Le gestionnaire de services fournit des systèmes d'accès aux fonctions d'autres systèmes qui seraient autrement indisponibles. Il est important de comprendre que l'accès aux fonctions est effectué à l'aide d'interfaces et non directement. Les informations sur les interfaces système sont également conservées dans le gestionnaire de services.
Pour éliminer les dépendances des systèmes les uns des autres, chacun d'entre eux n'a que petit ensemble Prestations de service. De plus, la possibilité d'utiliser un service est déterminée non par le système lui-même, mais le gestionnaire des services.


Figure 8. Exemple de gestionnaire de services

Le gestionnaire de services a une autre fonctionnalité. Il fournit un accès de systèmes aux propriétés d'autres systèmes. Les propriétés sont appelées valeurs spécifiques de systèmes spécifiques qui ne sont pas transmis dans le système de messagerie. Cela peut être une résolution d'écran d'extension dans le système graphique ou la valeur de la gravité en physique. Le gestionnaire de services ouvre l'accès à de telles données, mais ne leur permet pas de les contrôler directement. Il apporte des modifications dans les propriétés dans un virage spécial et les publie uniquement après une exécution cohérente. Veuillez noter que l'accès aux propriétés d'un autre système est assez rare et ne doit pas être abusé. Par exemple, il peut être nécessaire d'activer et de débrancher le mode maillage de cadre dans le système graphique à partir de la fenêtre de la console ou de modifier la résolution de l'écran à la demande du lecteur à partir de l'interface utilisateur. Cette fonctionnalité est principalement utilisée pour définir des paramètres qui ne changent pas de cadre à l'image.

3.2.4. Responsable de l'environnement
  • Le gestionnaire moyen assure le fonctionnement de l'environnement d'exécution du moteur. Ses fonctions peuvent être divisées en groupes suivants.
  • Variables: noms et valeurs de variables communes utilisées par toutes les parties du moteur. Typiquement, des valeurs variables sont définies lorsque la scène est chargée ou certains paramètres personnalisés. Le moteur et divers systèmes peuvent y accéder en envoyant la demande correspondante.
  • Exécution: données d'exécution, telles que la réalisation de l'exécution de la scène ou du programme. Ces paramètres peuvent être installés et demander à la fois les systèmes et le moteur.
3.2.5. Responsable de la plateforme
Le gestionnaire de plateformes implémente l'abstraction des défis du système d'exploitation et fournit également une fonctionnalité supplémentaire en plus de la simple abstraction. L'avantage de cette approche est l'encapsulation de plusieurs fonctions typiques dans un seul appel. C'est-à-dire qu'ils ne doivent pas être mis en œuvre séparément pour chaque élément causant, surchargeant ses détails sur les appels du système d'exploitation.
Considérez comme exemple appelez le gestionnaire de plate-forme pour télécharger la bibliothèque système dynamique. Il charge non seulement le système, mais reçoit également les points d'entrée de la fonction et provoque la fonction d'initialisation de la bibliothèque. Le gestionnaire stocke également le descripteur de bibliothèque et le décharge après la fin de l'opération.

Le gestionnaire de plateformes est également chargé de fournir des informations sur un processeur, telles que la prise en charge des instructions SIMD, et pour l'initialisation d'un certain mode de fonctionnement des processus. Aucune autre fonction pour la formation de demandes de système ne peut être utilisée.

4. Interfaces

Les interfaces sont des moyens d'interaction entre le cadre, les gestionnaires et les systèmes. Les cadres et les gestionnaires font partie du moteur, afin qu'ils puissent interagir directement les uns avec les autres. Les systèmes au moteur n'appartiennent pas. De plus, ils effectuent toutes différentes fonctions, ce qui conduit à la nécessité de créer une seule méthode d'interaction avec elles. Étant donné que les systèmes ne peuvent pas interagir avec les gestionnaires directement, il est nécessaire de fournir une autre méthode d'accès. Dans ce cas, toutes les fonctions des gestionnaires ne doivent pas être ouvertes aux systèmes. Certains d'entre eux ne sont que des cadres disponibles.

Interfaces définissent un ensemble de fonctions requises pour une utilisation méthode standard Accès. Il élimine le cadre de la nécessité de connaître les détails de la mise en œuvre de systèmes spécifiques, car il peut interagir avec eux uniquement au moyen d'un certain ensemble d'appels.

4.1. Interfaces Objet et Observateur

L'objectif principal des interfaces Objet et d'observateur est l'enregistrement de ce que les observateurs modifient les notifications de quels sujets, ainsi que d'envoyer de telles notifications. L'enregistrement et la rupture de la communication avec un observateur sont des caractéristiques standard pour tous les sujets inclus dans la mise en œuvre de leur interface.

4.2. Gestionnaires d'interfaces

Les gestionnaires, malgré le fait qu'ils sont des objets singleton, ne sont disponibles directement que pour le cadre. D'autres systèmes peuvent accéder aux gestionnaires uniquement via des interfaces qui ne représentent qu'une partie de leur fonctionnalité globale. Après l'initialisation, l'interface est transmise à un système qui l'utilise pour fonctionner avec certaines fonctions du gestionnaire.
Il n'y a pas d'interface unique pour tous les gestionnaires. Chacun d'entre eux a sa propre interface distincte.

4.3. Interfaces système

Pour rendre le cadre pour accéder aux composants du système, il a besoin d'interfaces. Sans eux soutiennent chacun nouveau système Le moteur devrait être mis en œuvre séparément.
Chaque système comprend quatre composants, donc les interfaces doivent être quatre. Nommément: le système, la scène, l'objet et la tâche. Description détaillée Voir la section 5, "Systèmes". Les interfaces sont des outils permettant d'accéder à des composants. Les interfaces système vous permettent de créer et de supprimer des scènes. Les interfaces de la scène, à leur tour, vous permettent de créer et de détruire des objets, ainsi que de demander des informations sur la tâche principale du système. L'interface de tâche est principalement utilisée par le gestionnaire de tâches lors de la définition des tâches dans le pool de flux.
Étant donné que la scène et l'objet, dans le cadre du système, doivent interagir entre eux et avec une scène universelle et l'objet auxquels ils sont liés, leurs interfaces sont également créées sur la base des interfaces sujettes et observateurs.

4.4. Les interfaces changent

Ces interfaces servent à transférer des données entre systèmes. Tous les systèmes qui apportent des modifications à un certain type doivent mettre en œuvre une telle interface. Par exemple, vous pouvez apporter la géométrie. L'interface géométrie comprend des procédés de détermination de la position, de l'orientation et de l'élément d'échelle. Tout système qui modifie la géométrie doit mettre en œuvre une telle interface afin qu'il n'existe aucune information sur les autres systèmes pour accéder aux données modifiées.

5. Systèmes

Les systèmes font partie du moteur qui est responsable de la mise en œuvre de la fonctionnalité de jeu. Ils effectuent toutes les tâches principales, sans laquelle le moteur n'aurait aucun sens. L'interaction entre le moteur et les systèmes est effectuée à l'aide d'interfaces (voir section 4.3, "Interfaces système"). Il est nécessaire de ne pas surcharger les informations du moteur sur différents types Systèmes. Grâce aux interfaces, le processus d'ajout d'un nouveau système devient beaucoup plus facile, car le moteur n'a pas besoin de prendre en compte tous les détails de la mise en œuvre.

5.1. Les types

Les systèmes de moteur peuvent être divisés en plusieurs catégories prédéterminées correspondant aux composants standard du jeu. Par exemple: géométrie, graphiques, physique (collision de solides), son, traitement d'entrée, aï et animation.
Les systèmes avec des fonctions non standard concernent une catégorie distincte. Il est important de comprendre que tout système qui modifie les données de catégorie spécifiques doit être conscient de l'interface de cette catégorie, car le moteur ne fournit pas de telles informations.

5.2. Composants du système

Pour chaque système, vous devez implémenter plusieurs composants. Voici certains d'entre eux: système, scène, objet et tâche. Tous ces composants servent à interagir avec différentes parties du moteur.
Le schéma ci-dessous montre des interactions entre différents composants.


Figure 9. Composants du système

Un circuit détaillé des liens entre les systèmes de moteur est donné à l'annexe B, le "schéma d'interaction du moteur et systèmes".

5.2.1. Système
Le composant "System", ou simplement le système, est responsable de l'initialisation des ressources système, qui ne changeront pratiquement pas lors du fonctionnement du moteur. Par exemple, un système graphique analyse les adresses de ressources pour déterminer l'emplacement et l'accélération du téléchargement lors de l'utilisation de la ressource. Il définit également la résolution de l'écran.
Le système est le principal point d'entrée du cadre. Il fournit des informations sur vous-même (par exemple, type de système), ainsi que des méthodes de création et de suppression de scènes.
5.2.2. Scène
Le composant "Scène", ou la scène système, est responsable de la gestion des ressources liées à la scène actuelle. La scène universelle utilise des scènes système pour développer la fonctionnalité grâce à l'utilisation de leurs fonctions. À titre d'exemple, une scène physique peut être apportée, ce qui est utilisé lors de la création d'un nouveau monde de jeu et, lors de l'initialisation de la scène, détermine les forces de gravité.
Les scènes prévoient des méthodes de création et de détruire des objets, ainsi que la composante "Tâche" pour traiter la scène et la méthode d'accès.
5.2.3. Un objet
Le composant "objet", ou l'objet système, appartient à la scène et est généralement associé au fait que l'utilisateur voit à l'écran. L'objet universel utilise un objet système pour développer la fonctionnalité, offrant ses propriétés comme elles propres.
Un exemple peut servir de prolongation géométrique, graphique et physique d'un objet universel pour afficher un faisceau de bois à l'écran. Les propriétés géométriques comprendront la position, l'orientation et l'échelle de l'objet. Pour l'afficher, le système graphique utilisera une grille spéciale. Et le système physique lui donnera les propriétés d'un solide pour calculer les interactions avec les autres corps et les forces de gravité actuelles.

Dans certains cas, dans l'objet système, il est nécessaire de prendre en compte les modifications de l'objet universel ou de l'une de ses extensions. À cette fin, vous pouvez créer une connexion spéciale qui vous permettra de suivre les modifications apportées.

5.2.4. Une tâche
Le composant "tâche" ou la tâche système est utilisé pour traiter la scène. La tâche reçoit une commande pour mettre à jour la scène du gestionnaire de tâches. Ceci est un signal de départ. fonctions système Aux objets de la scène.
La tâche doit être exécutée sur des sous-tâches, les distribuant également à l'aide du gestionnaire de tâches à un nombre encore plus grand de flux. C'est un moyen pratique de réduire le moteur en plusieurs processeurs. Cette méthode s'appelle la décomposition de données.
Les informations sur la modification des objets dans le processus de mise à jour des tâches de scène sont transmises au gestionnaire d'Etat. Pour plus de détails sur le gestionnaire d'état, reportez-vous à la section 3.2.2.

6. Combinaison de tous les composants

Tous les éléments décrits ci-dessus sont interconnectés et font partie d'un tout. Le fonctionnement du moteur peut être divisé en plusieurs étapes décrites dans les sections suivantes.

6.1. Initialisation de la scène

Le travail du moteur commence par l'initialisation des gestionnaires et des cadres.
  • Le cadre appelle le chargeur de scène.
  • En définissant quels systèmes de scène utiliseront, le téléchargeur appelle le gestionnaire de plate-forme pour télécharger les modules correspondants.
  • Le gestionnaire de plate-forme charge les modules correspondants et les transmet au gestionnaire d'interface, puis les appelle à créer un nouveau système.
  • Le module renvoie le pointeur de chargement à une instance du système qui implémente l'interface système.
  • Le gestionnaire de services enregistre tous les services que le module système fournit.


Figure 10. Initialisation des gestionnaires et des systèmes de moteur

6.2. Scène de téléchargement de scène

Le contrôle est renvoyé par le chargeur qui charge la scène.
  • Le chargeur de démarrage crée une scène universelle. Pour créer des instances de scènes système, il provoque des interfaces système, développant la fonctionnalité d'une scène universelle.
  • La scène universelle détermine quelles données peuvent modifier chaque scène système et les alertes sur les modifications nécessaires pour recevoir.
  • En comparant les scènes qui effectuent certaines modifications et souhaitent recevoir des alertes à leur sujet, la scène universelle transmet ces informations au gestionnaire d'État.
  • Pour chaque objet de scène, le chargeur de démarrage crée un objet universel, puis détermine les systèmes élargiront l'objet universel. La correspondance entre les objets système est déterminée par le même schéma utilisé pour les scènes. Il est également transmis au gestionnaire d'état.
  • En utilisant les interfaces de scène obtenues, le chargeur de démarrage crée des instances d'objets système et les utilise pour développer des objets universels.
  • Le planificateur demande des données sur les interfaces de scènes sur leurs tâches principales, de sorte que, dans le processus d'exécution de ces informations au gestionnaire de tâches.


Figure 11. Initialisation de la scène universelle et de l'objet

6.3. Jeu de cycle de scène

  • Le gestionnaire de plate-forme est utilisé pour traiter les fenêtres et d'autres éléments nécessaires à la plate-forme actuelle.
  • Ensuite, le contrôle passe le planificateur, qui attend que la fin de l'horloge continue à travailler.
  • À la fin du tact en mode libre étape par étape, le planificateur vérifie les tâches terminées. Toutes les tâches terminées (c'est-à-dire prêtes à exécuter) sont transmises au gestionnaire de tâches.
  • Le planificateur détermine les tâches terminées pour le tact actuel et les attendra.
  • Dans le mode d'exécution difficile à étapes, ces opérations sont répétées chaque horloge. Le planificateur envoie toutes les tâches au gestionnaire et s'attend à ce qu'ils effectuent.
6.3.1. Exécution de la tâche
Le contrôle va au gestionnaire de tâches.
  • Il forme une file d'attente de toutes les tâches reçues, alors que des flux gratuits apparaissent, il commence leur exécution. (Le processus d'exécution de la tâche varie en fonction des systèmes. Les systèmes ne peuvent fonctionner qu'avec une tâche ou pour traiter plusieurs tâches de la file d'attente simultanément, mettant ainsi la mise en œuvre d'une exécution parallèle.)
  • Dans le processus d'exécution de la tâche, peut fonctionner avec toute la scène ou uniquement avec certains objets, en modifiant leurs données internes.
  • Les systèmes doivent recevoir des notifications de tout changement de données générales (par exemple, position ou orientation). Par conséquent, lors de l'exécution d'une tâche, une scène système ou un objet informer un observateur sur les modifications. Dans ce cas, l'observateur agit en réalité en tant que contrôleur du changement, qui fait partie du gestionnaire d'État.
  • Le contrôleur de changement génère une file d'attente de notifications de changement pour le traitement ultérieur. Il ignore les changements qui ne concernent pas cet observateur.
  • Pour utiliser certains services, la tâche fait référence au gestionnaire de services. Le gestionnaire de services vous permet également de modifier les propriétés d'autres systèmes, inaccessible pour la transmission dans le mécanisme de messagerie (par exemple, le système de saisie de données modifie l'expansion de l'écran - la propriété du système graphique).
  • Les tâches peuvent également accéder au gestionnaire moyen pour obtenir des variables d'environnement et modifier l'état d'exécution (suspension de l'exécution, transition vers la scène suivante, etc.).


Figure 12. Gestionnaire de tâches et tâches

6.3.2. Mise à jour des données
Après avoir effectué toutes les tâches de l'horloge actuelle, le cycle de jeu principal fait référence au gestionnaire d'état pour démarrer l'étape de mise à jour des données.
  • Le gestionnaire d'état fait alternativement chacun de ses contrôleurs d'envoyer des notifications accumulées. Le contrôleur vérifie les observateurs d'envoyer des notifications sur les modifications de chacun des sujets.
  • Ensuite, il appelle l'observateur souhaité et lui dit de la modification (la notification inclut également un pointeur à l'interface sujet). En mode d'exécution libre étape par étape, l'observateur reçoit des données modifiées du contrôleur de modifications, mais dans le mode d'exécution de l'étape difficile, il devrait les demander au sujet lui-même.
  • En règle générale, les observateurs intéressés à recevoir des notifications sur les modifications de l'objet système sont d'autres objets système associés au même objet universel. Cela vous permet de diviser le processus de modification de plusieurs tâches pouvant être effectuées en parallèle. Pour simplifier le processus de synchronisation, toutes les extensions associées de l'objet universel peuvent être combinées dans une tâche.
6.3.3. Vérifiez les performances et quittez
La dernière étape du cycle de jeu est une validation de l'état du temps d'exécution. Il existe plusieurs états: travail, pause, scène suivante, etc. Si l'état "Travail" est sélectionné, l'itération du cycle suivant sera lancée. L'état "Sortie" désigne l'achèvement du cycle, la libération des ressources et de la sortie de l'application. D'autres États peuvent être mis en œuvre, par exemple "Pause", "Scène suivante", etc.

7. Conclusion

L'idée principale de cet article est énoncée à la section 2, "Etat de l'exécution parallèle". Grâce à la décomposition fonctionnelle et à la décomposition des données, il est possible de mettre en œuvre non seulement le moteur multithreading, mais également son évolutivité à un nombre encore plus grand de noyaux à l'avenir. Pour exclure les coûts de synchronisation, continuer à soutenir les données à jour, utilisez les gestionnaires d'état en plus du mécanisme de messagerie.

Le modèle "Observateur" est la fonction du mécanisme de messagerie. Il est important de comprendre le principe de son travail de bien choisir la méthode optimale de sa mise en œuvre pour le moteur. En fait, il s'agit du mécanisme d'interaction entre différents systèmes, qui fournit la synchronisation des données communes.

Un rôle important dans la distribution des charges est joué par la gestion des tâches. L'annexe D fournit des conseils sur la création d'un gestionnaire de tâches efficace pour le moteur de jeu.

Comme vous pouvez le constater, la multithreading du moteur de jeu peut être mise en œuvre grâce à un mécanisme de structure et de messagerie clairement définis. Avec cela, il est possible d'augmenter considérablement la productivité des transformateurs modernes et futurs.

Annexe A. Schéma moteur

Le traitement de démarrage est effectué à partir du cycle de jeu principal (voir Fig. 4, "Cycle de jeu principal").


Annexe B. Schéma d'interaction du moteur et systèmes


Annexe C. Observateur (modèle de conception)

Le modèle "Observateur" est décrit en détail dans le livre "Conception axée sur l'acceptation. Motifs de design », E. gamma, R. Helm, R. Johnson, J. Wlissides (" Motifs de conception: éléments de logiciels orientés d'objets réutilisables ", Gamma E., Helm R., Johnson R., Vlissides J.). En anglais, elle a été publiée pour la première fois en 1995 par Addison-Wesley Publishing House.

L'idée principale de ce modèle est la suivante: Si certains éléments doivent recevoir des notifications sur les modifications d'autres éléments, elles ne sont pas tenues d'afficher la liste de tous les changements possibles, en essayant de trouver les données requises. Le modèle implique la présence d'un sujet et d'un observateur, utilisé pour envoyer des notifications sur les changements. L'observateur surveille les modifications apportées au sujet. Le contrôleur de changement agit comme un intermédiaire entre les deux composants de données. Le schéma suivant illustre cette connexion.


Figure 13. Modèle "Observateur"

Ce qui suit décrit le processus d'utilisation de ce modèle.

  1. Le contrôleur de changement enregistre l'observateur et le sujet, dont il souhaite recevoir.
  2. Le contrôleur de changement est en réalité un observateur. Au lieu d'un observateur, avec le sujet, il s'enregistre. Le contrôleur de changement stocke également sa propre liste d'observateurs et enregistrés avec eux.
  3. Le sujet contribue à un observateur (c'est-à-dire le contrôleur de la modification) à sa liste des observateurs qui souhaitent recevoir des notifications sur ses modifications. Parfois, indique également le type de changement qui détermine les changements dans lesquels l'observateur s'intéresse. Cela vous permet d'optimiser le processus d'envoi de notifications sur les modifications.
  4. Modification des données ou du statut, le sujet notifie l'observateur via le mécanisme de rappel et transmet des informations sur les types modifiés.
  5. Le contrôleur de changement génère une file d'attente de notifications de changement et attend qu'un signal les distribue sur des objets et des systèmes.
  6. Au cours de la distribution, le contrôleur de changement fait appel à de vrais observateurs.
  7. Les observateurs demandent des informations sur les données modifiées ou sur un sujet du sujet (ou les obtenir avec des notifications).
  8. Avant de supprimer un observateur ou s'il n'a plus besoin de recevoir des notifications sur le sujet, il supprime un abonnement à ce sujet dans le contrôleur de changement.
Il y a beaucoup de en différentes manières Mettre en œuvre la distribution des tâches. Cependant, il est préférable de maintenir le nombre de flux de travail égaux au nombre de processeurs de plate-forme logiques disponibles. Essayez de ne pas nouer des tâches à un flux spécifique. Les tâches du temps de divers systèmes ne coïncident pas toujours. Cela peut conduire à une distribution de charge inégale entre les flux de travail et affecter l'efficacité. Pour simplifier ce processus, utilisez des bibliothèques de gestion des tâches, telles que

Compte tenu de la théorie de la multithreading, considérez l'exemple pratique - Pentium 4. Déjà au stade du développement de ce processeur, Intel Ingénieurs a continué de travailler à améliorer ses performances sans apporter des modifications à l'interface du programme. Les cinq moyens simples ont été pris en compte:

Augmenter la fréquence d'horloge;

Placement sur une seule puce de deux processeurs;

Introduction de nouveaux blocs fonctionnels;

Extension du convoyeur;

Utiliser de multithreading.

Le moyen le plus évident d'améliorer la vitesse consiste à augmenter la fréquence d'horloge sans changer d'autres paramètres. En règle générale, chaque modèle de processeur subséquent a une fréquence d'horloge légèrement supérieure à celle du précédent. Malheureusement, avec une augmentation directe de la fréquence d'horloge, les développeurs sont confrontés à deux problèmes: une augmentation de la consommation d'énergie (qui est pertinente pour ordinateurs portables et d'autres dispositifs informatiques fonctionnant sur des piles) et la surchauffe (ce qui nécessite de créer des dissipateurs de chaleur plus efficaces).

La deuxième méthode est la mise en place sur la puce de deux processeurs - relativement simple, mais elle est associée au doublement de la zone occupée par le microcircuit. Si chaque processeur est fourni avec sa propre mémoire cache, le nombre de microcirces sur la plaque est d'arrêt, mais cela signifie également doubler le coût de la production. Si, pour les deux processeurs, il existe une mémoire de cache courante, une augmentation significative de la zone occupée peut être évitée, mais dans ce cas, un autre problème se produit - la quantité de mémoire cache en termes de chaque processeur est divisée par deux, ce qui est inévitablement affecté par la performance. . De plus, si les applications de serveur professionnel sont en mesure d'utiliser pleinement les ressources de plusieurs transformateurs, dans les programmes de bureau classiques, le parallélisme interne est développé dans une grande mesure.

L'introduction de nouveaux blocs fonctionnels n'est pas non plus difficile, mais il est important de garder l'équilibre. Quelle est la signification des dix principaux blocs d'ALU, si la puce ne peut pas émettre des commandes au convoyeur à une vitesse qui vous permet de télécharger tous ces blocs?

Le convoyeur avec un nombre accru d'étapes capables de séparer les tâches en segments plus petits et de les traiter en courtes périodes de temps, d'une part, d'une part, d'une part, d'une part, d'une autre, améliore les conséquences négatives de la prévision incorrecte des transitions, des cachures, des interruptions. et d'autres événements qui violent les commandes normales de traitement du cours dans le processeur. De plus, pour mettre en œuvre pleinement les possibilités d'un convoyeur élargi, il est nécessaire d'augmenter la fréquence de l'horloge, ce qui, comme nous le savons, conduit à une consommation d'énergie accrue et au transfert de chaleur.

Enfin, il est possible de mettre en œuvre la multithreading. L'avantage de cette technologie consiste à introduire un flux logiciel supplémentaire qui vous permet d'entrer en vigueur les ressources matérielles qui auraient autrement été simples. Selon les résultats des études expérimentales, les développeurs Intel ont découvert que l'augmentation de la zone de microcircuit de 5% sur la mise en œuvre de multithreading pour de nombreuses applications donne une augmentation de 25%. Le premier processeur Intel avec support pour la multithreading était Heon 2002. Par la suite, à partir de la fréquence de 3,06 GHz, la multithreading a été introduite dans le Pentium 4. Le dirigeant Intel appelle la mise en œuvre de multithreading dans l'hypermatochisme de Pentium 4 (hyperthreading).

  • Didacticiel

Dans cet article, je vais essayer de décrire la terminologie utilisée pour décrire des systèmes pouvant exécuter plusieurs programmes en parallèle, c'est-à-dire multi-noyau, multiprocesseur, multi-filetés. Différents types de parallélisme dans la CPU IA-32 sont apparus à différents moments et de manière légèrement incohérente. Dans tout cela, il est assez facile de se confondre, en particulier pour que les systèmes d'exploitation cachent soigneusement les pièces de programmes d'application trop sophistiqués.

L'article a pour but de montrer qu'avec la diversité des configurations possibles de systèmes multiprocesseurs, multi-noyau et multi-filetés pour les programmes qui sont effectués sur eux, des opportunités sont créées à la fois pour l'abstraction (ignorer les différences) et prendre en compte des spécificités. (la possibilité de programmer la configuration).

Avertissement des signes ®, ™, dans l'article

Mon explique pourquoi les employés des entreprises devraient utiliser des marques de droit d'auteur dans les communications publiques. Dans cet article, ils devaient être utilisés assez souvent.

CPU

Bien sûr, le terme le plus ancien et le plus souvent utilisé et ambigu est un "processeur".

Dans le monde moderne, le processeur est alors (paquet) que nous achetons dans une belle boîte de vente au détail ou non un très beau sac OEM. Une essence indivisible insérée dans le connecteur (prise) sur carte mère. Même s'il n'y a pas de connecteur et qu'il est impossible de le supprimer, c'est-à-dire s'il est étroitement soudé, il s'agit d'une seule puce.

Systèmes mobiles (téléphones, tablettes, ordinateurs portables) et la plupart des ordinateurs de bureau ont un processeur. Les postes de travail et les serveurs disposent parfois de deux ou plusieurs processeurs sur une carte mère.

La prise en charge de plusieurs processeurs centraux dans un système nécessite de nombreux changements dans sa conception. Au moins besoin de leur fournir connexion physique (Fournissez plusieurs sockets sur la carte mère), résolvez les problèmes des problèmes d'identification du processeur (voir plus loin dans cet article, ainsi que ma note), coordonner l'accès à la mémoire et à la livraison des interruptions (contrôleur d'interruption doit pouvoir rouler des interruptions en plusieurs processeurs. ) et, bien sûr, le soutien du système d'exploitation. Malheureusement, je n'ai pas pu trouver un documentaire mentionnant le moment de créer le premier système multiprocesseur sur les processeurs Intel, mais Wikipedia affirme que les systèmes informatiques séquent les ont déjà fournis en 1987 à l'aide de processeurs Intel 80386. Un support généralisé pour plusieurs puces dans un système devient Disponible à partir de Intel® Pentium.

S'il y a plusieurs processeurs, chacun d'entre eux a son propre connecteur sur le tableau. Chacun d'entre eux dispose de copies indépendantes complètes de toutes les ressources, telles que des registres, des dispositifs d'exécution, des caches. Ils partagent la mémoire globale - RAM. La mémoire peut se connecter à eux de manière variable et plutôt non triviale, mais c'est une histoire séparée qui dépasse cet article. Il est important qu'avec tout scénario pour les programmes exécutables, l'illusion de la mémoire globale homogène doit être créée, accessible à partir de tous les processeurs inclus dans le système.


Décollage prêt! Intel® Desktop Board D5400XS

Cœur

Historiquement, le multi-noyau dans Intel IA-32 est apparu ultérieurement Intel® HyperThreading, mais dans une hiérarchie logique, elle va ensuite.

Il semblerait que s'il ya plus de processeurs dans le système, sa performance (sur les tâches pouvant utiliser toutes les ressources). Toutefois, si le coût des communications entre eux est trop important, l'ensemble de la victoire du parallélisme est tué par de longs retards dans la transmission de données communes. C'est ce qui est observé dans les systèmes multiprocesseurs - à la fois physiquement et logiquement, ils sont très éloignés les uns des autres. Pour une communication efficace dans de telles conditions, vous devez inventer des pneus spécialisés, tels que Intel® QuickPath Interconnect. La consommation d'énergie, la taille et le prix de la décision finale ne diminuent bien pas de tout cela. L'intégration élevée des composants - Les régimes qui exécutent des parties du programme parallèle doivent être atteints de sauvetage, il est nécessaire de se soulever, de préférence sur un cristal. En d'autres termes, plusieurs processeurs doivent organiser plusieurs graines, de tous identiques les uns avec les autres, mais travaillant de manière indépendante.

Les premiers processeurs multi-noyau IA-32 d'Intel ont été présentés en 2005. Depuis lors, le nombre moyen de noyaux dans le serveur, le bureau et les plates-formes mobiles augmentent régulièrement.

Contrairement à deux processeurs monocarifiés dans un système, ne séparant que la mémoire, deux noyaux peuvent également avoir des caches courantes et d'autres ressources responsables de l'interaction avec la mémoire. Le plus souvent, les caches de premier niveau restent privés (chaque noyau), alors que le deuxième et le troisième niveau peut être à la fois général et séparé. Une telle organisation du système réduit les retards dans la fourniture de données entre noyaux adjacents, surtout s'ils travaillent sur une tâche commune.


Microsentins du processeur Intel à quatre nœuds avec le nom du code NEHALEM. Les noyaux séparés sont mis en évidence, le cache total de troisième niveau, ainsi que les liens QPI vers d'autres processeurs et le contrôleur de mémoire global.

Hyperpot

Jusqu'à environ 2002, le seul moyen d'obtenir le système IA-32 capable d'exécuter deux programmes ou plus en parallèle, était d'utiliser des systèmes multiprocesseurs. Dans l'Intel® Pentium® 4, ainsi que la ligne Xeon avec le nom de code Foster (Netburst), une nouvelle technologie est présentée - Hyperthrons ou hyperpotions - Intel® HyperThreading (ci-après HT).

Il n'y a rien de nouveau sous le soleil. HT est un cas particulier que dans la littérature est appelé multithreading simultané (multithreading simultané, SMT). Contrairement aux noyaux «réels» qui sont des copies complètes et indépendants, dans le cas de HT dans un processeur, seule une partie des nœuds internes est dupliquée, principalement responsable du stockage des États-Unis - registres. Les nœuds exécutifs responsables de l'organisation et du traitement des données restent dans le singulier, et à tout moment, ils utilisent un maximum de l'un des flux. Comme le noyau, les hyperpotions sont divisées par des caches, mais à partir de ce que cela dépend du système spécifique.

Je n'essaierai pas d'expliquer tous les avantages et inconvénients des conceptions avec SMT en général et de HT en particulier. Un lecteur merveilleux peut trouver une discussion assez détaillée de la technologie dans de nombreuses sources et, bien sûr, à Wikipedia. Cependant, je vais noter ce qui suit moment importantExpliquer les limitations actuelles sur le nombre d'hyperpotions dans des produits réels.

Restrictions de flux
Quand la présence de "malhonnête" multi-noyau est-elle sous la forme de HT justifiée? Si un flux d'application n'est pas en mesure de charger tous les nœuds d'exécution dans le noyau, ils peuvent être «empruntés» à un autre flux. Il est généralement pour les applications ayant " goulot»Pas dans les calculs, mais lorsque vous accédez aux données, vous générez souvent des missiles de cache et forcé de s'attendre à ce que les données fournissent des données de la mémoire. À ce stade, le noyau sans HT sera obligé de faire du ralenti. La présence de HT vous permet de changer rapidement de nœuds d'exécution libre à un autre état d'architecture (car il est simplement dupliqué) et exécuter ses instructions. Il s'agit d'un cas particulier d'acceptation appelé cachette de latence, lorsqu'une opération longue, au cours desquelles les ressources utiles sont inactives, est masquée par une autre tâche parallèle. Si l'application dispose déjà d'un degré élevé de recyclage des ressources du noyau, la présence d'hyperpotions ne permettra pas d'obtenir une accélération - vous avez ici besoin de nuclei "honnête".

Scénarios de travail typiques pour les applications de bureau et de serveur conçues pour les architectures de la machine usage général, ont un potentiel de parallélisme mis en œuvre à l'aide de HT. Cependant, ce potentiel est "dépensé" rapidement. Peut-être pour cette raison, presque tous les processeurs IA-32, le nombre d'hyperpotions matérielles ne dépasse pas deux. Sur les scripts typiques, la victoire de l'utilisation de trois et plus d'hyperpotions serait petite, mais la perte de la taille du cristal, sa consommation d'énergie et sa valeur sont importantes.

Une autre situation est observée sur des tâches typiques effectuées sur des scénaristes vidéo. Par conséquent, ces architectures sont caractérisées par l'utilisation de la technologie SMT avec un plus grand nombre de fils. Puisque Intel® Xeon Phi Coprocesses (présenté en 2010) sont idéologiquement et généalogiquement près des cartes vidéo, elles peuvent être quatre L'hypertension sur chaque noyau est unique pour la configuration IA-32.

Processeur logique

Parmi les trois "niveaux" de parallélisme (processeurs, noyaux, hyperpotts), certains ou même tout peuvent être manquants dans un système particulier. Ceci est influencé paramètres du BIOS (Multi-noyau et multithreading sont déconnectés de manière indépendante), les caractéristiques de la microarchitecture (par exemple, HT étaient absentes dans Intel® Core ™ Duo, mais ont été renvoyées avec la libération de Nehalem) et des événements au cours du fonctionnement du système (les serveurs multiprocesseurs peuvent éteindre les processeurs refusés. En cas de dysfonctionnement et continuez à «voler» sur le reste). Comment ce zoo de parallélisme à plusieurs niveaux est-il vu par le système d'exploitation et a finalement appliqué des applications?

Ensuite, pour la commodité, nous désignons le nombre de processeurs, des noyaux et des flux dans un système à trois voies ( x., y., z.), où x. - c'est le nombre de processeurs, y. - Nombre de noyaux dans chaque processeur et z. - Le nombre d'hyperpotions dans chaque noyau. Ensuite, je vais appeler ce triple topologie - terme établi, peu d'avoir avec une section de mathématiques. Composition p. = xyz. détermine le nombre d'entités appelées processeurs logiques Systèmes. Il détermine le nombre total de contextes indépendants de processus appliqués dans le système avec une mémoire partagée exécutable en parallèle, qui système opérateur Forcé de prendre en compte. Je dis "forcé," car il ne peut pas gérer la procédure d'exécution de deux processus sur divers processeurs logiques. Cela s'applique également aux hyperpotions: bien qu'ils travaillent "systématiquement" sur un noyau, l'ordre spécifique est dicté par équipement et n'est pas disponible pour surveiller ou gérer des programmes.

Le plus souvent, le système d'exploitation se cache des applications finales. Caractéristiques de la topologie physique du système sur lequel elle est en cours d'exécution. Par exemple, trois topologies suivantes: (2, 1, 1), (1, 2, 1) et (1, 1, 2) - OS seront représentées sous forme de deux processeurs logiques, bien que la première d'entre elles ait deux processeurs, la Deuxièmement, deux noyaux, et le troisième n'est que deux ruisseaux.


Windows Task Manager affiche 8 processeurs logiques; Mais combien cela est-il dans les processeurs, les noyaux et les hyperpots?


Le haut Linux montre 4 processeurs logiques.

Il est tout à fait pratique pour les créateurs d'applications appliquées - ils n'ont pas à traiter souvent de manière insignifiante pour eux des fonctionnalités de l'équipement.

Définition du logiciel de topologie

Bien entendu, l'abstraction de la topologie dans un nombre unique de processeurs logiques dans certains cas crée une raison de la confusion et des malentendus (dans les différends Internet à chaud). Les applications informatiques souhaitant sortir de la performance maximale du fer nécessitent un contrôle détaillé sur l'endroit où leurs flux seront placés: se rapprocher de l'autre sur des hyperpots voisins ou inversement sur différents processeurs. La vitesse de communication entre les processeurs logiques dans la composition d'un noyau ou du processeur est nettement supérieure au taux de transfert de données entre les processeurs. La possibilité d'une inhomogénéité dans l'organisation mémoire vive Complique également la photo.

Les informations sur la topologie du système dans son ensemble, ainsi que la position de chaque processeur logique de l'IA-32 sont disponibles à l'aide de l'instruction CPUID. Depuis l'apparition des premiers systèmes multiprocesseurs, le schéma d'identification des processeurs logiques s'est développé plusieurs fois. À ce jour, sa partie est contenue dans des feuilles 1, 4 et 11 CPUID. Laquelle des draps doit être vue, vous pouvez déterminer du schéma de principe suivant tiré de l'article:

Je ne vais pas piquer tous les détails des différentes parties de cet algorithme. Si vous êtes intéressé, cela peut être consacré à la partie suivante de cet article. Je vais quitter le lecteur du lecteur dans lequel cette question est compréhensible aussi détaillée que possible. Ici, je vais d'abord décrire brièvement ce que l'APIC est et comment elle est associée à la topologie. Ensuite, envisagez de travailler avec une feuille de 0xb (onze en nombres décimaux), qui est actuellement le dernier mot de la "construction de pics".

ID APIC
L'APIC locale (contrôleur d'interruption programmable avancé) est un périphérique (désormais inclus dans le processeur), responsable de la collaboration avec des interruptions, qui vient à un processeur logique spécifique. Chaque processeur logique a sa propre apic. Et chacun d'entre eux dans le système devrait avoir signification unique ID APIC. Ce numéro est utilisé par interruption des contrôleurs à adresser lors de la délivrance de messages et de tous les autres (par exemple, le système d'exploitation) - pour identifier les processeurs logiques. La spécification de ce contrôleur d'interruption a évolué, passant de la puce de pic Intel 8259 via une double photo, APIC et XAPIC à X2apic.

Actuellement, la largeur du nombre stocké dans APIC ID a atteint un 32 bits complets, bien que dans le passé, elle était limitée à 16, et même plus tôt - seulement 8 bits. Aujourd'hui, les vestiges de vieux jours sont dispersés dans la CPUID, mais les 32 bits d'ID APIC sont retournés à CPUID.0XB.EDX. Sur chaque processeur logique, l'exécution indépendante de l'instruction CPUID reviendra à sa valeur.

Filmer des liens connexes
L'ID APIC elle-même ne dit rien sur la topologie. Pour savoir ce que sont les deux processeurs logiques à l'intérieur du même physique (c'est-à-dire des "frères" avec des hyperthms), quelles sont les deux à l'intérieur d'un seul processeur et qui sont également du tout dans des processeurs différents, il est nécessaire de comparer leurs valeurs d'identification APIC. En fonction du degré de parenté, certains de leurs bits coïncideront. Ces informations sont contenues dans la console de CPUID.0XB, qui sont codées à l'aide de l'opérande en ECX. Chacun d'entre eux décrit la position du champ de bits de l'un des niveaux de topologie dans EAX (plus précisément, le nombre de bits à décaler dans l'ID APIC à droite pour éliminer les niveaux de topologie inférieurs), ainsi que le Type de ce niveau - Hyperpotions, un noyau ou un processeur, en ECX.

Les processeurs logiques qui sont à l'intérieur d'un seul noyau coïncideront toutes les bits d'ID APIC, à l'exception du champ SMT. Pour les processeurs logiques situés dans un processeur, tous les bits sauf les champs Core et SMT. Étant donné que le nombre de sublitters dans CPUID.0XB peut augmenter, ce schéma vous permettra de conserver une description des topologies et de plus de niveaux de niveau s'il ya nécessaire à l'avenir. De plus, il sera possible d'introduire des niveaux intermédiaires entre ceux existants.

Une conséquence importante de l'organisation de ce système est que, dans l'ensemble de tous les ID de l'APIC de tous les processeurs logiques du système, peut être "Trous", c'est-à-dire Ils ne seront pas séquentiellement. Par exemple, dans un processeur multicœurs avec l'arrêt HT, tous les ID APIC peuvent être bien connus, car le bit plus jeune responsable de l'encodage du nombre d'hyperpottop sera toujours zéro.

Je note que cpuid.0xb n'est pas la seule source de Informations sur les processeurs logiques disponibles pour le système d'exploitation. La liste de tous les processeurs accessibles, ainsi que leurs valeurs d'identification APC, sont codées dans la table ACPI de MADT.

Systèmes d'exploitation et topologie

Les systèmes d'exploitation fournissent des informations sur la topologie des processeurs logiques aux applications utilisant leurs propres interfaces.

Sous Linux, les informations sur la topologie sont contenues dans pseudo-file / proc / cpuinfo, ainsi que la sortie de la commande dmidecode. Dans l'exemple ci-dessous, je filtre le contenu de CPUInfo sur un système à quatre nœuds sans HT, ne laissant que des entrées relatives à la topologie:

Texte caché

[Email protégé]: ~ $ CAT / PROC / CPUINFO | GREP "ProSessor \\ | PHYSIQUE \\ ID \\ | SIBLINGS \\ | CORE \\ | | CORELS \\ | APICID" Processeur: 0 ID physique: 0 Soifs: 0 Core ID: 0 CPU CORELS: 2 APICID: 0 Apicide initial: 0 Processeur: 1 ID physique: 0 frères et sœurs: 4 Core ID: 0 CPU CORELS: 2 APICID: 1 Apicide initial: 1 Processeur: 2 Identifiant physique: 0 frères et sœurs: 4 Core ID: 1 CPU CORELS: 2 Apicide: 2 Apicide initial: 2 Processeur: 3 ID physique: 0 frères et sœurs: 4 ID de noyau: 1 CPU CORELS: 2 Apicide: 3 Apicide initial: 3

La topologie FreeBSD est signalée via le mécanisme SYSTL dans la variable Kern.SCHED.Topology_Spec sous la forme de XML:

Texte caché

[Email protégé]: ~ $ SYSCTL KERN.SCHED.TOPOLOGIE_SPEC KERN.SCHED.TOPOLOGIE_SPEC: 0, 1, 2, 3, 4, 5, 6, 7 0, 1, 2, 3, 4, 5, 6, 7 0, 1 Groupe de fil.Groupe SMT. 2, 3 Groupe de fil.Groupe SMT. 4, 5 Groupe de fil.Groupe SMT. 6, 7 Groupe de fil.Groupe SMT.

Dans MS Windows 8, des informations sur la topologie sont visibles dans le gestionnaire de tâches du gestionnaire de tâches.

Pour industrie de l'information Le début du XXIe siècle a coïncidé avec des déplacements pouvant être décrits comme "tectoniques". Les signes d'une nouvelle ère devraient inclure l'utilisation d'architectures axées sur les services (architecture orientée-service, SOA), configurations de cluster et beaucoup d'autres, y compris les processeurs multicœurs. Mais, bien sûr, la cause fondamentale de ce qui se passe est le développement de la physique des semi-conducteurs, dont la conséquence est devenue une augmentation du nombre d'éléments logiques par unité de surface, qui obéit la loi de Gordon Moore. Le nombre de transistors sur le cristal est déjà calculé par des centaines de millions et va bientôt surmonter le milliardiat frontalier, à la suite de laquelle la loi connue de la dialectique se manifeste inévitablement avec la relation de changements quantitatifs et qualitatifs. Dans les conditions modifiées, une nouvelle catégorie vient à l'avant complexitéet les systèmes deviennent complexes et sur le micro-niveau (processeurs) et sur le niveau macro (systèmes d'information d'entreprise).

Dans une certaine mesure, ce qui se passe dans le monde informatique moderne peut être assimilé à la transition évolutive qui s'est produite il y a des millions d'années, lorsque des organismes multicellulaires sont apparus. Au moment où la complexité d'une cellule a atteint une certaine limite et que l'évolution ultérieure a suivi la voie du développement de la complexité des infrastructures. La même chose arrive avec systèmes informatiques: La complexité d'un noyau du processeur, ainsi que de l'architecture d'entreprise monolithique systèmes d'information Atteint un certain maximum. Maintenant, le niveau macro est la transition des systèmes monolithiques à la composante (ou composé de services) et l'attention du développeur axée sur le logiciel d'infrastructure de la couche intermédiaire et de nouvelles architectures de processeur apparaissent sur le niveau micro.

Littéralement à tout le moins, l'idée de la complexité a commencé à perdre du bon sens, se transformant en un facteur indépendant. À cet égard, la complexité n'est pas encore complètement comprise et l'attitude envers elle n'est pas complètement définie, bien que, bien que, pendant près de 50 ans, il existe une discipline scientifique distincte, également appelée "la théorie des systèmes complexes". (Rappelez-vous que dans la théorie du "complexe" appelé le système, dont les composants individuels sont combinés à une méthode non linéaire; un tel système n'est pas seulement la somme des composants, car elle se produise dans des systèmes linéaires.) On ne peut que être Surpris que la théorie des systèmes ne soit pas encore perçue par les spécialistes et les entreprises, dont l'activité qui les conduit à la création de ces systèmes complexes au moyen de technologies de l'information.

"Bouteille" Architecture Von Neymanan

Sur le niveau micro, un analogue de la transition provenant d'organismes à cellules à des agences multicellulaires peut être transition à partir de processeurs mono-core à multi-noyau (multiprocessoires de puce, CMP). CMP donne l'une des possibilités de surmonter la faiblesse congénitale des transformateurs modernes - la «gorge de bouteille» de l'architecture von Neymanan.

C'est ce que John Bacik a déclaré à la cérémonie de présentation du prix Tyuringov en 1977: "Qu'est-ce qu'un ordinateur sur le fond de Nimanan? Quand il y a 30 ans, John Von Neuman et d'autres offrent leur architecture d'origine, l'idée semblait élégante, pratique et permettant de simplifier la solution d'un certain nombre de tâches d'ingénierie et de programmation. Et bien que, au cours de la dernière fois, les conditions qui existaient au moment de sa publication ont été radicalement modifiées, nous identifions nos idées sur les ordinateurs avec ces anciens concepts. Dans la présentation la plus simple, l'ordinateur Nimanian est composé de trois parties: il s'agit d'un processeur central (processeur ou processeur), mémoire et connectage de leur canal, qui sert à échanger des données entre la CPU et la mémoire, ainsi que de petites portions (uniquement par un mot (uniquement par un mot). Je suggère d'appeler ce canal "Bouteille de bouteille de bouteille de fond NEYMANAN." Il doit sûrement y avoir une solution moins primitive que de pomper une énorme quantité de données à travers une "gorge de bouteille étroite". Un tel canal crée non seulement un problème de trafic, mais constitue également une "bouteille de gorge intelligente", qui impose la pensée "salade" des programmeurs, ne permettant pas de discuter dans des catégories conceptuelles plus élevées. "

La plus grande renommée de Bakusa a apporté la création au milieu des années 50 de la langue de la Fortrane, qui, depuis plusieurs décennies, c'était le moyen le plus populaire de création de programmes de règlement. Mais plus tard, apparemment, BACUS était profondément conscient de ses faiblesses et s'est rendu compte qu'il développait la "langue de fond-neimanovsky" de toutes les langues de haut niveau. Par conséquent, la principale pathologie de sa critique était principalement confrontée à des méthodes de programmation imparfaites.

À partir du moment de la discours de Bacus de prononce dans la programmation, des changements remarquables survenus, des technologies fonctionnelles et orientées objet sont apparues, et avec leur aide réussie à surmonter ce que Bacus appelé la "bouteille intelligente-Nimanovsky". Cependant, la cause des racines architecturales de ce phénomène, maladie congénitale du canal entre la mémoire et le processeur - son débit limité - n'a pas disparu, malgré les progrès dans le domaine de la technologie au cours des 30 dernières années. Au fil des ans, ce problème est constamment aggravé, car la vitesse de la mémoire augmente beaucoup plus lentement que la performance des transformateurs et l'écart entre eux devient de plus en plus.

Le fond de l'architecture Nimanovsk de l'ordinateur n'est pas le seul possible. Du point de vue de l'organisation des commandes d'échange entre le processeur et la mémoire, tous les ordinateurs peuvent être divisés en quatre classes:

  • SISD (instructions simples données unique) - "Un flux de commandes, un flux de données" ";
  • Simd (instruction unique multiplier des données) - un flux de commandes, de nombreux flux de données;
  • MISD (instructions multiples données unique) - de nombreux flux de commandement, un flux de données;
  • MIMD (instruction multiple plusieurs données) - Beaucoup de flux de commandes, de nombreux flux de données.

De cette classification, on peut voir que la machine Nimanovskaya est un cas particulier qui tombe dans la catégorie SISD. Des améliorations possibles dans le cadre de l'architecture SISD sont limitées aux convoyeurs en ligne et à d'autres nœuds fonctionnels supplémentaires, ainsi qu'à l'utilisation de différentes méthodes de mise en cache. Deux autres catégories d'architectures (SIMD, qui incluent des processeurs vectoriels et des architectures de convoyeur MISD) ont été mises en œuvre dans plusieurs projets, mais ne sont pas devenues massives. Si vous restez au sein de cette classification, la seule possibilité de surmonter les restrictions de la "bouteille de gorge" reste le développement des architectures de la classe MIMD. Dans leur cadre, de nombreuses approches sont trouvées: il peut s'agir de diverses architectures parallèles et de grappes et de transformateurs multi-filetés.

Il y a quelques années, en raison de restrictions technologiques, tous les processeurs multi-filetés ont été construits sur la base d'un noyau et de telles multi-dimensions ont été appelées "simultanées" - Multhreading simultané (SMT). Et avec l'avènement de processeurs multicœurs, un type alternatif de multi-dimensions est apparu - MultiProcesseurs de puce (CMP).

Caractéristiques des processeurs multi-filetés

La transition de processeurs simples à une seule fois à un conjugué multi-écoulement logiquement complexe avec surmonter des difficultés spécifiques et non encore satisfaisantes. Le fonctionnement de l'appareil dans lequel le processus d'exécution est divisé en agents ou threads (threads) comporte deux caractéristiques:

  • principe de non-détermination (principe d'indétermination). Dans une application multi-threadée, le processus est divisé en agents de flux interagissant sans certitude pré-convenu;
  • principe incertain. La manière dont les ressources seront distribuées entre les agents de flux sont également inconnues à l'avance.

En raison de ces caractéristiques, le travail de processeurs multi-filetés est fondamentalement différent des calculs déterministes sur le schéma Nimanov. Dans ce cas, l'état actuel du processus ne peut pas être défini comme une fonction linéaire de l'état précédent et reçu sur l'entrée des données, bien que chacun des processus puisse être considéré comme un micromestyle nimanan. (Dans l'application au comportement des flux, vous pouvez même utiliser le terme «Ovieritait» utilisé dans la physique quantique.) La présence de ces fonctionnalités apporte le processeur multi-thread aux idées sur système complexeMais avec un point de vue purement pratique, il est clair que, au niveau de la mise en œuvre des processus, aucune non déterministe ni incertitude, et encore plus sur la bizarrerie et la parole ne peuvent pas être. Le programme correctement exécuté ne peut pas être étrange.

Dans la forme la plus générale, un processeur multi-thread est composé de deux types de primitives. Le premier type est une ressource qui prend en charge le flux d'un flux, appelé mutex (à partir de l'exclusion mutuelle - "exception mutuelle") et les seconde événements. Le chemin qui est physiquement mis en œuvre par l'un ou l'autre Mutex dépend du schéma sélectionné - SMT ou CMP. Dans tous les cas, le processus est réduit au fait que le prochain flux capture le mutex lors de son exécution, puis le libère. Si MuTex est occupé dans un seul flux, le deuxième flux ne peut pas l'obtenir. La procédure spécifique pour transférer des pouvoirs à la possession de mutex d'un flux à un autre peut être aléatoire; Cela dépend de la mise en œuvre de la gestion, par exemple dans un système d'exploitation spécifique. Dans tous les cas, la gestion doit être construite de sorte que les ressources composées de mutex soient distribuées correctement et l'effet d'incertitude a été supprimé.

Les événements sont des objets (événement), signalant la modification de l'environnement externe. Ils peuvent se traduire en mode veille avant un autre événement ou signaler leur état à un autre événement. De cette manière, les événements peuvent interagir les uns avec les autres et la continuité des données entre les événements devrait être assurée. Exécution en attente Un agent doit informer la volonté des données. Et comme dans la distribution de mutex, l'effet de l'incertitude doit être supprimé, alors lorsque vous travaillez avec des événements doit être supprimé par l'effet inconnu. Pour la première fois, le schéma SMT a été mis en œuvre dans les processeurs Compaq Alpha 21464, ainsi que dans Intel Xeon MP et Itanium.

Logiquement, CMP est plus simple: le parallélisme est assuré par le fait que chacun des threads est traité par son propre noyau. Mais si l'application ne peut pas être divisée en flux, elle (en l'absence de mesures spéciales) est traitée par un noyau, et dans ce cas, la performance globale du processeur est limitée à la vitesse d'un noyau. À première vue, le processeur construit selon le schéma SMT est plus flexible et donc ce schéma est préférable. Mais une telle assertion n'est vraie que à faible densité de transistors. Si la fréquence est mesurée par des mégatéreurs et que le nombre de transistors dans un cristal s'approche des milliards et que les retards de transmission des signaux deviennent grands que le temps de commutation, les avantages reçoivent la microarchitecture CMP dans laquelle les éléments de calcul associés sont localisés.

Cependant, la parallélisation physique entraîne le fait que le CMP n'est pas trop efficace avec des calculs consécutifs. Pour surmonter cet inconvénient, l'approche est utilisée, appelée "multi-dimensionnement spéculative" (multithreading spéculatif). En russe, le mot "spéculatif" a une nuance sémantique négative, nous appellerons donc une telle multidimensionnelle du "conditionnel". Cette approche suggère une prise en charge matérielle ou logicielle pour fiction d'une application série de flux conditionnels, correspondant à leur mise en œuvre et à l'intégration des résultats en mémoire.

Evolution CMP

Les premiers processeurs de masse CMP étaient destinés au marché du serveur. Indépendamment du vendeur, ils ont essentiellement deux processeurs supercalar indépendants sur un substrat. La principale motivation de la création de telles structures consiste à réduire le volume de sorte que, d'une base constructive, il peut s'agir de "emballages" plus de processeurs, augmentant ainsi la puissance spécifique par unité de volume (qui est essentielle aux centres de données modernes). Ensuite, au niveau du système général, certaines économies supplémentaires réalisent, puisque les processeurs sur une utilisation des ressources générales du système de cristal, telles que les communications à grande vitesse. Typiquement, il n'y a qu'une interface système commune entre les processeurs adjacents ( figure. une, b).

Les apologistes pour l'utilisation des processeurs CMP justifient davantage (plus de deux) l'augmentation du nombre de noyaux par les caractéristiques de la charge de serveur, qui distingue ce type d'ordinateurs de systèmes incorporés ou destinés aux systèmes informatiques massifs. Une grande performance globale est requise du serveur, mais le retard dans le système n'est pas si critique. Exemple trivial: l'utilisateur peut simplement ne pas remarquer un délai millisecond dans l'apparence d'une page Web mise à jour, mais réagit très douloureusement à la surcharge de serveur, ce qui peut entraîner des interruptions de maintenance.

La spécificité de la charge donne aux processeurs CMP un autre avantage notable. Disons que le remplacement du processeur double-noyau de même noyau, vous pouvez doubler la fréquence d'horloge à la même performance. Dans le même temps, le temps de traitement théorique d'une demande séparée peut augmenter deux fois, mais comme la séparation physique des flux réduit la restriction de la "gorge de la bouteille" de l'architecture Nymananovsk, le délai total sera nettement inférieur au double. À la fréquence inférieure et à la complexité d'un noyau, la consommation d'énergie est considérablement réduite et avec un nombre croissant de noyaux, les arguments énumérés en faveur du CMP ne sont que renforcés. Par conséquent, la prochaine étape d'acquittement logiquement consiste à collecter plusieurs noyaux et à les combiner avec une mémoire de cache courante, par exemple, comme dans le projet HYDRA (Figure 1, B). Et puis vous pouvez compliquer le noyau et les rendre multi-filetés, mis en œuvre dans le projet Niagara (Fig. 1, D).

La complexité des transformateurs a une autre manifestation importante. La conception des milliards de composants de numérotation de produit devient une tâche de plus en plus laborieuse - malgré l'utilisation d'outils d'automatisation. Il est important que nous assistons à plus d'une décennie "porter à l'esprit" l'architecture IA-64. La conception du processeur CMP est sensiblement plus simple: s'il existe un noyau développé, il peut être reproduit dans les quantités nécessaires et la conception est limitée par la création de l'infrastructure cristalline interne. De plus, la simplicité des noyaux simplifie la conception plastiques systèmequi se résume à la mise à l'échelle et, finalement, les indicateurs des sous-systèmes d'E / S sont modifiés.

Malgré les arguments ci-dessus, il n'existe aucun motif raisonnable d'une déclaration sans équivoque sur les avantages du CMP par rapport à SMT. L'expérience de la création de processeurs mettant en œuvre SMT est beaucoup plus: à partir du milieu des années 80, plusieurs dizaines de produits expérimentaux et plusieurs transformateurs série ont été créés. L'histoire du développement du CPM est toujours courte: si vous ne prenez pas compte de la famille des processeurs de signalisation Spécialisés Texas Instruments TMS 320C8X, le premier projet réussi est devenu Hydra, fait dans l'université de Standford. Parmi les projets de recherche universitaires destinés à la construction de processeurs CMP sont également connus trois autres - Wisconsin Multisalar, Carnegie-Mellon Stampede et MIT M-Machine.

Microprocesseur Hydra.

Le cristal Hydra se compose de quatre noyaux de processeur basés sur l'architecture de la RISC MIPS. Chaque noyau a un cache de commande et un cache de données, et tous les noyaux sont combinés dans un deuxième cache de deuxième niveau. Les processeurs effectuent un ensemble normal de commandes MIPS plus des commandes de stockage conditionnelles (stockez conditionnel ou SC), conçues pour implémenter des primitives de synchronisation. Les processeurs et la mémoire de cache de second niveau sont combinés à des pneus de lecture / écriture et, de plus, il existe une adresse auxiliaire et des pneus de contrôle. Tous ces pneus sont virtuels, c'est-à-dire de manière logique par des pneus câblés et sont physiquement divisés en une pluralité de segments utilisant des répéteurs et des tampons, ce qui permet d'augmenter la vitesse des cœurs.

Le pneu de lecture / enregistrement joue le rôle du système. En raison de son emplacement à l'intérieur du cristal, il a suffisamment débit Pour fournir des échanges avec le cache pour un cycle. Atteindre ces indicateurs de performance de performance, même dans les architectures multiprocesseurs traditionnelles les plus chères difficiles en raison des restrictions physiques du nombre contacts externes processeurs. Un bus d'échange efficace avec la mémoire cache empêche le problème de l'émergence de la "bouteille de gorge" entre nuclei et mémoire.

Les tests Hydra avec des charges avec un parallélisme expressément prononcé sur des applications Web et serveur typiques ont montré que la performance des quatre cœurs comparé à un noyau augmente de 3-3,8 fois, qui est pratiquement linéaire. Cela donne des raisons de croire que les processeurs de ce type seront tout à fait "apte" dans ces applications dans lesquelles des serveurs avec architecture SMP sont utilisés. Mais il est clair que le processeur devrait fonctionner de manière assez efficace avec des applications cohérentes. L'une des tâches les plus importantes est donc de mettre en œuvre une multi-dimensionnalité conditionnelle. En Hydra, il est mis en œuvre au niveau matériel et le choix de cette approche est justifié par le fait qu'il ne nécessite pas de coûts supplémentaires pour la programmation des applications parallèles.

La multi-dimension conditionnelle est basée sur la partition de la séquence de commande de programme sur les flux pouvant être effectués en parallèle. Naturellement, il peut y avoir une interdépendance logique entre ces flux et le mécanisme de synchronisation spécial est incorporé à leur processeur. L'essence de ses travaux est réduite au fait que si certains threads nécessitent des données d'un flux parallèle, et ils ne sont pas encore prêts, puis l'exécution d'un tel flux est suspendue. En fait, il existe des éléments de non-détermination, qui ont été discutés ci-dessus. Le processus de synchronisation est assez compliqué car il est nécessaire de déterminer toutes les dépendances possibles entre les threads et les conditions de synchronisation. La synchronisation conditionnelle vous permet de paralliser les programmes sans savoir avoir une connaissance préalable de leurs propriétés. Il est important que le mécanisme de synchronisation soit dynamique, cela fonctionne sans l'intervention d'un programmeur ou d'un compilateur, qui n'est capable que pour la division statique des applications aux flux. Les tests du modèle basé sur différents tests ont montré que les moyens de multi-dimensions conditionnelles vous permettent d'accroître la performance du processeur plusieurs fois et du parallélisme plus évident caractérisé par un test, moins la valeur est caractérisée.

En 2000, Afara a été créée dans la situation du strict secret. Ses fondateurs sont devenus le professeur Kunle Olukotun de l'Université de Stanford et le développeur bien connu des transformateurs de processeurs Kon, expérimentés dans des microsystèmes Intel et Sun. Kon était l'un des auteurs des processeurs I860 et I960 RISC dans la première de ces sociétés et ultrasparc-i dans la seconde. Sous son leadership, Hydra a été recyclé sous les cœurs du processeur sur la base du processeur SPARC. En 2002, Afara a été achetée par Sun Microsystems, et cela a mis fin à l'histoire du projet HYDRA et l'histoire de Niagara a commencé.

Niagara - "Alliage" Majc et Hydra

Au processeur UltrasParc T1, plus connu sous le nom de Niagara, deux prédécesseurs principaux - Hydra et Majc.

Au milieu des années 90, sur une vague de passe-temps, des processeurs Java spécialisés, le Sun Microsystems a tenté de créer un processeur «avec un très long mot» - très longue mot d'instruction (VLIW). Cette initiative a été nommée Majc (architecture de microprocesseur pour l'informatique Java). Comme dans d'autres projets commençant à cette époque (Intel IA-64 Itanium), dans ce cas, il y avait une tâche de transférer certaines des opérations les plus difficiles à maintenir le compilateur. La logique de transistor libérée peut être utilisée pour créer des nœuds fonctionnels plus productifs (unités fonctionnelles) afin de fournir un échange productif de commandes et de données entre les processeurs, la mémoire cache et la mémoire de base. Ainsi, la "bouteille de la bouteille" de fond-nimanovsky a été surmontée.

Majc était différent de la plupart des processeurs en l'absence de coprocesseurs spécialisés (sous-processus), qui sont communément appelés dispositifs fonctionnels destinés à effectuer des opérations avec des entiers, des numéros de points flottants et des données multimédia. Tout appareils fonctionnels étaient les mêmes capables d'effectuer des opérations, qui, d'une part, ont réduit l'efficacité des opérations individuelles, mais sur l'autre élevant le taux d'utilisation de l'ensemble du processeur.

Niagara incarne la meilleure des deux approches alternatives de la mise en œuvre de multi-dimensions - SMT et CMP. À première vue, c'est très similaire à Hydra, mais plutôt Hydra peut être appelé "Layout" Niagara. En plus du fait que, dans le second, deux cœurs, chacun d'entre eux peut traiter quatre ruisseaux.

Le processeur Niagara fournit un support matériel pour effectuer 32 threads divisés en huit groupes (quatre threads chacun). Pour effectuer chaque groupe, sert son canal de traitement de pipeline SPARC ( fig.2). C'est un noyau de processeur, construit conformément à l'architecture de SPARC V9. Chaque pipeline SPARC contient un cache de premier niveau pour les commandes et les données. Ensemble, 32 ruisseaux utilisent une mémoire cache de deuxième niveau d'une capacité de 3 Mo, divisée en quatre banques. Le commutateur connecte huit noyaux, banques de cache de second niveau et autres ressources du processeur distribuées, et prend en charge le taux de change de 200 GB / s. De plus, le commutateur contient un port pour les systèmes d'E / S et les canaux de la mémoire DRAM DDR2, fournissant le taux de change de 20 Go / s; La capacité de mémoire maximale est comprise jusqu'à 128 Go.

Le projet Niagara est axé sur le système d'exploitation Solaris. Toutes les applications exécutées Solaris peuvent donc être effectuées sur un nouveau processeur sans aucune modification. Le logiciel d'application perçoit Niagara comme 32 processeur discret.

Projet de cellule

Une approche propre à la création de processeurs multicœurs a été offerte IBM Corporation, dont le projet de cellule a été nommé «MultiProcesseur de puces hétérogènes). L'architecture cellulaire fait également référence à l'architecture de moteur à large bande cellulaire (CBEA). Le multiprocesseur de cellules est composé du noyau d'architecture d'alimentation IBM 64 bits et de huit coprocesseurs spécialisés qui mettent en œuvre la "commande une commande beaucoup de données". Dans IBM, cette architecture s'appelle une unité de processeur synergique (SPU). Il peut être utilisé avec succès si nécessaire pour traiter des flux de données volumineux, par exemple en cryptographie, dans différentes applications multimédia et scientifiques, telles que la transformation rapide de Fourier ou des opérations matricielles. L'architecture cellulaire a été créée par les chercheurs de recherche IBM conjointement avec des collègues du groupe IBM Systems Technology, Sony et Toshiba, et sa première application doit être des périphériques multimédia qui nécessitent de grandes quantités de calculs.

La base de l'unité de processeur synergique est un ensemble d'architecture de jeu d'instructions (ISA). Les commandes ont une longueur de 32 bits et sont adressées à trois opérandes placées dans le pool de registres, qui consiste en des registres de 128 bits dans chacun.

À l'avenir, l'utilisation de la cellule ne sera pas limitée systèmes de jeu. Sur la file d'attente - télévision haute définition, serveurs à domicile et même supercalculateurs.

Littérature
  1. Leonid Chernyak. L'audit de la primauté - la fin de la stagnation? // des systèmes ouverts. - 2003, №5.
  2. Mikhail Kuzminsky. Architecture de microprocesseur multiligne // Systèmes ouverts. - 2002, №1.
  3. Rajat A Dua, Bhushan Lokhande. Une étude comparative des multiprocesseurs SMT et CMP. -

Compte tenu de la théorie de la multithreading, considérez l'exemple pratique - Pentium 4. Déjà au stade du développement de ce processeur, Intel Ingénieurs a continué de travailler à améliorer ses performances sans apporter des modifications à l'interface du programme. Les cinq moyens simples ont été pris en compte:
1. Élever la fréquence d'horloge.
2. Placement sur une seule puce de deux processeurs.
3. Introduction de nouveaux blocs fonctionnels.
1. Extension du convoyeur.
2. Utilisation de multithreading.
Le moyen le plus évident d'améliorer la vitesse consiste à augmenter la fréquence d'horloge sans changer d'autres paramètres. En règle générale, chaque modèle de processeur subséquent a une fréquence d'horloge légèrement supérieure à celle du précédent. Malheureusement, avec une augmentation directe de la fréquence d'horloge, les développeurs sont confrontés à deux problèmes: une augmentation de la consommation d'énergie (qui est pertinente pour les ordinateurs portables et d'autres dispositifs informatiques exécutant des batteries) et la surchauffe (qui nécessite de créer des dissipateurs de chaleur plus efficaces).
La deuxième méthode est la mise en place sur la puce de deux processeurs - relativement simple, mais elle est associée au doublement de la zone occupée par le microcircuit. Si chaque processeur est fourni avec sa propre mémoire cache, le nombre de microcirces sur la plaque est d'arrêt, mais cela signifie également doubler le coût de la production. Si, pour les deux processeurs, il existe une mémoire de cache courante, une augmentation significative de la zone occupée peut être évitée, mais dans ce cas, un autre problème se produit - la quantité de mémoire cache en termes de chaque processeur est divisée par deux, ce qui est inévitablement affecté par la performance. . De plus, si les applications de serveur professionnel sont en mesure d'utiliser pleinement les ressources de plusieurs transformateurs, dans les programmes de bureau classiques, le parallélisme interne est développé dans une grande mesure.
L'introduction de nouveaux blocs fonctionnels n'est pas non plus difficile, mais il est important de garder l'équilibre. Quelle est la signification des dix principaux blocs d'ALU, si la puce ne peut pas émettre des commandes au convoyeur à une vitesse qui vous permet de télécharger tous ces blocs?
Le convoyeur avec un nombre accru d'étapes capables de séparer les tâches en segments plus petits et de les traiter en courtes périodes de temps, d'une part, d'une part, d'une part, d'une part, d'une autre, améliore les conséquences négatives de la prévision incorrecte des transitions, des cachures, des interruptions. et d'autres événements qui violent les commandes normales de traitement du cours dans le processeur. De plus, pour mettre en œuvre pleinement les possibilités d'un convoyeur élargi, il est nécessaire d'augmenter la fréquence de l'horloge, ce qui, comme nous le savons, conduit à une consommation d'énergie accrue et au transfert de chaleur.
Enfin, il est possible de mettre en œuvre la multithreading. L'avantage de cette technologie consiste à introduire un flux logiciel supplémentaire qui vous permet d'entrer en vigueur les ressources matérielles qui auraient autrement été simples. Selon les résultats des études expérimentales, les développeurs Intel ont découvert que l'augmentation de la zone de microcircuit de 5% sur la mise en œuvre de multithreading pour de nombreuses applications donne une augmentation de 25%. Xeon 2002 est devenu le premier processeur Intel avec un soutien à la multithreading. Par la suite, à partir de la fréquence de 3,06 GHz, la multithreading a été introduite dans le Pentium 4. Le dirigeant Intel appelle la mise en œuvre de multithreading dans l'hypermatochisme de Pentium 4 (hyperthreading).
Le principe principal de l'hyperpotimité est l'exécution simultanée de deux flux logiciels (ou processus - le processeur ne distingue pas les processus des flux logiciels). Le système d'exploitation considère le processeur d'hypervision Pentium 4 sous la forme d'un complexe à deux processeurs avec des caches courantes et une mémoire de base. Planification du système d'exploitation fonctionne pour chaque flux de logiciels séparément. Ainsi, deux applications peuvent être effectuées en même temps. Par exemple, le programme de messagerie peut envoyer ou recevoir des messages à mode de fondJusqu'à ce que l'utilisateur interagit avec l'application interactive - c'est-à-dire que le démon et le programme utilisateur sont effectués simultanément, comme si deux processeurs sont disponibles sur le système.
Les programmes d'application impliquant la possibilité d'exécution sous forme de plusieurs flux de logiciels peuvent utiliser des "processeurs virtuels". Par exemple, les programmes d'édition vidéo permettent généralement aux utilisateurs d'appliquer des filtres à tous les cadres. De tels filtres ajustent la luminosité, le contraste, la balance des couleurs et d'autres propriétés des cadres. Dans une telle situation, le programme peut affecter un processeur virtuel pour traiter même des cadres et l'autre pour traiter impair. Dans le même temps, deux processeurs travailleront totalement indépendamment les uns des autres.
Étant donné que les flux logiciels se tournent vers les mêmes ressources matérielles, cette coordination de thread est nécessaire. Dans le contexte de l'hypertension, les développeurs Intel ont identifié quatre stratégies utiles de gestion de la gestion des ressources: la duplication des ressources, ainsi que la séparation rigide, seuil et complète des ressources. Considérez ces stratégies.
Commençons par la duplication de ressources (duplication de ressources). Comme vous le savez, certaines ressources sont dupliquées dans le but d'organiser des flux de logiciels. Par exemple, étant donné que chaque flux de logiciel nécessite un contrôle individuel, vous avez besoin d'un deuxième compteur de commande. De plus, vous devez entrer la deuxième table d'affichage des registres architecturaux (EAH, UE, etc.) aux registres physiques; De même, le contrôleur d'interruption est dupliqué, car le traitement des interruptions pour chaque flux est effectué individuellement.
Ensuite, la méthode de partage des ressources partitionnées est suivie entre les flux logiciels. Par exemple, si le processeur fournit une file d'attente entre les deux étapes fonctionnelles du convoyeur, la moitié des fentes peut être donnée un flux 1, l'autre demi-flux 2. La séparation des ressources est facilement mise en œuvre, ne mène pas à la déséquilibre et fournit une indépendance complète des flux logiciels les uns des autres. Avec une division complète de toutes les ressources, un processeur se transforme en deux. D'autre part, il peut y avoir une telle situation à laquelle un thread de programme n'utilise pas les ressources qui pourraient être utiles au deuxième flux, mais à l'égard desquelles il n'a aucune autorité d'accès. En conséquence, les ressources qui peuvent être impliquées dans une situation différente sont inaccessibles.
L'opposé de la séparation rigide est une séparation complète des ressources (partage complet des ressources). Dans ce schéma, tout flux logiciel peut accéder aux ressources souhaitées et elles sont desservies pour des demandes d'accès. Considérez une situation dans laquelle un flux rapide constitué principalement d'opérations d'addition et de soustraction coexiste avec un écoulement lent qui implémente des opérations de multiplication et de division. Si les commandes sont appelées de mémoire plus rapidement que les opérations de multiplication et de division sont effectuées, le nombre de commandes causés dans le cadre du flux lent et de la mise en file d'attente sur le convoyeur se développera progressivement. En fin de compte, ces commandes rempliront la file d'attente, par conséquent, le flux rapide due au manque d'espace s'arrêtera. La séparation complète des ressources résout le problème des dépenses non optimales de ressources partagées, mais crée un déséquilibre de leur consommation - un thread peut ralentir ou arrêter l'autre.
Le schéma intermédiaire est mis en œuvre dans le seuil de ressource (partage des ressources de seuil). Selon ce système, tout flux logiciel peut recevoir de manière dynamique un volume de ressources (limité). En ce qui concerne les ressources répliquées, cette approche offre une flexibilité sans une menace pour l'un des flux logiciels en raison de l'impossibilité d'obtenir des ressources. Si, par exemple, d'interdire à chacun des flux d'occuper plus de 3/4 des files d'attente de commande, la consommation accrue de ressources avec un flux lent n'empêchera pas l'exécution du rapide.
Le modèle Hyperplow Pentium 4 combine différentes stratégies de séparation des ressources. Ainsi, une tentative est faite pour résoudre tous les problèmes liés à chaque stratégie. La duplication est mise en œuvre en ce qui concerne les ressources, l'accès auxquels est constamment requis par les deux flux logiciels (en particulier, en ce qui concerne le compteur de commande, les tables d'affichage et les contrôleurs d'interruption). La duplication de ces ressources augmente la zone de microcircuit de seulement 5% - vous êtes d'accord, des frais assez raisonnables pour la multithreading. Ressources disponibles dans un tel volume éliminé pratiquement par la probabilité de les capturer avec un flux (par exemple, des rangées de cache) sont distribuées de manière dynamique. L'accès aux ressources qui contrôlent le travail du convoyeur (en particulier, ses nombreuses files d'attentes) est divisée - la moitié des emplacements sont donnés à chaque programme. Le convoyeur principal de l'architecture Netburst mis en œuvre dans Pentium 4 est décrit à la Fig. 8.7; Blanc I. zones grises Cette illustration indique le mécanisme d'allocation de ressources entre les flux logiciels blancs et gris.
Comme vous pouvez le constater, toutes les files d'attente de cette illustration sont divisées - chaque flux logiciel est mis en surbrillance à la moitié des machines à sous. Aucun des flux logiciels ne peut limiter le fonctionnement d'un autre. L'unité de distribution et la substitution sont également séparées. Les ressources de planificateur sont divisées de manière dynamique, mais basée sur une certaine valeur de seuil - Aucun des threads ne peut prendre toutes les couches de la file d'attente. Pour toutes les autres étapes du convoyeur, il y a une séparation complète.
Cependant, avec multithreading, tout n'est pas si simple. Même une telle technique progressive a des lacunes. La séparation des ressources rigides n'est pas associée à des coûts graves, mais la séparation dynamique, en particulier en tenant compte des seuils, nécessite de suivre la consommation de ressources à la phase d'exécution. De plus, dans certains cas, les programmes fonctionnent de manière significative sans multithreading qu'avec. Supposons, par exemple, en présence de deux flux de logiciels pour le fonctionnement normal, chacune d'elles nécessite 3/4 cache. S'ils ont été réalisés alternativement, chacun montrerait une efficacité suffisante avec une petite quantité de cache misses (comme connue pour être liée à des coûts supplémentaires). En cas d'exécution parallèle de cache Misses, tout le monde serait beaucoup plus important et le résultat final serait pire que sans multithreading.
Pour plus d'informations sur le mécanisme de répétition multithreading 4, vous pouvez apprendre dans.

La cloche.

Il y a ceux qui ont lu cette nouvelle devant vous.
Abonnez-vous pour recevoir des articles frais.
E-mail
Nom
Nom de famille
Comment voulez-vous lire la cloche
Sans spam