Partager via


Vue d'ensemble du runtime d'accès concurrentiel

Ce document fournit une vue d'ensemble du runtime d'accès concurrentiel. Il décrit les avantages du runtime d'accès concurrentiel, quand l'utiliser et la façon dont ses composants interagissent entre eux et avec le système d'exploitation et les applications.

Sections

Ce document contient les sections suivantes :

  • Pourquoi un runtime est-il important pour l'accès concurrentiel ?

  • Architecture

  • Expressions lambda C++

  • Spécifications

Pourquoi un runtime est-il important pour l'accès concurrentiel ?

Un runtime d'accès concurrentiel procure une uniformité et une prévisibilité aux applications et aux composants d'applications qui s'exécutent simultanément. La planification de tâche coopérative et le blocage coopératif constituent deux exemples des avantages offerts par un runtime d'accès concurrentiel.

Le runtime d'accès concurrentiel utilise un planificateur de tâche coopératif qui implémente un algorithme de vol de travail pour répartir efficacement le travail parmi les ressources de calcul. Par exemple, considérez une application qui a deux threads gérés par le même runtime. Si un thread termine sa tâche planifiée, il peut décharger le travail de l'autre thread. Ce mécanisme équilibre la charge de travail totale de l'application.

Le runtime d'accès concurrentiel fournit également des primitives de synchronisation qui utilisent le blocage coopératif pour synchroniser l'accès aux ressources. Par exemple, considérez une tâche qui doit avoir un accès exclusif à une ressource partagée. En effectuant un blocage coopératif, le runtime peut utiliser le quantum restant pour effectuer une autre tâche pendant que la première tâche attend la ressource. Ce mécanisme favorise l'utilisation maximale des ressources de calcul.

[retour en haut]

Architecture

Le runtime d'accès concurrentiel est divisé en quatre composants : la Bibliothèque de modèles parallèles (PPL, Parallel Patterns Library), la Bibliothèque d'agents asynchrones, le Planificateur de tâches et le Gestionnaire des ressources. Ces composants résident entre le système d'exploitation et les applications. L'illustration suivante indique comment les composants du runtime d'accès concurrentiel interagissent parmi le système d'exploitation et les applications :

Architecture de runtime d'accès concurrentiel

Architecture de runtime d'accès concurrentiel

Le runtime d'accès concurrentiel est hautement composable, autrement dit, vous pouvez combiner les fonctionnalités existantes pour en retirer davantage. Le runtime d'accès concurrentiel compose de nombreuses fonctionnalités, telles que les algorithmes parallèles, à partir de composants de niveau inférieur.

Le runtime d'accès concurrentiel fournit également des primitives de synchronisation qui utilisent le blocage coopératif pour synchroniser l'accès aux ressources. Pour plus d'informations sur ces primitives de synchronisation, consultez Structures de données de synchronisation.

Les sections suivantes fournissent une vue d'ensemble de ce que fournit chaque composant et expliquent quand utiliser ces composants.

Bibliothèque de modèles parallèles

La Bibliothèque de modèles parallèles (PPL, Parallel Patterns Library) fournit des conteneurs et des algorithmes à usage général pour effectuer un parallélisme affiné. La bibliothèque PPL permet de disposer d'un parallélisme des données impératif en procurant des algorithmes parallèles qui répartissent les calculs sur des collections ou des groupes de données parmi les ressources de calcul. Elle permet également de bénéficier d'un parallélisme des tâches en fournissant des objets de tâches qui répartissent plusieurs opérations indépendantes parmi les ressources de calcul.

Utilisez la Bibliothèque de modèles parallèles lorsque vous avez un calcul local qui peut tirer parti de l'exécution parallèle. Par exemple, vous pouvez utiliser l'algorithme Concurrency::parallel_for pour transformer une boucle for existante de sorte qu'elle opère en parallèle.

Pour plus d'informations sur la Bibliothèque de modèles parallèles, consultez Bibliothèque de modèles parallèles.

Bibliothèque d'agents asynchrones

La Bibliothèque d'agents asynchrones (ou simplement Bibliothèque d'agents) fournit à la fois un modèle de programmation basé sur acteur et des interfaces de passage de message pour des tâches de traitement « pipeline » et de flux de données de granularité grossière. Les agents asynchrones vous permettent d'utiliser la latence de manière productive en effectuant du travail pendant que d'autres composants attendent des données.

Utilisez la Bibliothèque d'agents lorsque vous avez plusieurs entités qui communiquent les unes avec les autres de façon asynchrone. Par exemple, vous pouvez créer un agent qui lit des données à partir d'un fichier ou d'une connexion réseau et qui utilise ensuite les interfaces de passage de message pour envoyer ces données à un autre agent.

Pour plus d'informations sur la Bibliothèque d'agents, consultez Bibliothèque d'agents asynchrones.

Planificateur de tâches

Le Planificateur de tâches planifie et coordonne les tâches au moment de l'exécution. Le Planificateur de tâches est coopératif et utilise un algorithme de vol de travail pour accomplir une utilisation maximale des ressources de traitement.

Le runtime d'accès concurrentiel fournit un planificateur par défaut afin que vous n'ayez pas à gérer les détails de l'infrastructure. Toutefois, vous pouvez également fournir votre propre stratégie de planification ou associer des planificateurs spécifiques à des tâches spécifiques afin de répondre aux besoins de votre application en matière de qualité.

Pour plus d'informations sur le Planificateur de tâches, consultez Planificateur de tâches (runtime d'accès concurrentiel).

Gestionnaire des ressources

Le rôle du Gestionnaire des ressources consiste à gérer les ressources de calcul, telles que les processeurs et la mémoire. Le Gestionnaire des ressources répond aux charges de travail à mesure qu'elles évoluent au moment de l'exécution en assignant les ressources là où elles peuvent être le plus efficaces.

Le Gestionnaire des ressources sert d'abstraction sur les ressources de calcul et interagit principalement avec le Planificateur de tâches. Bien qu'il soit possible d'utiliser le Gestionnaire des ressources pour affiner les performances des bibliothèques et applications, on utilise en général les fonctionnalités fournies par la Bibliothèque de modèles parallèles, la Bibliothèque d'agents et le Planificateur de tâches. Ces bibliothèques utilisent le Gestionnaire des ressources afin d'équilibrer de manière dynamique les ressources à mesure que les charges de travail évoluent.

[retour en haut]

Expressions lambda C++

Une grande partie des types et algorithmes définis par le runtime d'accès concurrentiel sont implémentés en tant que modèles C++. Certains de ces types et algorithmes prennent comme paramètre une routine qui effectue un travail. Ce paramètre peut être une fonction lambda, un objet de fonction ou un pointeur fonction. Ces entités sont également appelées fonctions de travail ou routines de travail.

Les expressions lambda constituent une nouvelle fonctionnalité de langage Visual C++, car elles offrent un moyen succinct pour définir des fonctions de travail pour le traitement en parallèle. Les objets de fonction et les pointeurs fonction vous permettent d'utiliser le runtime d'accès concurrentiel avec votre code existant. Toutefois, nous vous conseillons d'utiliser des expressions lambda lorsque vous écrivez du nouveau code. Vous bénéficiez ainsi des avantages qu'elles procurent en termes de sécurité et de productivité.

L'exemple suivant compare la syntaxe des fonctions lambda, des objets de fonction et des pointeurs fonction dans plusieurs appels à l'algorithme Concurrency::parallel_for_each. Chaque appel à parallel_for_each utilise une technique différente pour calculer le carré de chaque élément dans un objet std::array.

// comparing-work-functions.cpp
// compile with: /EHsc
#include <ppl.h>
#include <array>
#include <iostream>

using namespace Concurrency;
using namespace std;

// Function object (functor) class that computes the square of its input.
template<class Ty>
class SquareFunctor
{
public:
   void operator()(Ty& n) const
   {
      n *= n;
   }
};

// Function that computes the square of its input.
template<class Ty>
void square_function(Ty& n)
{
   n *= n;
}

int wmain()
{
   // Create an array object that contains 5 values.
   array<int, 5> values = { 1, 2, 3, 4, 5 };

   // Use a lambda function, a function object, and a function pointer to 
   // compute the square of each element of the array in parallel.

   // Use a lambda function to square each element.
   parallel_for_each(values.begin(), values.end(), [](int& n){n *= n;});

   // Use a function object (functor) to square each element.
   parallel_for_each(values.begin(), values.end(), SquareFunctor<int>());

   // Use a function pointer to square each element.
   parallel_for_each(values.begin(), values.end(), &square_function<int>);

   // Print each element of the array to the console.
   for_each(values.begin(), values.end(), [](int& n) { 
      wcout << n << endl;
   });
}

Cet exemple génère la sortie suivante :

1
256
6561
65536
390625

Pour plus d'informations sur les fonctions lambda en C++, consultez Lambda Expressions in C++.

[retour en haut]

Spécifications

Le tableau suivant répertorie les fichiers d'en-tête associés à chaque composant du runtime d'accès concurrentiel :

Composant

Fichiers d'en-tête

Bibliothèque de modèles parallèles

ppl.h

concurrent_queue.h

concurrent_vector.h

Bibliothèque d'agents asynchrones

agents.h

Planificateur de tâches

concrt.h

Gestionnaire des ressources

concrtrm.h

Le runtime d'accès concurrentiel est déclaré dans l'espace de noms Concurrency. L'espace de noms Concurrency::details prend en charge l'infrastructure du runtime d'accès concurrentiel et n'est pas destiné à être utilisé directement à partir de votre code.

Le runtime d'accès concurrentiel est fourni dans le cadre de la Bibliothèque runtime C (CRT). Pour plus d'informations sur la façon de générer une application qui utilise le CRT, consultez C Run-Time Libraries.

[retour en haut]

Historique des modifications

Date

Historique

Motif

Juillet 2010

Réorganisation du contenu.

Améliorations apportées aux informations.