Donnez votre avis !                   Depuis votre smartphone, sur :                    http://notes.mstechdays.fr    De n...
La programmation GPU        avec C++ AMP pour les        performances extrêmes                               Bruno Boucard...
CONSEIL ET ARCHITECTURE IT-         •         •             160 collaborateurs spécialisés en IT-Finance             CA 20...
Démo Cartoonizer !De quoi allons-nous parler ?
Agenda     • 1ière Partie : L’essentiel de C++ AMP      – Contexte      – Fondamentaux     • 2ième Partie: Concepts plus a...
CPU vs GPU aujourd’hui       •   Faible bande passante mémoire           •   Bande passante mémoire élevée       •   Forte...
CPU vs GPU aujourd’hui                                                             image     • CPUs et GPUs se rapprochent...
Plateformes d’exécution de C++ AMP*      •   Windows Azure                         •   Windows Phone                      ...
Qu’est que C++ AMP ?    • Appartient à Visual C++    • Intégrée à Visual Studio    • Librairie STL-like pour gérer      le...
Transformer ce code séquentiel en code          GPU                                           #include <amp.h>            ...
Comprendre le code C++ AMP    parallel_for_each:          void AddArrays(int n, int * pA, int * pB, int * pC)             ...
Comprendre le fonctionnement du     parallel_for_each     •   Exécute l’expression lambda pour chaque point de l’extent   ...
Le mot clef restrict    • Sapplique aux fonctions (y compris les lambda)    • resctrict(…) informe le compilateur d’appliq...
Les restrictions du mot clef restrict     • Pas de                                   • Pas de       • récusions           ...
Surcharge via le mot clef restrict       double cos( double d );                            // 1a code cpu       double co...
Gestion des données multidimensionnelles     •   index<N> - représente un point à N coordonnées     •   extent<N> - taille...
Le conteneur: array_view<T, N>      •       Vue sur les données stockées dans la mémoire CPU ou              la mémoire GP...
Le second conteneur: array<T, N>        •   Tableau multidimensionnel qui contient des éléments de type T de dimension N  ...
Comprendre les accélérateurs                                   Host                Accélérateurs     • accelerator        ...
Démo Accélérateurs!Fondamentaux
Algorithme produit matriciel  • Aij * Bjk = Cik      – Chaque ligne A est multipliée par toutes les        colonnes entièr...
Produit matriciel du CPU au GPUvoid MatrixMultiplySerial( vector<float>& vC,         void MatrixMultiplyAMP( vector<float>...
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 ...
Une vue du matériel GPU pour un développeur                                                        Thread                 ...
Une vue du matériel GPU pour un développeur                     …                                 …           Tuile compos...
Une vue du matériel GPU pour un développeur                     …                                 …           Tuile compos...
parallel_for_each: surcharge pour les tuiles        • Orchestrer des threads           array_view<int,1> data(12, my_data)...
tiled_extent (depuis un extent)                    extent<1> e(12);                     0     1     2        3   4      5 ...
tiled_index      • Soit                                           col 0   col 1       col 2   col 3   col 4   col 5       ...
tile_static        • Le mot clef tile_static dédié au stockage mémoire        • Second mot clef ajouté au langage C++     ...
tile_barrier      • classe tile_barrier            – Synchronise tous les threads au sein d’une tuile jusquà              ...
Cacher avec tile_static                0,0 0,1 0,2 0,3 0,4 0,5                                              1,0 1,1 1,2 1,...
tile_static en action                  0,0 0,1 0,2 0,3 0,4 0,5                                              1,0 1,1 1,2 1,...
Synchro avec tile_barrier0,0               0,1 0,2 0,3 0,4 0,5                                              1,0 1,1 1,2 1,...
Retour sur la Multiplication Matricielle       • Chargement des données pour 4 threads       • Les threads chargent plusie...
Multiplication Matricielle – Exemple (tuilée) void MatrixMultSimple(vector<float>& vC, const vector<float>& vA, const   vo...
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...
Debugger GPU en ActionVisual Studio
2ième Partie: ce que vous avez appris !  Comprendre le calcul tuilé        La macro architecture GPU pour les développeur...
Conclusion     • Démocratisation de la programmation parallèle hétérogène        – Haute performance accessible au grand p...
Pour aller plus loin …      MSDN Forums to ask questions      •    http://social.msdn.microsoft.com/Forums/en/parallelcppn...
Développeurs                                                         Pros de l’IT http://aka.ms/generation-app       Forme...
Prochain SlideShare
Chargement dans…5
×

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

1 027 vues

Publié le

Visual Studio 2012 propose une nouvelle librairie appelée C++ Accelerated Massive Parallelism (C++ AMP). Cette librairie permet d'exploiter facilement les nombreux cœurs des cartes GPU afin d'obtenir des performances extrêmes. À l'instar des librairies parallèles fournies avec Visual Studio 2010, la librairie C++ AMP est accompagnée d'un écosystème facilitant le cycle de vie d'une application utilisant du code GPU. Que vous soyez développeur C++ ou bien même C# sans connaissance sur la programmation GPU, cette session vous permettra de comprendre à la fois les concepts inhérents à la programmation sur GPU et leurs implémentations respectives avec la librairie C++ AMP. Si au contraire, vous êtes déjà familier avec les technologies comme CUDA ou OpenCL, cette session vous permettra d'apprécier l'expressivité de C++ AMP associé à un outillage à la fois simple et efficace.

0 commentaire
1 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

Aucun téléchargement
Vues
Nombre de vues
1 027
Sur SlideShare
0
Issues des intégrations
0
Intégrations
5
Actions
Partages
0
Téléchargements
18
Commentaires
0
J’aime
1
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive
  • Notation
  • Intro code / dev
  • Utilisation de Visual C++ component extensions (C++/CX ) afin de produire un application Windows Store sur le base de l’application full C++.
  • La programmation GPU avec C++ AMP pour les performances extrêmes

    1. 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 TechDayshttp://notes.mstechdays.fr
    2. 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. 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. 4. Démo Cartoonizer !De quoi allons-nous parler ?
    5. 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 • ConclusionLa programmation GPU avec C++ AMP
    6. 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 dexé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écialistesContexte
    7. 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 demainContexte
    8. 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 ouverteContexte * Certaines plateformes seront disponibles dans la prochaine version de C++ AMP
    9. 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. 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. 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 demandeFondamentaux
    12. 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 7Fondamentaux
    13. 13. Le mot clef restrict • Sapplique 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++ AMPFondamentaux
    14. 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 doubleFondamentaux
    15. 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. 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 <=128Fondamentaux
    17. 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. 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 laccé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. 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 lhôte et un accelerator_viewFondamentaux
    20. 20. Démo Accélérateurs!Fondamentaux
    21. 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 » CFondamentaux
    22. 22. Produit matriciel du CPU au GPUvoid 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. 23. Démo Produit Matriciel !Fondamentaux
    24. 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éesRésumé de la première partie
    25. 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-GPUComprendre le calcul tuilé
    26. 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-GPUComprendre le calcul tuilé
    27. 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-GPUComprendre le calcul tuilé
    28. 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. 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,5Techniques plus avancées: calcul tuilé
    30. 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. 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. 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. 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_originsComprendre le calcul tuilé
    34. 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_originsComprendre le calcul tuilé
    35. 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_originsComprendre le calcul tuilé
    36. 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. 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. 38. Démo Produit Matriciel Tuilé !Comprendre le calcul tuilé
    39. 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 conditionsVisual Studio
    40. 40. Debugger GPU en ActionVisual Studio
    41. 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 curseurRésumé de la seconde partie
    42. 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 StudioC++ AMP en quelques mots
    43. 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.aspxPour creuser un peu plus …
    44. 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 accompagnerWindows 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

    ×