SlideShare ist ein Scribd-Unternehmen logo
1 von 44
Downloaden Sie, um offline zu lesen
Donnez votre avis !
                   Depuis votre smartphone, sur :
                    http://notes.mstechdays.fr

    De nombreux lots à gagner toutes les heures !!!
               Claviers, souris et jeux Microsoft…

       Merci de nous aider à améliorer les TechDays

http://notes.mstechdays.fr
La programmation GPU
        avec C++ AMP pour les
        performances extrêmes
                               Bruno Boucard
                              Expert Parallèle
                                    FINAXYS


  LAN401               http://blogs.msdn.com/devpara/

Code / Développement
CONSEIL ET ARCHITECTURE IT-
         •

         •
             160 collaborateurs spécialisés en IT-Finance

             CA 2012 (prév.) de 16M€

         FINANCE
         •   Une large palette d’expertises :

                    •   Conseil SI & fonctionnel Finance,

                    •   AMOA SI et métiers Finance

                    •   Ingénierie logicielle (architecture, études, conception, développement, intégration continue)

                          •     Technologies Microsoft C++ et C#/.NET

                    •   Support et production applicative

         •   Un accompagnement global sur l’ensemble du cycle de vie projet, du cadrage à la recette, avec une démarche qualité
         intégrée

         •   Une contractualisation sur mesure : forfait, centre de service, assistance technique groupée ou assistance technique
         simple

         •   Nos références :




Ma société
Démo Cartoonizer !



De quoi allons-nous parler ?
Agenda
     • 1ière Partie : L’essentiel de C++ AMP
      – Contexte
      – Fondamentaux
     • 2ième Partie: Concepts plus avancés
      – Comprendre le calcul tuilé
      – Mise au point avec Visual Studio 2012
     • Conclusion

La programmation GPU avec C++ AMP
CPU vs GPU aujourd’hui


       •   Faible bande passante mémoire           •   Bande passante mémoire élevée
       •   Forte consommation d’énergie/FLOP       •   Faible consommation d'énergie/FLOP
       •   Niveau moyen de parallélisme            •   Haut niveau de parallélisme
       •   Pipelines d’exécution profonds          •   Pipelines d'exécution peu profonds
       •   Accès cache mémoire aléatoires          •   Accès cache mémoire séquentiels
       •   Supporte la programmation généraliste   •   Supporte la programmation parallèle orientée
       •   Programmation grand public                  données

                                                   •   Programmation réservée à des spécialistes
Contexte
CPU vs GPU aujourd’hui

                                                             image
     • CPUs et GPUs se rapprochent de plus en plus …      source: AMD

     • …mais rien n’est figé, le sujet est toujours en mouvement …

     • C++ AMP a été pensé comme une solution grand public pas
       seulement pour aujourd’hui, mais aussi pour demain




Contexte
Plateformes d’exécution de C++ AMP*
      •   Windows Azure                         •   Windows Phone
                                                •   Windows RT
      •   Windows Desktop
                                                •   Windows Embedded
      •   Windows Server
                                                •   Xbox
      •   Windows HPC Server




        ... tourne aussi sur des plateformes non Microsoft via une spécification
        ouverte
Contexte        * Certaines plateformes seront disponibles dans la prochaine version de C++ AMP
Qu’est que C++ AMP ?
    • Appartient à Visual C++
    • Intégrée à Visual Studio
    • Librairie STL-like pour gérer
      les données                     performance
      multidimensionnelles
    • Construite sur Direct3D 11      productivité
    • Spécification ouverte
                                      portabilité
Contexte
Transformer ce code séquentiel en code
          GPU                                           #include <amp.h>
                                                        using namespace concurrency;

  void AddArrays(int n, int * pA, int * pB, int * pC)   void AddArrays(int n, int * pA, int * pB, int * pC)
  {                                                     {
                                                          array_view<int,1> a(n, pA);
                                                          array_view<int,1> b(n, pB);
                                                          array_view<int,1> c(n, pC);

      for (int i=0; i<n; i++)                               parallel_for_each(
                                                            for (int i=0; i<n; i++)
                                                                c.extent,
                                                                [=](index<1> i) restrict(amp)
      {                                                         {
           pC[i] = pA[i] + pB[i];                                  c[i] = = pA[i] + pB[i];
                                                                   pC[i] a[i] + b[i];
      }                                                         }
                                                             );
  }                                                     }




Fondamentaux
Comprendre le code C++ AMP
    parallel_for_each:          void AddArrays(int n, int * pA, int * pB, int * pC)
                                                                           restrict(amp): dit au compilateur de
    exécute l’expression        {                                          forcer l’exécution de ce code sur le
    lambda sur                    array_view<int,1> a(n, pA);              GPU
    l’accélérateur une fois       array_view<int,1> b(n, pB);
    par thread
                                  array_view<int,1> c(n, pC);
                                                           array_view: wrapping des
                                  parallel_for_each(       données pour les traiter sur
                                                           l’accélérateur
    extent: le nombre de
                                           c.extent,
    threads et leur topologie              [=](index<1> i) restrict(amp)
    pour exécuter                          {
    l’expression lambda                         c[i] = a[i] + b[i];
                                           }
                                  );                                Les variables array_view sont
                                                                  capturées par valeur et leurs
    index: le thread ID qui exécute l’expression
                                 }                                données associées sont copiées
    lambda, est utilisé pour retrouver les données
                                                                  dans l’accélérateur à la demande

Fondamentaux
Comprendre le fonctionnement du
     parallel_for_each
     •   Exécute l’expression lambda pour chaque point de l’extent
     •   Semble synchrone, mais en réalité est asynchrone

                                                                                                                                                                                 parallel_for_each(
                                                                                                                                                                                      c.extent,
                                                                                                                                                                                      [=](index<1> idx) restrict(amp)
                              c[1] = a[1] + b[1]
         c[0] = a[0] + b[0]


                                                   c[2] = a[2] + b[2]
                                                                        c[3] = a[3] + b[3]
                                                                                             c[4] = a[4] + b[4]
                                                                                                                  c[5] = a[5] + b[5]
                                                                                                                                       c[6] = a[6] + b[6]
                                                                                                                                                            c[7] = a[7] + b[7]
                                                                                                                                                                                      {




                                                                                                                                                                                                                   Code noyau
                                                                                                                                                                                        c[idx] = a[idx] + b[idx];
                                                                                                                                                                                      }
                                                                                                                                                                                   );
                                                                                                                                                                                 }
          0                    1                     2                    3                    4                    5                    6                    7


Fondamentaux
Le mot clef restrict

    • S'applique aux fonctions (y compris les lambda)
    • resctrict(…) informe le compilateur d’appliquer des
      restrictions au langage
       – e.g. restrictions spécifiques, optimisations,
         génération de code
       – Dans cette 1ère version, supporte deux directives
          • cpu – est le défaut implicite
          • amp – vérifie la conformité de la fonction vis à vis
             de C++ AMP
Fondamentaux
Les restrictions du mot clef restrict
     • Pas de                                   • Pas de
       • récusions                               • goto ou labels
       • ‘volatile'                              • throw, try, catch
       • fonctions virtuelles                    • Variables globales ou statiques
       • pointeurs de fonctions                  • dynamic_cast ou typeid
       • pointeurs vers des fonctions membres    • déclarations __asm__
       • pointeurs dans des structures           • varargs
       • pointeurs de pointeurs                  • types non supportés
       • champs de bits                          •   e.g. char, short, long double
Fondamentaux
Surcharge via le mot clef restrict
       double cos( double d );                            // 1a code cpu
       double cos( double d ) restrict(amp);              // 1b code amp
       double bar( double d ) restrict(cpu,amp);          // 2 supporte les deux mode

       void some_method(array_view<double,2> c) {
         parallel_for_each( c.extent, [=](index<2> idx) restrict(amp)
         {
           //…
           double d0 = c[idx];
           double d1 = bar(d0); // ok, bar supporte amp aussi
           double d2 = cos(d0); // ok, sélection de la surcharge amp
           //…
         });
       }




Fondamentaux
Gestion des données multidimensionnelles
     •   index<N> - représente un point à N coordonnées
     •   extent<N> - taille de la données d’un espace à N dimensions
                                       index<2> i(0,2);           index<3> i(2,0,1);
          index<1> i(2);

                                   3                               2
               6                                                                 3
         extent<1> e(6);                    4                            2
                                extent<2> e(3,4);              extent<3> e(3,2,2);
     •   N peut être n’importe quel nombre <=128




Fondamentaux
Le conteneur: array_view<T, N>
      •       Vue sur les données stockées dans la mémoire CPU ou
              la mémoire GPU
      •       Capture par valeur [=] dans l’expression lambda
      •       De type T et de rang N
      •       Réclame un extent
                                                     vector<int> v(10);
      •       Rectangulaire                         extent<2> e(2,5); array_view<int,2> a(e, v);

      •       Accès aux éléments déclenchent
      •       des copies implicites
          index<2> i(3,9);                                  // Les 2 lignes peuvent aussi s’écrire
                                                            // array_view<int,2> a(2,5,v);
          int o = a[i]; // ou a[i] = 16;
          // ou int o = a(3, 9);


Fondamentaux
Le second conteneur: array<T, N>
        •   Tableau multidimensionnel qui contient des éléments de type T de dimension N

        •   Les données sont stockées dans la mémoire de l'accélérateur

        •   Capture par référence [&] dans l’expression lambda

        •   Copie explicit

        •   Presque identique à l’interface array_view<T,N>

    vector<int> v(8 * 12);                       parallel_for_each(e, [&](index<2> idx) restrict(amp)
    extent<2> e(8,12);                           {
                                                     a[idx] += 1;
    array<int,2> a(e);                           });
    copy_async(v.begin(), v.end(), a);           copy(a, v.begin());

Fondamentaux
Comprendre les accélérateurs                                   Host                Accélérateurs
     • accelerator
         – DX11 GPU
             • Support GPU
                                                                                PCIe
         – WARP (Windows Advanced Rasterisation
           Platform)
             • multi-core & vectorisazion (SSE)
             • Accessible via Direct3D
         – REF
             • Emulateur qui simule un pilote direct3d sur •   accelerator View
                 CPU                                            – Contexte pour
         – CPU                                                    ordonnancer les threads
                                                                  GPU et gérer les données
             • Support pour optimiser les transferts de
                                                                  en mémoire
                 données entre l'hôte et un
                 accelerator_view
Fondamentaux
Démo Accélérateurs!




Fondamentaux
Algorithme produit matriciel
  • Aij * Bjk = Cik
      – Chaque ligne A est multipliée par toutes les
        colonnes entières de B
      – Chaque multiplication est sommée dans une
        variable temporaire
      – Après avoir multiplié tous les éléments de la
        ligne avec tous les éléments de la colonne
        courante
      – Le résultat temporaire est placé dans la cellule
        correspondante de la « matrice produit » C

Fondamentaux
Produit matriciel du CPU au GPU
void MatrixMultiplySerial( vector<float>& vC,         void MatrixMultiplyAMP( vector<float>& vC,
  const vector<float>& vA,                              const vector<float>& vA,
  const vector<float>& vB, int M, int N, int W )        const vector<float>& vB, int M, int N, int W )
{                                                     {
                                                        array_view<const float,2> a(M,W,vA),b(W,N,vB);
                                                        array_view<float,2> c(M,N,vC);c.discard_data();
                                                        parallel_for_each(c.extent,
    for (int row = 0; row < M; row++) {                    [=](index<2> idx) restrict(amp) {
      for (int col = 0; col < N; col++){                       int row = idx[0]; int col = idx[1];
        float sum = 0.0f;                                         float sum = 0.0f;
        for(int i = 0; i < W; i++)                                for(int i = 0; i < W; i++)
          sum += vA[row * W + i] * vB[i * N + col];                 sum += a(row, i) * b(i, col);
        vC[row * N + col] = sum;                                  c[idx] = sum;
      }                                                    }
    }                                                   );
}                                                     }


Fondamentaux
Démo Produit Matriciel !



Fondamentaux
1ière Partie: ce que vous avez appris !
    Sur des volumes de données immenses, le calcul sur GPU offre des performances
     extraordinaires
    Microsoft souhaite démocratiser la programmation GPU avec C++ AMP sur toutes les
     plateformes

   Les éléments fondamentaux
         class index<N> : pointe une valeur dans un conteneur multidimensionnel
         class extent<N> : taille d’un conteneur multidimensionnel
         restrict(amp, cpu) : restreint la syntaxe C++ pour exécuter une méthode ou une
          lambda en mode noyau
         parallel_for_each : exécute une boucle en parallèle sur des données
          multidimensionnelle
         class array_view<T,N> : wrapper multidimensionnel sur des données
         class accelerator : accélérateur utilisé en interne pour exécuter le code parallèle
         class accelerator_view : isole l’accélérateur des différents usages multithreads
         class array<T,N> : conteneur multidimensionnel sur des données
Résumé de la première partie
Une vue du matériel GPU pour un développeur
                                                        Thread

                       …                           …
                     … ……                        … ……
                             Registres par Threads

                                                        N’est pas montré:
                                                        • Mémoire constante
                                                        • Mémoire des
                               Mémoire Globale             contrôleurs
                                                        • Schedulers
                                                        • Autres caches
                                                        • Cas Multi-GPU


Comprendre le calcul tuilé
Une vue du matériel GPU pour un développeur

                     …                                 …           Tuile composée de
                                                                   threads


                   … ……                              … ……
           Registres par Threads           Registres par Threads

                                                                       N’est pas montré:
                                                                       • Mémoire constante
                                                                       • Mémoire des
                                   Mémoire Globale                        contrôleurs
                                                                       • Schedulers
                                                                       • Autres caches
                                                                       • Cas Multi-GPU


Comprendre le calcul tuilé
Une vue du matériel GPU pour un développeur

                     …                                 …           Tuile composée de
                                                                   threads


                   … ……                              … ……          Les variable tile_static
                                                                   sont partagée par les
                                                                   threads dans la même
                                                                   tuile
           Registres par Threads            Registres par Thread
          Cache Programmable               Cache Programmable          N’est pas montré:
                                                                       • Mémoire constante
                                                                       • Mémoire des contrôleurs
                                                                       • Schedulers
                                   Mémoire Globale                     • Autres caches
                                                                       • Cas Multi-GPU




Comprendre le calcul tuilé
parallel_for_each: surcharge pour les tuiles
        • Orchestrer des threads           array_view<int,1> data(12, my_data);
          dans des tuiles
           – La version de base ne
               le permet pas               parallel_for_each(data.extent,
        • parallel_for_each version          [=] (index<1> idx) restrict(amp)
          tuile accepte ces                  { … });
          surcharges
              – tiled_extent<D0> ou
                tiled_extent<D0, D1> ou    parallel_for_each(data.extent.tile<6>(),
                tiled_extent<D0, D1, D2>
        • L’expression lambda                [=] (tiled_index<6> t_idx) restrict(amp)
          accepte                            { … });
              – tiled_index<D0> ou
                tiled_index<D0, D1> ou
                tiled_index<D0, D1, D2>

Comprendre le calcul tuilé
tiled_extent (depuis un extent)
                    extent<1> e(12);
                     0     1     2        3   4      5         6    7     8      9    10     11

                          tiled_extent<6> t_e = e.tile<6>();
                           0     1        2   3      4         5    6     7      8     9     10     11




                    extent<2> ee(2, 6);                            tiled_extent<2, 2> t_ee = ee.tile<2, 2>();
                    0,0   0,1   0,2    0,3    0,4   0,5                  0,0    0,1   0,2   0,3    0,4    0,5

                    1,0   1,1   1,2    1,3    1,4   1,5                  1,0    1,1   1,2   1,3    1,4    1,5




Techniques plus avancées: calcul tuilé
tiled_index
      • Soit                                           col 0   col 1       col 2   col 3   col 4   col 5

        array_view<int,2> data(2, 6, p_my_data); row
        parallel_for_each(                        0
          data.extent.tile<2,2>(),
          [=] (tiled_index<2,2> t_idx)… { … });
                                                 row
                                                  1
                                                                                    T

      • Lorsque la lambda est exécutée par                             T

            –   t_idx.global        // index<2> (1,3)
            –   t_idx.local         // index<2> (1,1)
            –   t_idx.tile          // index<2> (0,1)
            –   t_idx.tile_origin   // index<2> (0,2)

Comprendre le calcul tuilé
tile_static
        • Le mot clef tile_static dédié au stockage mémoire
        • Second mot clef ajouté au langage C++
        • Représente la mémoire locale du GPU

        • Usage du mot clé tile_static
           – Dans une boucle parallel_for_each tuilée
           – Le mot clef tile_static devant une déclaration de
             variable locale place cette variable dans la mémoire
             locale GPU pour la tuile courante
           – Cette mémoire est partagée par tous les threads
             associés à la tuile
           – Applicable seulement pour les fonctions restrict(amp)


Comprendre le calcul tuilé
tile_barrier
      • classe tile_barrier
            – Synchronise tous les threads au sein d’une tuile jusqu'à
              ce que tous les accès à la mémoire soient terminés
                 • t_idx.barrier.wait();
                 • ~ t_idx.barrier.wait_with_all_memory_fence();

            – Synchronise tous les threads au sein d’une tuile jusqu'à
              ce que tous les accès à la mémoire globale soient
              terminés
                 • t_idx.barrier.wait_with_global_memory_fence();

            – Synchronise tous les threads au sein d’une tuile jusqu'à
              ce que tous les accès à la mémoire la mémoire tile_static
              (locale) soient terminés
                 • t_idx.barrier.wait_with_tile_static_memory_fence();


Comprendre le calcul tuilé
Cacher avec tile_static                0,0 0,1 0,2 0,3 0,4 0,5
                                              1,0 1,1 1,2 1,3 1,4 1,5
   1    static const int TS = 2;
   2    array_view<int, 2> av(2, 6, my_vector);
   3    parallel_for_each(av.extent.tile<TS,TS>(),
        [=](tiled_index<TS,TS> t_idx) restrict(amp)
   4    {
   5        tile_static int t[TS][TS];
   6        t[t_idx.local[0]][t_idx.local[1]] = av[t_idx.global];
   7
   8      if (t_idx.local == index<2>(0,0)) {
   9         int temp = t[0][0] + t[0][1] + t[1][0] + t[1][1];
   10        av[t_idx.tile_origin] = temp;
   11     }
   12 });
   13 int sum = av(0,0) + av(0,2) + av(0,4); //the three tile_origins


Comprendre le calcul tuilé
tile_static en action                  0,0 0,1 0,2 0,3 0,4 0,5
                                              1,0 1,1 1,2 1,3 1,4 1,5
   1    static const int TS = 2;
   2    array_view<int, 2> av(2, 6, my_vector);
   3    parallel_for_each(av.extent.tile<TS,TS>(),
        [=](tiled_index<TS,TS> t_idx) restrict(amp)
   4    {
   5        tile_static int t[TS][TS];
   6        t[t_idx.local[0]][t_idx.local[1]] = av[t_idx.global];
   7
   8      if (t_idx.local == index<2>(0,0)) {
   9         int temp = t[0][0] + t[0][1] + t[1][0] + t[1][1];
   10        av[t_idx.tile_origin] = temp;
   11     }
   12 });
   13 int sum = av(0,0) + av(0,2) + av(0,4); //the three tile_origins


Comprendre le calcul tuilé
Synchro avec tile_barrier0,0               0,1 0,2 0,3 0,4 0,5
                                              1,0 1,1 1,2 1,3 1,4 1,5
   1    static const int TS = 2;
   2    array_view<int, 2> av(2, 6, my_vector);
   3    parallel_for_each(av.extent.tile<TS,TS>(),
        [=](tiled_index<TS,TS> t_idx) restrict(amp)
   4    {
   5        tile_static int t[TS][TS];
   6        t[t_idx.local[0]][t_idx.local[1]] = av[t_idx.global];
   7        tile_barrier.wait();
   8        if (t_idx.local == index<2>(0,0)) {
   9           int temp = t[0][0] + t[0][1] + t[1][0] + t[1][1];
   10          av[t_idx.tile_origin] = temp;
   11       }
   12   });
   13   int sum = av(0,0) + av(0,2) + av(0,4); //the three tile_origins


Comprendre le calcul tuilé
Retour sur la Multiplication Matricielle
       • Chargement des données pour 4 threads




       • Les threads chargent plusieurs fois la même
         valeur depuis la mémoire globale !
             – Comment éviter ce problème ?

Comprendre le calcul tuilé
Multiplication Matricielle – Exemple (tuilée)
 void MatrixMultSimple(vector<float>& vC, const vector<float>& vA, const   void MatrixMultTiled(vector<float>& vC, const vector<float>& vA, const
                                                                           void
 vector<float>& vB, int M, int N, int W )                                  vector<float>& vB, int M, int N,           W)
                                                                           const vector<float>& vB, int M, int N, int W )
 {                                                                         {
                                                                             static const int TS = 16;
                                                                                     const int TS = 16;
     array_view<const float,2> a(M, W, vA), b(W, N, vB);                     array_view<const float,2> a(M, W, vA), b(W, N, vB);
     array_view<float,2> c(M,N,vC); c.discard_data();                        array_view<float,2> c(M,N,vC); c.discard_data();
     parallel_for_each(c.extent,                                             parallel_for_each(c.extent.tile< TS, TS >(),
                                                                                                                     TS, TS >(),
       [=] (index<2> idx) restrict(amp) {                                       [=] (tiled_index<TS, TS> t_idx) restrict(amp) { {
                                                                                    (tiled_index< TS, TS> t_idx) restrict(amp)
         int row = idx[0]; int col = idx[1];                                      int row = t_idx.local[0]; int col = t_idx.local[1];
                                                                                                                          t_idx.local[1];
         float sum = 0.0f;                                                        float sum = 0.0f;
                                                                                  for (int i = 0; ii < W; ii += TS) {{
                                                                                               0; < W; += TS)
                                                                                      tile_static float locA[TS][TS], locB[TS][TS];
                                                                                      tile_static float locA[TS][TS], locB[TS][TS];




                                                                                                                                         Phase 1
                                                                                      locA[row][col] = a(t_idx.global[0], col i);
                                                                                      locA[row][col]= a(t_idx.global[0], col ++ i);
                                                                                      locB[row][col] = b(row + i, t_idx.global[1]);
                                                                                      locB[row][col] = b(row + i, t_idx.global[1]);
                                                                                      t_idx.barrier.wait();
                                                                                      t_idx.barrier.wait();

         for(int k = 0; k < W; k++)                                                for (int k = 0; k < TS; k++)




                                                                                                                                         Phase 2
           sum += a(row, k) * b(k, col);                                             sum += locA[row][k] * locB[k][col];
                                                                                   t_idx.barrier.wait();
                                                                                   t_idx.barrier.wait();
                                                                                    }
          c[idx] = sum;                                                           c[t_idx.global] = sum;
                                                                                  c[t_idx.global] = sum;
       } );                                                                    } );
 }                                                                         }

Techniques plus avancées: calcul tuilé
Démo Produit Matriciel Tuilé !




Comprendre le calcul tuilé
C++ AMP Parallel Debugger
      • Fonctionnalités bien connues du débogage Visual studio
            – Launch, Attach, Break, Stepping, Breakpoints, DataTips
            – Outillage orienté fenêtre
               • Processes, Debug Output, Modules, Disassembly, Call Stack,
                  Memory, Registers, Locals, Watch, Quick Watch
      • Nouvelles fonctionnalités (à la fois le CPU et le GPU)
            – Parallel Stacks window, Parallel Watch window, Barrier
      • Nouveautés spécifiques GPU
            – Emulateur, fenêtre GPU Threads , détection de races conditions

Visual Studio
Debugger GPU en Action




Visual Studio
2ième Partie: ce que vous avez appris !
  Comprendre le calcul tuilé
        La macro architecture GPU pour les développeurs
        La classe tile_static pour cacher des données pour un groupe de threads
        Le classe tiled_extent< , , > permet à la surcharge parallel_foreach de simplifier le
         calcul en tuilé
        La classe tiled_index< , , > permet à la surcharge parallel_foreach de simplifier le
         calcul en tuilé
        La classe tile_barrier permet de synchroniser les threads au sein d’une tuile
  Mise au point avec Visual Studio
        Configurer le mode Debug GPU
        Détecter les races conditions
        Utiliser la fenêtre Parallel GPU pour observer l’état de tous les threads et naviguer
         entre eux
        Utiliser la fenêtre Parallel Watch pour observer des données pour chacun des threads
        Exécuter toute une tuile de threads jusqu’à votre curseur
Résumé de la seconde partie
Conclusion
     • Démocratisation de la programmation parallèle hétérogène
        – Haute performance accessible au grand public
        – Abstraction de la plateforme matérielle
        – Abstractions de haut niveau en C++ (pas en langage C)
        – Repose sur un jeu minimal d’API
        – C++ AMP est une spécification libre
        – Etat de l’art de l’IDE de Visual Studio


C++ AMP en quelques mots
Pour aller plus loin …
      MSDN Forums to ask questions
      •    http://social.msdn.microsoft.com/Forums/en/parallelcppnative/threads

      MSDN Native parallelism blog (team blog)
      •    http://blogs.msdn.com/nativeconcurrency/
                                                                                          Libraries for C++ AMP
      C++ AMP Samples                                                                     •    http://blogs.msdn.com/b/nativeconcurrency/archive/2012/05/19/libraries-for-
      •    http://blogs.msdn.com/b/nativeconcurrency/archive/2012/01/30/c-amp-sample-          c-amp.aspx
           projects-for-download.aspx

      Graphics in C++ AMP                                                                 C++ AMP for the OpenCLProgrammer
      •    http://blogs.msdn.com/b/nativeconcurrency/archive/2012/01/25/concurrency-
                                                                                          •    http://blogs.msdn.com/b/nativeconcurrency/archive/2012/04/10/c-amp-for-
           graphics-in-c-amp.aspx                                                              the-opencl-programmer.aspx

      Interoperability between Direct 3D and C++ AMP                                      C++ AMP for the CUDA Programmer
      •    http://blogs.msdn.com/b/nativeconcurrency/archive/2011/12/29/interoperabilit   •    http://blogs.msdn.com/b/nativeconcurrency/archive/2012/04/11/c-amp-for-
           y-between-direct-3d-and-c-amp.aspx                                                  the-cuda-programmer.aspx

      C++ AMP open spec                                                                   C++ AMP for the DirectCompute Programmer
      •    http://blogs.msdn.com/b/nativeconcurrency/archive/2012/02/03/c-amp-open-       •    http://blogs.msdn.com/b/nativeconcurrency/archive/2012/04/09/c-amp-for-
           spec-published.aspx                                                                 the-directcompute-programmer.aspx




Pour creuser un peu plus …
Développeurs                                                         Pros de l’IT
 http://aka.ms/generation-app       Formez-vous en ligne        www.microsoftvirtualacademy.com

    http://aka.ms/evenements-
                 developpeurs     Retrouvez nos évènements      http://aka.ms/itcamps-france


            Les accélérateurs
                                  Faites-vous accompagner
Windows Azure, Windows Phone,
                                  gratuitement
                   Windows 8


                                   Essayer gratuitement nos     http://aka.ms/telechargements
                                                 solutions IT

         La Dev’Team sur MSDN       Retrouver nos experts       L’IT Team sur TechNet
          http://aka.ms/devteam           Microsoft             http://aka.ms/itteam

Weitere ähnliche Inhalte

Andere mochten auch

Introduction to CUDA
Introduction to CUDAIntroduction to CUDA
Introduction to CUDARaymond Tay
 
Programmation sur GPU avec CUDA
Programmation sur GPU avec CUDAProgrammation sur GPU avec CUDA
Programmation sur GPU avec CUDAIn Fine
 
Mémoire Parallélisation d'algorithmes de graphes avec MapReduce sur un cluste...
Mémoire Parallélisation d'algorithmes de graphes avec MapReduce sur un cluste...Mémoire Parallélisation d'algorithmes de graphes avec MapReduce sur un cluste...
Mémoire Parallélisation d'algorithmes de graphes avec MapReduce sur un cluste...Hadjer BENHADJ DJILALI
 
Graphics card as computation engine
Graphics card as computation engineGraphics card as computation engine
Graphics card as computation enginevalery brasseur
 

Andere mochten auch (7)

GPU: Understanding CUDA
GPU: Understanding CUDAGPU: Understanding CUDA
GPU: Understanding CUDA
 
Introduction to CUDA
Introduction to CUDAIntroduction to CUDA
Introduction to CUDA
 
Gpao 6 - Ordonnancement
Gpao 6 - OrdonnancementGpao 6 - Ordonnancement
Gpao 6 - Ordonnancement
 
Calculs sur GPU
Calculs sur GPUCalculs sur GPU
Calculs sur GPU
 
Programmation sur GPU avec CUDA
Programmation sur GPU avec CUDAProgrammation sur GPU avec CUDA
Programmation sur GPU avec CUDA
 
Mémoire Parallélisation d'algorithmes de graphes avec MapReduce sur un cluste...
Mémoire Parallélisation d'algorithmes de graphes avec MapReduce sur un cluste...Mémoire Parallélisation d'algorithmes de graphes avec MapReduce sur un cluste...
Mémoire Parallélisation d'algorithmes de graphes avec MapReduce sur un cluste...
 
Graphics card as computation engine
Graphics card as computation engineGraphics card as computation engine
Graphics card as computation engine
 

Ähnlich wie La programmation GPU avec C++ AMP pour les performances extrêmes

Développer en natif avec C++11
Développer en natif avec C++11Développer en natif avec C++11
Développer en natif avec C++11Microsoft
 
Monitoring applicatif : Pourquoi et comment ?
Monitoring applicatif : Pourquoi et comment ?Monitoring applicatif : Pourquoi et comment ?
Monitoring applicatif : Pourquoi et comment ?Kenny Dits
 
OWF12/PAUG Conf Days Render script, sylvain galand, software engineer at geny...
OWF12/PAUG Conf Days Render script, sylvain galand, software engineer at geny...OWF12/PAUG Conf Days Render script, sylvain galand, software engineer at geny...
OWF12/PAUG Conf Days Render script, sylvain galand, software engineer at geny...Paris Open Source Summit
 
Monitoring d'applications/environnements PHP: APM et Pinba
Monitoring d'applications/environnements PHP: APM et PinbaMonitoring d'applications/environnements PHP: APM et Pinba
Monitoring d'applications/environnements PHP: APM et PinbaPatrick Allaert
 
Partie1 TypeScript
Partie1 TypeScriptPartie1 TypeScript
Partie1 TypeScriptHabib Ayad
 
Spark-adabra, Comment Construire un DATALAKE ! (Devoxx 2017)
Spark-adabra, Comment Construire un DATALAKE ! (Devoxx 2017) Spark-adabra, Comment Construire un DATALAKE ! (Devoxx 2017)
Spark-adabra, Comment Construire un DATALAKE ! (Devoxx 2017) univalence
 
Les nouveautés de C++11 : Ecrire du C++ Moderne
Les nouveautés de C++11 : Ecrire du C++ ModerneLes nouveautés de C++11 : Ecrire du C++ Moderne
Les nouveautés de C++11 : Ecrire du C++ ModerneMicrosoft
 
Chap1V2019: Cours en C++
Chap1V2019: Cours en C++Chap1V2019: Cours en C++
Chap1V2019: Cours en C++Aziz Darouichi
 
Introduction à MacRuby - OSDC.fr 2009
Introduction à MacRuby - OSDC.fr 2009Introduction à MacRuby - OSDC.fr 2009
Introduction à MacRuby - OSDC.fr 2009guest60b8020b
 
Réutilisation de code entre windows 8 et windows phone 8
Réutilisation de code entre windows 8 et windows phone 8Réutilisation de code entre windows 8 et windows phone 8
Réutilisation de code entre windows 8 et windows phone 8Arnaud Auroux
 
Performance et optimisation de PrestaShop
Performance et optimisation de PrestaShopPerformance et optimisation de PrestaShop
Performance et optimisation de PrestaShopPrestaShop
 
Dans les entrailles du langage C
Dans les entrailles du langage CDans les entrailles du langage C
Dans les entrailles du langage CStephanie Ouillon
 
Présentation Javascript à l'ESI (Alger)
Présentation Javascript à l'ESI (Alger)Présentation Javascript à l'ESI (Alger)
Présentation Javascript à l'ESI (Alger)Dr Samir A. ROUABHI
 
C++ 11 - Tech Days 2014 in Paris
C++ 11 - Tech Days 2014 in ParisC++ 11 - Tech Days 2014 in Paris
C++ 11 - Tech Days 2014 in Parischristophep21
 
Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
Bonnes pratiques pour apprivoiser le C++11 avec Visual C++Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
Bonnes pratiques pour apprivoiser le C++11 avec Visual C++Microsoft
 

Ähnlich wie La programmation GPU avec C++ AMP pour les performances extrêmes (20)

Développer en natif avec C++11
Développer en natif avec C++11Développer en natif avec C++11
Développer en natif avec C++11
 
Monitoring applicatif : Pourquoi et comment ?
Monitoring applicatif : Pourquoi et comment ?Monitoring applicatif : Pourquoi et comment ?
Monitoring applicatif : Pourquoi et comment ?
 
_JCVFr
_JCVFr_JCVFr
_JCVFr
 
OWF12/PAUG Conf Days Render script, sylvain galand, software engineer at geny...
OWF12/PAUG Conf Days Render script, sylvain galand, software engineer at geny...OWF12/PAUG Conf Days Render script, sylvain galand, software engineer at geny...
OWF12/PAUG Conf Days Render script, sylvain galand, software engineer at geny...
 
Monitoring d'applications/environnements PHP: APM et Pinba
Monitoring d'applications/environnements PHP: APM et PinbaMonitoring d'applications/environnements PHP: APM et Pinba
Monitoring d'applications/environnements PHP: APM et Pinba
 
Partie1 TypeScript
Partie1 TypeScriptPartie1 TypeScript
Partie1 TypeScript
 
Spark-adabra, Comment Construire un DATALAKE ! (Devoxx 2017)
Spark-adabra, Comment Construire un DATALAKE ! (Devoxx 2017) Spark-adabra, Comment Construire un DATALAKE ! (Devoxx 2017)
Spark-adabra, Comment Construire un DATALAKE ! (Devoxx 2017)
 
_JCVFr
_JCVFr_JCVFr
_JCVFr
 
Les nouveautés de C++11 : Ecrire du C++ Moderne
Les nouveautés de C++11 : Ecrire du C++ ModerneLes nouveautés de C++11 : Ecrire du C++ Moderne
Les nouveautés de C++11 : Ecrire du C++ Moderne
 
Chap1V2019: Cours en C++
Chap1V2019: Cours en C++Chap1V2019: Cours en C++
Chap1V2019: Cours en C++
 
Introduction à MacRuby - OSDC.fr 2009
Introduction à MacRuby - OSDC.fr 2009Introduction à MacRuby - OSDC.fr 2009
Introduction à MacRuby - OSDC.fr 2009
 
introduction au CPP
introduction au CPPintroduction au CPP
introduction au CPP
 
Réutilisation de code entre windows 8 et windows phone 8
Réutilisation de code entre windows 8 et windows phone 8Réutilisation de code entre windows 8 et windows phone 8
Réutilisation de code entre windows 8 et windows phone 8
 
REX Ansible
REX AnsibleREX Ansible
REX Ansible
 
Performance et optimisation de PrestaShop
Performance et optimisation de PrestaShopPerformance et optimisation de PrestaShop
Performance et optimisation de PrestaShop
 
Dans les entrailles du langage C
Dans les entrailles du langage CDans les entrailles du langage C
Dans les entrailles du langage C
 
Présentation Javascript à l'ESI (Alger)
Présentation Javascript à l'ESI (Alger)Présentation Javascript à l'ESI (Alger)
Présentation Javascript à l'ESI (Alger)
 
Introduction à MacRuby
Introduction à MacRubyIntroduction à MacRuby
Introduction à MacRuby
 
C++ 11 - Tech Days 2014 in Paris
C++ 11 - Tech Days 2014 in ParisC++ 11 - Tech Days 2014 in Paris
C++ 11 - Tech Days 2014 in Paris
 
Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
Bonnes pratiques pour apprivoiser le C++11 avec Visual C++Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
 

Mehr von Microsoft

Uwp + Xamarin : Du nouveau en terre du milieu
Uwp + Xamarin : Du nouveau en terre du milieuUwp + Xamarin : Du nouveau en terre du milieu
Uwp + Xamarin : Du nouveau en terre du milieuMicrosoft
 
La Blockchain pas à PaaS
La Blockchain pas à PaaSLa Blockchain pas à PaaS
La Blockchain pas à PaaSMicrosoft
 
Tester, Monitorer et Déployer son application mobile
Tester, Monitorer et Déployer son application mobileTester, Monitorer et Déployer son application mobile
Tester, Monitorer et Déployer son application mobileMicrosoft
 
Windows 10, un an après – Nouveautés & Démo
Windows 10, un an après – Nouveautés & Démo Windows 10, un an après – Nouveautés & Démo
Windows 10, un an après – Nouveautés & Démo Microsoft
 
Prenez votre pied avec les bots et cognitive services.
Prenez votre pied avec les bots et cognitive services.Prenez votre pied avec les bots et cognitive services.
Prenez votre pied avec les bots et cognitive services.Microsoft
 
Office 365 Dev PnP & PowerShell : exploitez enfin le potentiel de votre écosy...
Office 365 Dev PnP & PowerShell : exploitez enfin le potentiel de votre écosy...Office 365 Dev PnP & PowerShell : exploitez enfin le potentiel de votre écosy...
Office 365 Dev PnP & PowerShell : exploitez enfin le potentiel de votre écosy...Microsoft
 
Créer un bot de A à Z
Créer un bot de A à ZCréer un bot de A à Z
Créer un bot de A à ZMicrosoft
 
Microsoft Composition, pierre angulaire de vos applications ?
Microsoft Composition, pierre angulaire de vos applications ?Microsoft Composition, pierre angulaire de vos applications ?
Microsoft Composition, pierre angulaire de vos applications ?Microsoft
 
Les nouveautés SQL Server 2016
Les nouveautés SQL Server 2016Les nouveautés SQL Server 2016
Les nouveautés SQL Server 2016Microsoft
 
Conteneurs Linux ou Windows : quelles approches pour des IT agiles ?
Conteneurs Linux ou Windows : quelles approches pour des IT agiles ?Conteneurs Linux ou Windows : quelles approches pour des IT agiles ?
Conteneurs Linux ou Windows : quelles approches pour des IT agiles ?Microsoft
 
Administration et supervision depuis le Cloud avec Azure Logs Analytics
Administration et supervision depuis le Cloud avec Azure Logs AnalyticsAdministration et supervision depuis le Cloud avec Azure Logs Analytics
Administration et supervision depuis le Cloud avec Azure Logs AnalyticsMicrosoft
 
Retour d'expérience de projets Azure IoT "large scale" (MicroServices, portag...
Retour d'expérience de projets Azure IoT "large scale" (MicroServices, portag...Retour d'expérience de projets Azure IoT "large scale" (MicroServices, portag...
Retour d'expérience de projets Azure IoT "large scale" (MicroServices, portag...Microsoft
 
Plan de Reprise d'Activité avec Azure Site Recovery
Plan de Reprise d'Activité avec Azure Site RecoveryPlan de Reprise d'Activité avec Azure Site Recovery
Plan de Reprise d'Activité avec Azure Site RecoveryMicrosoft
 
Modélisation, déploiement et gestion des infrastructures Cloud : outils et bo...
Modélisation, déploiement et gestion des infrastructures Cloud : outils et bo...Modélisation, déploiement et gestion des infrastructures Cloud : outils et bo...
Modélisation, déploiement et gestion des infrastructures Cloud : outils et bo...Microsoft
 
Transformation de la représentation : De la VR à la RA, aller & retour.
Transformation de la représentation : De la VR à la RA, aller & retour.Transformation de la représentation : De la VR à la RA, aller & retour.
Transformation de la représentation : De la VR à la RA, aller & retour.Microsoft
 
Quelles architectures pour vos applications Cloud, de la VM au conteneur : ça...
Quelles architectures pour vos applications Cloud, de la VM au conteneur : ça...Quelles architectures pour vos applications Cloud, de la VM au conteneur : ça...
Quelles architectures pour vos applications Cloud, de la VM au conteneur : ça...Microsoft
 
Introduction à ASP.NET Core
Introduction à ASP.NET CoreIntroduction à ASP.NET Core
Introduction à ASP.NET CoreMicrosoft
 
Open Source et Microsoft Azure, rêve ou réalité ?
Open Source et Microsoft Azure, rêve ou réalité ?Open Source et Microsoft Azure, rêve ou réalité ?
Open Source et Microsoft Azure, rêve ou réalité ?Microsoft
 
Comment développer sur la console Xbox One avec une application Universal Win...
Comment développer sur la console Xbox One avec une application Universal Win...Comment développer sur la console Xbox One avec une application Universal Win...
Comment développer sur la console Xbox One avec une application Universal Win...Microsoft
 
Azure Service Fabric pour les développeurs
Azure Service Fabric pour les développeursAzure Service Fabric pour les développeurs
Azure Service Fabric pour les développeursMicrosoft
 

Mehr von Microsoft (20)

Uwp + Xamarin : Du nouveau en terre du milieu
Uwp + Xamarin : Du nouveau en terre du milieuUwp + Xamarin : Du nouveau en terre du milieu
Uwp + Xamarin : Du nouveau en terre du milieu
 
La Blockchain pas à PaaS
La Blockchain pas à PaaSLa Blockchain pas à PaaS
La Blockchain pas à PaaS
 
Tester, Monitorer et Déployer son application mobile
Tester, Monitorer et Déployer son application mobileTester, Monitorer et Déployer son application mobile
Tester, Monitorer et Déployer son application mobile
 
Windows 10, un an après – Nouveautés & Démo
Windows 10, un an après – Nouveautés & Démo Windows 10, un an après – Nouveautés & Démo
Windows 10, un an après – Nouveautés & Démo
 
Prenez votre pied avec les bots et cognitive services.
Prenez votre pied avec les bots et cognitive services.Prenez votre pied avec les bots et cognitive services.
Prenez votre pied avec les bots et cognitive services.
 
Office 365 Dev PnP & PowerShell : exploitez enfin le potentiel de votre écosy...
Office 365 Dev PnP & PowerShell : exploitez enfin le potentiel de votre écosy...Office 365 Dev PnP & PowerShell : exploitez enfin le potentiel de votre écosy...
Office 365 Dev PnP & PowerShell : exploitez enfin le potentiel de votre écosy...
 
Créer un bot de A à Z
Créer un bot de A à ZCréer un bot de A à Z
Créer un bot de A à Z
 
Microsoft Composition, pierre angulaire de vos applications ?
Microsoft Composition, pierre angulaire de vos applications ?Microsoft Composition, pierre angulaire de vos applications ?
Microsoft Composition, pierre angulaire de vos applications ?
 
Les nouveautés SQL Server 2016
Les nouveautés SQL Server 2016Les nouveautés SQL Server 2016
Les nouveautés SQL Server 2016
 
Conteneurs Linux ou Windows : quelles approches pour des IT agiles ?
Conteneurs Linux ou Windows : quelles approches pour des IT agiles ?Conteneurs Linux ou Windows : quelles approches pour des IT agiles ?
Conteneurs Linux ou Windows : quelles approches pour des IT agiles ?
 
Administration et supervision depuis le Cloud avec Azure Logs Analytics
Administration et supervision depuis le Cloud avec Azure Logs AnalyticsAdministration et supervision depuis le Cloud avec Azure Logs Analytics
Administration et supervision depuis le Cloud avec Azure Logs Analytics
 
Retour d'expérience de projets Azure IoT "large scale" (MicroServices, portag...
Retour d'expérience de projets Azure IoT "large scale" (MicroServices, portag...Retour d'expérience de projets Azure IoT "large scale" (MicroServices, portag...
Retour d'expérience de projets Azure IoT "large scale" (MicroServices, portag...
 
Plan de Reprise d'Activité avec Azure Site Recovery
Plan de Reprise d'Activité avec Azure Site RecoveryPlan de Reprise d'Activité avec Azure Site Recovery
Plan de Reprise d'Activité avec Azure Site Recovery
 
Modélisation, déploiement et gestion des infrastructures Cloud : outils et bo...
Modélisation, déploiement et gestion des infrastructures Cloud : outils et bo...Modélisation, déploiement et gestion des infrastructures Cloud : outils et bo...
Modélisation, déploiement et gestion des infrastructures Cloud : outils et bo...
 
Transformation de la représentation : De la VR à la RA, aller & retour.
Transformation de la représentation : De la VR à la RA, aller & retour.Transformation de la représentation : De la VR à la RA, aller & retour.
Transformation de la représentation : De la VR à la RA, aller & retour.
 
Quelles architectures pour vos applications Cloud, de la VM au conteneur : ça...
Quelles architectures pour vos applications Cloud, de la VM au conteneur : ça...Quelles architectures pour vos applications Cloud, de la VM au conteneur : ça...
Quelles architectures pour vos applications Cloud, de la VM au conteneur : ça...
 
Introduction à ASP.NET Core
Introduction à ASP.NET CoreIntroduction à ASP.NET Core
Introduction à ASP.NET Core
 
Open Source et Microsoft Azure, rêve ou réalité ?
Open Source et Microsoft Azure, rêve ou réalité ?Open Source et Microsoft Azure, rêve ou réalité ?
Open Source et Microsoft Azure, rêve ou réalité ?
 
Comment développer sur la console Xbox One avec une application Universal Win...
Comment développer sur la console Xbox One avec une application Universal Win...Comment développer sur la console Xbox One avec une application Universal Win...
Comment développer sur la console Xbox One avec une application Universal Win...
 
Azure Service Fabric pour les développeurs
Azure Service Fabric pour les développeursAzure Service Fabric pour les développeurs
Azure Service Fabric pour les développeurs
 

La programmation GPU avec C++ AMP pour les performances extrêmes

  • 1. Donnez votre avis ! Depuis votre smartphone, sur : http://notes.mstechdays.fr De nombreux lots à gagner toutes les heures !!! Claviers, souris et jeux Microsoft… Merci de nous aider à améliorer les TechDays http://notes.mstechdays.fr
  • 2. La programmation GPU avec C++ AMP pour les performances extrêmes Bruno Boucard Expert Parallèle FINAXYS LAN401 http://blogs.msdn.com/devpara/ Code / Développement
  • 3. CONSEIL ET ARCHITECTURE IT- • • 160 collaborateurs spécialisés en IT-Finance CA 2012 (prév.) de 16M€ FINANCE • Une large palette d’expertises : • Conseil SI & fonctionnel Finance, • AMOA SI et métiers Finance • Ingénierie logicielle (architecture, études, conception, développement, intégration continue) • Technologies Microsoft C++ et C#/.NET • Support et production applicative • Un accompagnement global sur l’ensemble du cycle de vie projet, du cadrage à la recette, avec une démarche qualité intégrée • Une contractualisation sur mesure : forfait, centre de service, assistance technique groupée ou assistance technique simple • Nos références : Ma société
  • 4. Démo Cartoonizer ! De quoi allons-nous parler ?
  • 5. Agenda • 1ière Partie : L’essentiel de C++ AMP – Contexte – Fondamentaux • 2ième Partie: Concepts plus avancés – Comprendre le calcul tuilé – Mise au point avec Visual Studio 2012 • Conclusion La programmation GPU avec C++ AMP
  • 6. CPU vs GPU aujourd’hui • Faible bande passante mémoire • Bande passante mémoire élevée • Forte consommation d’énergie/FLOP • Faible consommation d'énergie/FLOP • Niveau moyen de parallélisme • Haut niveau de parallélisme • Pipelines d’exécution profonds • Pipelines d'exécution peu profonds • Accès cache mémoire aléatoires • Accès cache mémoire séquentiels • Supporte la programmation généraliste • Supporte la programmation parallèle orientée • Programmation grand public données • Programmation réservée à des spécialistes Contexte
  • 7. CPU vs GPU aujourd’hui image • CPUs et GPUs se rapprochent de plus en plus … source: AMD • …mais rien n’est figé, le sujet est toujours en mouvement … • C++ AMP a été pensé comme une solution grand public pas seulement pour aujourd’hui, mais aussi pour demain Contexte
  • 8. Plateformes d’exécution de C++ AMP* • Windows Azure • Windows Phone • Windows RT • Windows Desktop • Windows Embedded • Windows Server • Xbox • Windows HPC Server ... tourne aussi sur des plateformes non Microsoft via une spécification ouverte Contexte * Certaines plateformes seront disponibles dans la prochaine version de C++ AMP
  • 9. Qu’est que C++ AMP ? • Appartient à Visual C++ • Intégrée à Visual Studio • Librairie STL-like pour gérer les données performance multidimensionnelles • Construite sur Direct3D 11 productivité • Spécification ouverte portabilité Contexte
  • 10. Transformer ce code séquentiel en code GPU #include <amp.h> using namespace concurrency; void AddArrays(int n, int * pA, int * pB, int * pC) void AddArrays(int n, int * pA, int * pB, int * pC) { { array_view<int,1> a(n, pA); array_view<int,1> b(n, pB); array_view<int,1> c(n, pC); for (int i=0; i<n; i++) parallel_for_each( for (int i=0; i<n; i++) c.extent, [=](index<1> i) restrict(amp) { { pC[i] = pA[i] + pB[i]; c[i] = = pA[i] + pB[i]; pC[i] a[i] + b[i]; } } ); } } Fondamentaux
  • 11. Comprendre le code C++ AMP parallel_for_each: void AddArrays(int n, int * pA, int * pB, int * pC) restrict(amp): dit au compilateur de exécute l’expression { forcer l’exécution de ce code sur le lambda sur array_view<int,1> a(n, pA); GPU l’accélérateur une fois array_view<int,1> b(n, pB); par thread array_view<int,1> c(n, pC); array_view: wrapping des parallel_for_each( données pour les traiter sur l’accélérateur extent: le nombre de c.extent, threads et leur topologie [=](index<1> i) restrict(amp) pour exécuter { l’expression lambda c[i] = a[i] + b[i]; } ); Les variables array_view sont capturées par valeur et leurs index: le thread ID qui exécute l’expression } données associées sont copiées lambda, est utilisé pour retrouver les données dans l’accélérateur à la demande Fondamentaux
  • 12. Comprendre le fonctionnement du parallel_for_each • Exécute l’expression lambda pour chaque point de l’extent • Semble synchrone, mais en réalité est asynchrone parallel_for_each( c.extent, [=](index<1> idx) restrict(amp) c[1] = a[1] + b[1] c[0] = a[0] + b[0] c[2] = a[2] + b[2] c[3] = a[3] + b[3] c[4] = a[4] + b[4] c[5] = a[5] + b[5] c[6] = a[6] + b[6] c[7] = a[7] + b[7] { Code noyau c[idx] = a[idx] + b[idx]; } ); } 0 1 2 3 4 5 6 7 Fondamentaux
  • 13. Le mot clef restrict • S'applique aux fonctions (y compris les lambda) • resctrict(…) informe le compilateur d’appliquer des restrictions au langage – e.g. restrictions spécifiques, optimisations, génération de code – Dans cette 1ère version, supporte deux directives • cpu – est le défaut implicite • amp – vérifie la conformité de la fonction vis à vis de C++ AMP Fondamentaux
  • 14. Les restrictions du mot clef restrict • Pas de • Pas de • récusions • goto ou labels • ‘volatile' • throw, try, catch • fonctions virtuelles • Variables globales ou statiques • pointeurs de fonctions • dynamic_cast ou typeid • pointeurs vers des fonctions membres • déclarations __asm__ • pointeurs dans des structures • varargs • pointeurs de pointeurs • types non supportés • champs de bits • e.g. char, short, long double Fondamentaux
  • 15. Surcharge via le mot clef restrict double cos( double d ); // 1a code cpu double cos( double d ) restrict(amp); // 1b code amp double bar( double d ) restrict(cpu,amp); // 2 supporte les deux mode void some_method(array_view<double,2> c) { parallel_for_each( c.extent, [=](index<2> idx) restrict(amp) { //… double d0 = c[idx]; double d1 = bar(d0); // ok, bar supporte amp aussi double d2 = cos(d0); // ok, sélection de la surcharge amp //… }); } Fondamentaux
  • 16. Gestion des données multidimensionnelles • index<N> - représente un point à N coordonnées • extent<N> - taille de la données d’un espace à N dimensions index<2> i(0,2); index<3> i(2,0,1); index<1> i(2); 3 2 6 3 extent<1> e(6); 4 2 extent<2> e(3,4); extent<3> e(3,2,2); • N peut être n’importe quel nombre <=128 Fondamentaux
  • 17. Le conteneur: array_view<T, N> • Vue sur les données stockées dans la mémoire CPU ou la mémoire GPU • Capture par valeur [=] dans l’expression lambda • De type T et de rang N • Réclame un extent vector<int> v(10); • Rectangulaire extent<2> e(2,5); array_view<int,2> a(e, v); • Accès aux éléments déclenchent • des copies implicites index<2> i(3,9); // Les 2 lignes peuvent aussi s’écrire // array_view<int,2> a(2,5,v); int o = a[i]; // ou a[i] = 16; // ou int o = a(3, 9); Fondamentaux
  • 18. Le second conteneur: array<T, N> • Tableau multidimensionnel qui contient des éléments de type T de dimension N • Les données sont stockées dans la mémoire de l'accélérateur • Capture par référence [&] dans l’expression lambda • Copie explicit • Presque identique à l’interface array_view<T,N> vector<int> v(8 * 12); parallel_for_each(e, [&](index<2> idx) restrict(amp) extent<2> e(8,12); { a[idx] += 1; array<int,2> a(e); }); copy_async(v.begin(), v.end(), a); copy(a, v.begin()); Fondamentaux
  • 19. Comprendre les accélérateurs Host Accélérateurs • accelerator – DX11 GPU • Support GPU PCIe – WARP (Windows Advanced Rasterisation Platform) • multi-core & vectorisazion (SSE) • Accessible via Direct3D – REF • Emulateur qui simule un pilote direct3d sur • accelerator View CPU – Contexte pour – CPU ordonnancer les threads GPU et gérer les données • Support pour optimiser les transferts de en mémoire données entre l'hôte et un accelerator_view Fondamentaux
  • 21. Algorithme produit matriciel • Aij * Bjk = Cik – Chaque ligne A est multipliée par toutes les colonnes entières de B – Chaque multiplication est sommée dans une variable temporaire – Après avoir multiplié tous les éléments de la ligne avec tous les éléments de la colonne courante – Le résultat temporaire est placé dans la cellule correspondante de la « matrice produit » C Fondamentaux
  • 22. Produit matriciel du CPU au GPU void MatrixMultiplySerial( vector<float>& vC, void MatrixMultiplyAMP( vector<float>& vC, const vector<float>& vA, const vector<float>& vA, const vector<float>& vB, int M, int N, int W ) const vector<float>& vB, int M, int N, int W ) { { array_view<const float,2> a(M,W,vA),b(W,N,vB); array_view<float,2> c(M,N,vC);c.discard_data(); parallel_for_each(c.extent, for (int row = 0; row < M; row++) { [=](index<2> idx) restrict(amp) { for (int col = 0; col < N; col++){ int row = idx[0]; int col = idx[1]; float sum = 0.0f; float sum = 0.0f; for(int i = 0; i < W; i++) for(int i = 0; i < W; i++) sum += vA[row * W + i] * vB[i * N + col]; sum += a(row, i) * b(i, col); vC[row * N + col] = sum; c[idx] = sum; } } } ); } } Fondamentaux
  • 23. Démo Produit Matriciel ! Fondamentaux
  • 24. 1ière Partie: ce que vous avez appris !  Sur des volumes de données immenses, le calcul sur GPU offre des performances extraordinaires  Microsoft souhaite démocratiser la programmation GPU avec C++ AMP sur toutes les plateformes Les éléments fondamentaux  class index<N> : pointe une valeur dans un conteneur multidimensionnel  class extent<N> : taille d’un conteneur multidimensionnel  restrict(amp, cpu) : restreint la syntaxe C++ pour exécuter une méthode ou une lambda en mode noyau  parallel_for_each : exécute une boucle en parallèle sur des données multidimensionnelle  class array_view<T,N> : wrapper multidimensionnel sur des données  class accelerator : accélérateur utilisé en interne pour exécuter le code parallèle  class accelerator_view : isole l’accélérateur des différents usages multithreads  class array<T,N> : conteneur multidimensionnel sur des données Résumé de la première partie
  • 25. Une vue du matériel GPU pour un développeur Thread … … … …… … …… Registres par Threads N’est pas montré: • Mémoire constante • Mémoire des Mémoire Globale contrôleurs • Schedulers • Autres caches • Cas Multi-GPU Comprendre le calcul tuilé
  • 26. Une vue du matériel GPU pour un développeur … … Tuile composée de threads … …… … …… Registres par Threads Registres par Threads N’est pas montré: • Mémoire constante • Mémoire des Mémoire Globale contrôleurs • Schedulers • Autres caches • Cas Multi-GPU Comprendre le calcul tuilé
  • 27. Une vue du matériel GPU pour un développeur … … Tuile composée de threads … …… … …… Les variable tile_static sont partagée par les threads dans la même tuile Registres par Threads Registres par Thread Cache Programmable Cache Programmable N’est pas montré: • Mémoire constante • Mémoire des contrôleurs • Schedulers Mémoire Globale • Autres caches • Cas Multi-GPU Comprendre le calcul tuilé
  • 28. parallel_for_each: surcharge pour les tuiles • Orchestrer des threads array_view<int,1> data(12, my_data); dans des tuiles – La version de base ne le permet pas parallel_for_each(data.extent, • parallel_for_each version [=] (index<1> idx) restrict(amp) tuile accepte ces { … }); surcharges – tiled_extent<D0> ou tiled_extent<D0, D1> ou parallel_for_each(data.extent.tile<6>(), tiled_extent<D0, D1, D2> • L’expression lambda [=] (tiled_index<6> t_idx) restrict(amp) accepte { … }); – tiled_index<D0> ou tiled_index<D0, D1> ou tiled_index<D0, D1, D2> Comprendre le calcul tuilé
  • 29. tiled_extent (depuis un extent) extent<1> e(12); 0 1 2 3 4 5 6 7 8 9 10 11 tiled_extent<6> t_e = e.tile<6>(); 0 1 2 3 4 5 6 7 8 9 10 11 extent<2> ee(2, 6); tiled_extent<2, 2> t_ee = ee.tile<2, 2>(); 0,0 0,1 0,2 0,3 0,4 0,5 0,0 0,1 0,2 0,3 0,4 0,5 1,0 1,1 1,2 1,3 1,4 1,5 1,0 1,1 1,2 1,3 1,4 1,5 Techniques plus avancées: calcul tuilé
  • 30. tiled_index • Soit col 0 col 1 col 2 col 3 col 4 col 5 array_view<int,2> data(2, 6, p_my_data); row parallel_for_each( 0 data.extent.tile<2,2>(), [=] (tiled_index<2,2> t_idx)… { … }); row 1 T • Lorsque la lambda est exécutée par T – t_idx.global // index<2> (1,3) – t_idx.local // index<2> (1,1) – t_idx.tile // index<2> (0,1) – t_idx.tile_origin // index<2> (0,2) Comprendre le calcul tuilé
  • 31. tile_static • Le mot clef tile_static dédié au stockage mémoire • Second mot clef ajouté au langage C++ • Représente la mémoire locale du GPU • Usage du mot clé tile_static – Dans une boucle parallel_for_each tuilée – Le mot clef tile_static devant une déclaration de variable locale place cette variable dans la mémoire locale GPU pour la tuile courante – Cette mémoire est partagée par tous les threads associés à la tuile – Applicable seulement pour les fonctions restrict(amp) Comprendre le calcul tuilé
  • 32. tile_barrier • classe tile_barrier – Synchronise tous les threads au sein d’une tuile jusqu'à ce que tous les accès à la mémoire soient terminés • t_idx.barrier.wait(); • ~ t_idx.barrier.wait_with_all_memory_fence(); – Synchronise tous les threads au sein d’une tuile jusqu'à ce que tous les accès à la mémoire globale soient terminés • t_idx.barrier.wait_with_global_memory_fence(); – Synchronise tous les threads au sein d’une tuile jusqu'à ce que tous les accès à la mémoire la mémoire tile_static (locale) soient terminés • t_idx.barrier.wait_with_tile_static_memory_fence(); Comprendre le calcul tuilé
  • 33. Cacher avec tile_static 0,0 0,1 0,2 0,3 0,4 0,5 1,0 1,1 1,2 1,3 1,4 1,5 1 static const int TS = 2; 2 array_view<int, 2> av(2, 6, my_vector); 3 parallel_for_each(av.extent.tile<TS,TS>(), [=](tiled_index<TS,TS> t_idx) restrict(amp) 4 { 5 tile_static int t[TS][TS]; 6 t[t_idx.local[0]][t_idx.local[1]] = av[t_idx.global]; 7 8 if (t_idx.local == index<2>(0,0)) { 9 int temp = t[0][0] + t[0][1] + t[1][0] + t[1][1]; 10 av[t_idx.tile_origin] = temp; 11 } 12 }); 13 int sum = av(0,0) + av(0,2) + av(0,4); //the three tile_origins Comprendre le calcul tuilé
  • 34. tile_static en action 0,0 0,1 0,2 0,3 0,4 0,5 1,0 1,1 1,2 1,3 1,4 1,5 1 static const int TS = 2; 2 array_view<int, 2> av(2, 6, my_vector); 3 parallel_for_each(av.extent.tile<TS,TS>(), [=](tiled_index<TS,TS> t_idx) restrict(amp) 4 { 5 tile_static int t[TS][TS]; 6 t[t_idx.local[0]][t_idx.local[1]] = av[t_idx.global]; 7 8 if (t_idx.local == index<2>(0,0)) { 9 int temp = t[0][0] + t[0][1] + t[1][0] + t[1][1]; 10 av[t_idx.tile_origin] = temp; 11 } 12 }); 13 int sum = av(0,0) + av(0,2) + av(0,4); //the three tile_origins Comprendre le calcul tuilé
  • 35. Synchro avec tile_barrier0,0 0,1 0,2 0,3 0,4 0,5 1,0 1,1 1,2 1,3 1,4 1,5 1 static const int TS = 2; 2 array_view<int, 2> av(2, 6, my_vector); 3 parallel_for_each(av.extent.tile<TS,TS>(), [=](tiled_index<TS,TS> t_idx) restrict(amp) 4 { 5 tile_static int t[TS][TS]; 6 t[t_idx.local[0]][t_idx.local[1]] = av[t_idx.global]; 7 tile_barrier.wait(); 8 if (t_idx.local == index<2>(0,0)) { 9 int temp = t[0][0] + t[0][1] + t[1][0] + t[1][1]; 10 av[t_idx.tile_origin] = temp; 11 } 12 }); 13 int sum = av(0,0) + av(0,2) + av(0,4); //the three tile_origins Comprendre le calcul tuilé
  • 36. Retour sur la Multiplication Matricielle • Chargement des données pour 4 threads • Les threads chargent plusieurs fois la même valeur depuis la mémoire globale ! – Comment éviter ce problème ? Comprendre le calcul tuilé
  • 37. Multiplication Matricielle – Exemple (tuilée) void MatrixMultSimple(vector<float>& vC, const vector<float>& vA, const void MatrixMultTiled(vector<float>& vC, const vector<float>& vA, const void vector<float>& vB, int M, int N, int W ) vector<float>& vB, int M, int N, W) const vector<float>& vB, int M, int N, int W ) { { static const int TS = 16; const int TS = 16; array_view<const float,2> a(M, W, vA), b(W, N, vB); array_view<const float,2> a(M, W, vA), b(W, N, vB); array_view<float,2> c(M,N,vC); c.discard_data(); array_view<float,2> c(M,N,vC); c.discard_data(); parallel_for_each(c.extent, parallel_for_each(c.extent.tile< TS, TS >(), TS, TS >(), [=] (index<2> idx) restrict(amp) { [=] (tiled_index<TS, TS> t_idx) restrict(amp) { { (tiled_index< TS, TS> t_idx) restrict(amp) int row = idx[0]; int col = idx[1]; int row = t_idx.local[0]; int col = t_idx.local[1]; t_idx.local[1]; float sum = 0.0f; float sum = 0.0f; for (int i = 0; ii < W; ii += TS) {{ 0; < W; += TS) tile_static float locA[TS][TS], locB[TS][TS]; tile_static float locA[TS][TS], locB[TS][TS]; Phase 1 locA[row][col] = a(t_idx.global[0], col i); locA[row][col]= a(t_idx.global[0], col ++ i); locB[row][col] = b(row + i, t_idx.global[1]); locB[row][col] = b(row + i, t_idx.global[1]); t_idx.barrier.wait(); t_idx.barrier.wait(); for(int k = 0; k < W; k++) for (int k = 0; k < TS; k++) Phase 2 sum += a(row, k) * b(k, col); sum += locA[row][k] * locB[k][col]; t_idx.barrier.wait(); t_idx.barrier.wait(); } c[idx] = sum; c[t_idx.global] = sum; c[t_idx.global] = sum; } ); } ); } } Techniques plus avancées: calcul tuilé
  • 38. Démo Produit Matriciel Tuilé ! Comprendre le calcul tuilé
  • 39. C++ AMP Parallel Debugger • Fonctionnalités bien connues du débogage Visual studio – Launch, Attach, Break, Stepping, Breakpoints, DataTips – Outillage orienté fenêtre • Processes, Debug Output, Modules, Disassembly, Call Stack, Memory, Registers, Locals, Watch, Quick Watch • Nouvelles fonctionnalités (à la fois le CPU et le GPU) – Parallel Stacks window, Parallel Watch window, Barrier • Nouveautés spécifiques GPU – Emulateur, fenêtre GPU Threads , détection de races conditions Visual Studio
  • 40. Debugger GPU en Action Visual Studio
  • 41. 2ième Partie: ce que vous avez appris ! Comprendre le calcul tuilé  La macro architecture GPU pour les développeurs  La classe tile_static pour cacher des données pour un groupe de threads  Le classe tiled_extent< , , > permet à la surcharge parallel_foreach de simplifier le calcul en tuilé  La classe tiled_index< , , > permet à la surcharge parallel_foreach de simplifier le calcul en tuilé  La classe tile_barrier permet de synchroniser les threads au sein d’une tuile Mise au point avec Visual Studio  Configurer le mode Debug GPU  Détecter les races conditions  Utiliser la fenêtre Parallel GPU pour observer l’état de tous les threads et naviguer entre eux  Utiliser la fenêtre Parallel Watch pour observer des données pour chacun des threads  Exécuter toute une tuile de threads jusqu’à votre curseur Résumé de la seconde partie
  • 42. Conclusion • Démocratisation de la programmation parallèle hétérogène – Haute performance accessible au grand public – Abstraction de la plateforme matérielle – Abstractions de haut niveau en C++ (pas en langage C) – Repose sur un jeu minimal d’API – C++ AMP est une spécification libre – Etat de l’art de l’IDE de Visual Studio C++ AMP en quelques mots
  • 43. Pour aller plus loin … MSDN Forums to ask questions • http://social.msdn.microsoft.com/Forums/en/parallelcppnative/threads MSDN Native parallelism blog (team blog) • http://blogs.msdn.com/nativeconcurrency/ Libraries for C++ AMP C++ AMP Samples • http://blogs.msdn.com/b/nativeconcurrency/archive/2012/05/19/libraries-for- • http://blogs.msdn.com/b/nativeconcurrency/archive/2012/01/30/c-amp-sample- c-amp.aspx projects-for-download.aspx Graphics in C++ AMP C++ AMP for the OpenCLProgrammer • http://blogs.msdn.com/b/nativeconcurrency/archive/2012/01/25/concurrency- • http://blogs.msdn.com/b/nativeconcurrency/archive/2012/04/10/c-amp-for- graphics-in-c-amp.aspx the-opencl-programmer.aspx Interoperability between Direct 3D and C++ AMP C++ AMP for the CUDA Programmer • http://blogs.msdn.com/b/nativeconcurrency/archive/2011/12/29/interoperabilit • http://blogs.msdn.com/b/nativeconcurrency/archive/2012/04/11/c-amp-for- y-between-direct-3d-and-c-amp.aspx the-cuda-programmer.aspx C++ AMP open spec C++ AMP for the DirectCompute Programmer • http://blogs.msdn.com/b/nativeconcurrency/archive/2012/02/03/c-amp-open- • http://blogs.msdn.com/b/nativeconcurrency/archive/2012/04/09/c-amp-for- spec-published.aspx the-directcompute-programmer.aspx Pour creuser un peu plus …
  • 44. Développeurs Pros de l’IT http://aka.ms/generation-app Formez-vous en ligne www.microsoftvirtualacademy.com http://aka.ms/evenements- developpeurs Retrouvez nos évènements http://aka.ms/itcamps-france Les accélérateurs Faites-vous accompagner Windows Azure, Windows Phone, gratuitement Windows 8 Essayer gratuitement nos http://aka.ms/telechargements solutions IT La Dev’Team sur MSDN Retrouver nos experts L’IT Team sur TechNet http://aka.ms/devteam Microsoft http://aka.ms/itteam

Hinweis der Redaktion

  1. Notation
  2. Intro code / dev
  3. Utilisation de Visual C++ component extensions (C++/CX ) afin de produire un application Windows Store sur le base de l’application full C++.