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

44
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

description

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.

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

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

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

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

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

Bruno BoucardExpert Parallèle

FINAXYS

Code / Développement

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

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

CONSEIL ET ARCHITECTURE IT-FINANCE•160 collaborateurs spécialisés en IT-Finance

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

•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é

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

De quoi allons-nous parler ?

Démo Cartoonizer !

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

•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

Agenda

La programmation GPU avec C++ AMP

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

• Bande passante mémoire élevée

• Faible consommation d'énergie/FLOP

• Haut niveau de parallélisme

• Pipelines d'exécution peu profonds

• Accès cache mémoire séquentiels

• Supporte la programmation parallèle orientée

données

• Programmation réservée à des spécialistes

Contexte

CPU vs GPU aujourd’hui

•Faible bande passante mémoire

•Forte consommation d’énergie/FLOP

•Niveau moyen de parallélisme

•Pipelines d’exécution profonds

•Accès cache mémoire aléatoires

•Supporte la programmation généraliste

•Programmation grand public

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

• CPUs et GPUs se rapprochent de plus en plus …• …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

CPU vs GPU aujourd’hui

image source: AMD

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

• Windows Phone• Windows RT• Windows Embedded• Xbox

•Windows Azure

•Windows Desktop

•Windows Server

•Windows HPC Server

Contexte

Plateformes d’exécution de C++ AMP*

... tourne aussi sur des plateformes non Microsoft via une spécification ouverte

* Certaines plateformes seront disponibles dans la prochaine version de C++ AMP

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

• Appartient à Visual C++ • Intégrée à Visual Studio• Librairie STL-like pour gérer

les données multidimensionnelles

• Construite sur Direct3D 11• Spécification ouverte

Contexte

Qu’est que C++ AMP ?

performance

portabilité

productivité

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

Fondamentaux

Transformer ce code séquentiel en code GPU

void AddArrays(int n, int * pA, int * pB, int * pC){

for (int i=0; i<n; i++)

{ pC[i] = pA[i] + pB[i]; }

}

#include <amp.h>using namespace concurrency;

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); parallel_for_each( c.extent, [=](index<1> i) restrict(amp) { c[i] = a[i] + b[i]; } );}

void AddArrays(int n, int * pA, int * pB, int * pC){

for (int i=0; i<n; i++)

{ pC[i] = pA[i] + pB[i]; }

}

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

Fondamentaux

Comprendre le code C++ AMPvoid 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); parallel_for_each(

c.extent, [=](index<1> i) restrict(amp) { c[i] = a[i] + b[i];

} );}

Les variables array_view sont capturées par valeur et leurs données associées sont copiées dans l’accélérateur à la demande

restrict(amp): dit au compilateur de forcer l’exécution de ce code sur le GPU

parallel_for_each: exécute l’expression lambda sur l’accélérateur une fois par thread

extent: le nombre de threads et leur topologie pour exécuter l’expression lambda

index: le thread ID qui exécute l’expression lambda, est utilisé pour retrouver les données

array_view: wrapping des données pour les traiter sur l’accélérateur

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

• Exécute l’expression lambda pour chaque point de l’extent• Semble synchrone, mais en réalité est asynchrone

Fondamentaux

Comprendre le fonctionnement du parallel_for_each

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

Code noyau

Exécution sur la carte GPU

c[0]

= a

[0] +

b[0

]

0

c[1]

= a

[1] +

b[1

]

1

c[2]

= a

[2] +

b[2

]

2

c[3]

= a

[3] +

b[3

]

3

c[4]

= a

[4] +

b[4

]

4

c[5]

= a

[5] +

b[5

]

5

c[6]

= a

[6] +

b[6

]

6

c[7]

= a

[7] +

b[7

]

7

index

thread

Code noyau

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

• 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++ AMPFondamentaux

Le mot clef restrict

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

Fondamentaux

Les restrictions du mot clef restrict

• Pas de

• récusions

• ‘volatile'

• fonctions virtuelles

• pointeurs de fonctions

• pointeurs vers des fonctions

membres

• pointeurs dans des structures

• pointeurs de pointeurs

• champs de bits

• Pas de

• goto ou labels

• throw, try, catch

• Variables globales ou statiques

• dynamic_cast ou typeid

• déclarations __asm__

• varargs

• types non supportés

• e.g. char, short, long double

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

Fondamentaux

Surcharge via le mot clef restrictdouble cos( double d ); // 1a code cpudouble cos( double d ) restrict(amp); // 1b code ampdouble 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 //… });}

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

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

• N peut être n’importe quel nombre <=128

index<1> i(2);

extent<1> e(6);

6

index<2> i(0,2);

extent<2> e(3,4);4

3

index<3> i(2,0,1);

extent<3> e(3,2,2);2

23

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

• 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• Rectangulaire• Accès aux éléments déclenchent• des copies implicites

Fondamentaux

Le conteneur: array_view<T, N>

index<2> i(3,9);

int o = a[i]; // ou a[i] = 16;// ou int o = a(3, 9);

vector<int> v(10); extent<2> e(2,5); array_view<int,2> a(e, v);

// Les 2 lignes peuvent aussi s’écrire // array_view<int,2> a(2,5,v);

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

• 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>

Fondamentaux

Le second conteneur: array<T, N>

vector<int> v(8 * 12);extent<2> e(8,12);

array<int,2> a(e);copy_async(v.begin(), v.end(), a);

parallel_for_each(e, [&](index<2> idx) restrict(amp) { a[idx] += 1;});copy(a, v.begin());

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

• accelerator – DX11 GPU

• Support GPU– WARP (Windows Advanced Rasterisation

Platform)• multi-core & vectorisazion (SSE) • Accessible via Direct3D

– REF• Emulateur qui simule un pilote

direct3d sur CPU– CPU

• Support pour optimiser les transferts de données entre l'hôte et un accelerator_view

Fondamentaux

Comprendre les accélérateurs

CPUs

System memory

GPUPCIeGPU

GPU

GPU

Host Accélérateurs

• accelerator View– Contexte pour

ordonnancer les threads GPU et gérer les données en mémoire

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

Fondamentaux

Démo Accélérateurs!

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

• 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

Algorithme produit matriciel

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

Fondamentaux

Produit matriciel du CPU au GPUvoid MatrixMultiplySerial( vector<float>& vC, const vector<float>& vA, const vector<float>& vB, int M, int N, int W ){

for (int row = 0; row < M; row++) { for (int col = 0; col < N; col++){ float sum = 0.0f; for(int i = 0; i < W; i++) sum += vA[row * W + i] * vB[i * N + col]; vC[row * N + col] = sum; } }}

void MatrixMultiplyAMP( vector<float>& vC, const vector<float>& vA, 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, [=](index<2> idx) restrict(amp) { int row = idx[0]; int col = idx[1];

float sum = 0.0f; for(int i = 0; i < W; i++) sum += a(row, i) * b(i, col); c[idx] = sum; } );}

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

Fondamentaux

Démo Produit Matriciel !

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

Résumé de la première partie

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

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

Une vue du matériel GPU pour un développeur

Comprendre le calcul tuilé

Registres par Threads

Mémoire Globale

………

……… ……

Thread

N’est pas montré:• Mémoire constante• Mémoire des

contrôleurs• Schedulers• Autres caches• Cas Multi-GPU

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

Une vue du matériel GPU pour un développeur

Comprendre le calcul tuilé

Registres par Threads

Mémoire Globale

………

Registres par Threads

……… ……

Tuile composée de threads

N’est pas montré:• Mémoire constante• Mémoire des

contrôleurs• Schedulers• Autres caches• Cas Multi-GPU

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

Une vue du matériel GPU pour un développeur

Comprendre le calcul tuilé

Cache Programmable

Registres par Threads

Mémoire Globale

………

Cache Programmable

Registres par Thread

……… …… Les variable tile_static

sont partagée par les threads dans la même tuile

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

Tuile composée de threads

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

• Orchestrer des threads dans des tuiles– La version de base ne le

permet pas• parallel_for_each version

tuile accepte ces surcharges– tiled_extent<D0> ou

tiled_extent<D0, D1> ou tiled_extent<D0, D1, D2>

• L’expression lambda accepte– tiled_index<D0> ou

tiled_index<D0, D1> ou tiled_index<D0, D1, D2>

Comprendre le calcul tuilé

parallel_for_each: surcharge pour les tuiles

parallel_for_each(data.extent.tile<6>(), [=] (tiled_index<6> t_idx) restrict(amp) { … });

array_view<int,1> data(12, my_data);

parallel_for_each(data.extent, [=] (index<1> idx) restrict(amp) { … });

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

Techniques plus avancées: 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

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

• Soit

• Lorsque la lambda est exécutée par– 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é

tiled_index col 0 col 1 col 2 col 3 col 4 col 5

row 0

row 1

T

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

T

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

• 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_static

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

• 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();

tile_barrier

Comprendre le calcul tuilé

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

Comprendre le calcul tuilé

Cacher avec tile_static1 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

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

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

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

Comprendre le calcul tuilé

tile_static en action1 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

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

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

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

Comprendre le calcul tuilé

Synchro avec tile_barrier1 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

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

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

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

• 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é

Retour sur la Multiplication Matricielle

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

Multiplication Matricielle – Exemple (tuilée)

Techniques plus avancées: calcul tuilé

void MatrixMultSimple(vector<float>& vC, const vector<float>& vA, 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, [=] (index<2> idx) restrict(amp) { int row = idx[0]; int col = idx[1]; float sum = 0.0f;

for(int k = 0; k < W; k++) sum += a(row, k) * b(k, col);

c[idx] = sum; } );}

void MatrixMultTiled(vector<float>& vC, const vector<float>& vA, const vector<float>& vB, int M, int N, int W ){ static const int TS = 16; 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.tile< TS, TS >(), [=] (tiled_index< TS, TS> t_idx) restrict(amp) { int row = t_idx.local[0]; int col = t_idx.local[1]; float sum = 0.0f; for (int i = 0; i < W; i += TS) { tile_static float locA[TS][TS], locB[TS][TS]; locA[row][col] = a(t_idx.global[0], col + i); locB[row][col] = b(row + i, t_idx.global[1]); t_idx.barrier.wait(); for (int k = 0; k < TS; k++) sum += locA[row][k] * locB[k][col]; t_idx.barrier.wait(); } c[t_idx.global] = sum; } );}

void MatrixMultTiled(vector<float>& vC, const vector<float>& vA, const vector<float>& vB, int M, int N, int W ){ static const int TS = 16; 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.tile< TS, TS >(), [=] (tiled_index<TS, TS> t_idx) restrict(amp) { int row = t_idx.local[0]; int col = t_idx.local[1]; float sum = 0.0f; for (int i = 0; i < W; i += TS) { tile_static float locA[TS][TS], locB[TS][TS]; locA[row][col] = a(t_idx.global[0], col + i); locB[row][col] = b(row + i, t_idx.global[1]); t_idx.barrier.wait(); for (int k = 0; k < TS; k++) sum += locA[row][k] * locB[k][col]; t_idx.barrier.wait(); } c[t_idx.global] = sum; } );}

Phase 1 Phase 2

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

Comprendre le calcul tuilé

Démo Produit Matriciel Tuilé !

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

• 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

C++ AMP Parallel Debugger

Visual Studio

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

Debugger GPU en Action

Visual Studio

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

Résumé de la seconde partie

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

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

• 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

Conclusion

C++ AMP en quelques mots

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

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/

C++ AMP Samples• http://

blogs.msdn.com/b/nativeconcurrency/archive/2012/01/30/c-amp-sample-projects-for-download.aspx

Graphics in C++ AMP • http://

blogs.msdn.com/b/nativeconcurrency/archive/2012/01/25/concurrency-graphics-in-c-amp.aspx

Interoperability between Direct 3D and C++ AMP• http://

blogs.msdn.com/b/nativeconcurrency/archive/2011/12/29/interoperability-between-direct-3d-and-c-amp.aspx

C++ AMP open spec• http://

blogs.msdn.com/b/nativeconcurrency/archive/2012/02/03/c-amp-open-spec-published.aspx

Pour aller plus loin …

Pour creuser un peu plus …

Libraries for C++ AMP• http://

blogs.msdn.com/b/nativeconcurrency/archive/2012/05/19/libraries-for-c-amp.aspx

C++ AMP for the OpenCL Programmer• http://

blogs.msdn.com/b/nativeconcurrency/archive/2012/04/10/c-amp-for-the-opencl-programmer.aspx

C++ AMP for the CUDA Programmer• http://

blogs.msdn.com/b/nativeconcurrency/archive/2012/04/11/c-amp-for-the-cuda-programmer.aspx

C++ AMP for the DirectCompute Programmer• http://

blogs.msdn.com/b/nativeconcurrency/archive/2012/04/09/c-amp-for-the-directcompute-programmer.aspx

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

Formez-vous en ligne

Retrouvez nos évènements

Faites-vous accompagner gratuitement

Essayer gratuitement nos solutions IT

Retrouver nos experts Microsoft

Pros de l’ITDéveloppeurs

www.microsoftvirtualacademy.com

http://aka.ms/generation-app

http://aka.ms/evenements-developpeurs

http://aka.ms/itcamps-france

Les accélérateursWindows Azure, Windows Phone,

Windows 8

http://aka.ms/telechargements

La Dev’Team sur MSDNhttp://aka.ms/devteam

L’IT Team sur TechNethttp://aka.ms/itteam