57
Introduction ` a la programmation massivement parall` ele L’exemple d’opencl F. Sailhan CNAM, d´ epartement informatique November 21, 2014

Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Introduction a la programmation massivement paralleleL’exemple d’opencl

F. Sailhan

CNAM, departement informatique

November 21, 2014

Page 2: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Plan

1 Introduction

2 Notions de base sur le parallelismeArchitecture

3 OpenCLModelesModele d’executionMon premier ProgrammePremier bilanDeuxieme Programme

4 Conclusion

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 2 / 54

Page 3: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Pourquoi etudier la programmation parallele?

Les contres1 Les performances d’un meme logiciel s’ameliorent a chaque nouvelle

generation de processeur,

2 Nous sommes habitues a la programmation sequentielle,

3 La programmation parallele, ce n’est pas nouveaux et pourtant, peud’applications l’utilisent ...

4 Depuis 2003, le multi coeur ...

5 Les data centers, le cloud ...

@AFP Facebook Data Center on April 19, 2012 in Forest City, NorthCarolina.

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 3 / 54

Page 4: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Pourquoi etudier la programmation parallele?

Oui mais...1 Cette cadence se ralentit en 2003 : la consommation d’energie et la

dissipation de chaleur limitent la frequence des horloges,2 Plus besoin d’ordinateurs couteux... : la programmation devient

parallele avec le multi-coeur, massivement parallele avec les GPU(Graphic Processing Units)

I Exigence temps reelles (toucher l’ecran d’un smartphone)I 20 capteurs par smartphone (cameras, microphones), systemes

embarques (voitures)I Resolution plus poussee (20 fois plus de pixels)I acceleration CPU impossible a moins de vider la batterie

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 4 / 54

Page 5: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Pourquoi etudier la programmation parallele?

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 5 / 54

Page 6: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

To be or not to be ? CPU or GPU ? la fausse question

4 multi-coeurs optimises pour une execution sequentielle

1 Une logique de controle sophistiquee au service del’execution parrallele d’un seul thread

2 Large memoire cache avec acces reduit auxintructions + donnees

GPU = pleins de multi-processeurs = parallelisationmassive

1 Memoire globable: DRAM 6= DRAM de carte mereI bande passante GPU et memoire globale = 20 fois

plus rapide qu’avec la DRAM de la carte mere. ChipG80: 8GB/s DRAM-CPU et 86,4GB DRAM-GPU

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 6 / 54

Page 7: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

L’histoire des GPUs

En 3 mots

Annees 80-90 : les fonctionalites graphiques sont pipelinees au niveauhardware. Elles sont configurables mais pas programmables

Annees 2000: Nvidia developpe le compilateur CUDA C, C++, leslibrairies a destination des programmeurs,

Consortium Kronos cree pour developper d’un standard ouvert(middleware + langage), cross-plateforme

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 7 / 54

Page 8: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Standards ouverts specifies par le groupe Khronos

Khronos “connecting software to silicon”, https://www.khronos.org

OpenCL = API de calcul que nous verrons

OpenGL = API graphique

WebGL et WebCL = API pour l’acceleration graphique etacceleration des calculs pour le Web (dans les navigateurs)

Collada: exchange d’information 3D entre applications

OpenGL ES : API graphique pour les systemes embarques(smartphones, display, automobile)

Stream input = API pour l’interaction avec les capteurs generant desflux, combiner les flus

OpenKcam : fusion (camera) et controle (actuator)

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 8 / 54

Page 9: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Parallelisme : taxonomie de Michael J. Flynn

Classification basee sur la concurrence des flux d’instructions & donnees

Flux d’instructions = ensemble d’instructions formant un processus

Flux de donnees = donnees sur lesquelles le processus opere

Single Instruction, Single Data stream (SISD): systeme sequentiel : 1flux d’instructions opere sur 1 donnee

Single Instruction, Multiple Data streams (SIMD): 1 instruction

diffusee a plusieurs unites de calcul ;chacune opere la meme instruction sur

differentes donnees

Multiple Instruction, Single Data stream (MISD): plusieurs flux

d’instructions operent sur le meme flux de donnees

Multiple Instruction, Multiple Data streams (MIMD): plusieurs

unites de calculs operent sur plusieurs flux de donnees au moyen de plusieurs

flux d’instructions

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 9 / 54

Page 10: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Parallelisme MISD, MIMD : 2 modeles memoire

Par memoire distribuees

# processeurs (specialises ou non) sont connectes a la memoire viaun reseau haut debit (Myrinet, Infiniband, 10Gbit Ethernet), memoire

Exemple : cluster de serveurs, MPP (Massively Parallel Processor) cfla liste des plus puissants : http://www.top500.org

Chaque processeur dispose de son propre espace d’adressage

Inconvenient : transfert lent compare a un acces locale en memoire →adapte aux applications peu communicantes

Par memoire partagee

1 tous les processeurs partagent le meme espace d’adressage etcommuniquent entre eux par lecture/ecriture dans la memoirepartagee

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 10 / 54

Page 11: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Parallelisme MIMD : 2 modeles memoire

Par memoire distribuees

Les interactions se font par passage de message entre les processeurs

Inconvenient : portage difficile d’un programme sequentiel

Exemple: langage MPI (Message Passing Interface) utilise pour desclusters distribues (jusqu’a 100 000 noeuds)

Par memoire partagee

1 Coherence forte → quelques centaines de noeudsExemple : Open MP (Open Multi-processing)

2 Coherence relaxee : une memoire partagee de petite tailleExemple : Cuda, Opencl

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 11 / 54

Page 12: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Parallelisme logiciel

La parallelisation consiste a:

1 Analyser des dependances au niveau des structures de donnees et desprocessus

2 Determiner le meilleure algorithme/framework pour executer le code

3 Reecrire du code avec un framework tel que Message PassingInterface (MPI) ou OpenCL

Parrallelisme des donnees

Les sections de programme sont caracterisees par un parallelismeimportant des donnees ce qui permet d’effectuer des operationsarithmetiques en parallele sans danger

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 12 / 54

Page 13: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Parallelisme logiciel - Performances

Lois des 90-10

10 % du code est parallelisable,90 % du code est sequentiel,

Idee : en terme de temps d’execution, nous passons la plupart dutemps dans les 10% du code

Evaluation du benefice : loi d’Amdahl

S = 1(1−P)+ P

N

N : nombre de processeurs,

P : fraction du temps pris par la portion de code parallelisable

S : rapidite

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 13 / 54

Page 14: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Parallelisme de controle - Parallelisme de donnees

for(i=0;i<N;i++) {

resultA = taskA(i);

resultB = taskB(i);

resultC = taskC(i);

}

Parallelisme de donnees

Les donnees sont partionnees

Exemple: chaque processeur gere N/3 iterations de la boucle

Avantage : plusieurs processeurs executent le meme programme etfinissent en meme temps

Parallelisme de controle

Chaque processeur execute une tache de la boucle

Inconvenient: desynchronisation

Solution: partage equitable de la charge (gestion d’une queue destaches a assigner sur les processeur)F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 14 / 54

Page 15: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

1 Introduction

2 Notions de base sur le parallelismeArchitecture

3 OpenCLModelesModele d’executionMon premier ProgrammePremier bilanDeuxieme Programme

4 Conclusion

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 15 / 54

Page 16: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Architecture GPU

Grappes de multi-processeurs partageant un cached’instructions et la meme logique de controle

Chaque multi-processeur dispose d’une unite MAD(Multiply-Add) et (Add-Multiply) et de fonctionsparticulieres (exemple la racine carree)

Chaque multi-processeur execute un parallelismemassif (plusieurs milliers de threads)

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 16 / 54

Page 17: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Exemple d’architecture: Kepler GK100 de NVIDIA

Derniere generation (2014) :Kepler = Fermi * 2= 1536KB de cache L2 partage par 15 SMX =15 clusters contenant chacun 4 schedulers de32 threads

Chaque SMX dispose de 64KB (memoirepartagee + cache L1) + cache (read only) de48KB

@http://www.nvidia.com/object/nvidia-kepler.html

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 17 / 54

Page 18: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Exemple d’architecture: Kepler GK100

Chaque thread a acces a 255 registres + lesmemoires hierarchisees

Operation atomiques (add, min, mac, compareand swap)

Nouveaute : parallelisme dynamique =recursivite permise = planification a la volee @

http://www.nvidia.com/object/nvidia-kepler.html

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 18 / 54

Page 19: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

OpenCL (Open Computing Language)

Definitiona framework suited for parallel programming of heterogeneous systems

Objectifs

Utiliser toutes les ressources :I a la fois CPU multi-coeurs et GPU : meme code executable sur

CPU/GPU (minus quelques optimisations)I la parallelisation des taches et des donnees

Un modele de programmation haut niveau base sur le C

Cross-platform, cross-vendeur, cross-OS (android, ...)I API pour acceder a la plateforme : abstraction du materiel (memoire,

GPU ect...)I API pour l’execution : execution transparente des threads, gestion

transparente des queues, des ressources memoires

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 19 / 54

Page 20: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Modelisation de la memoire

Un modele facilement retransposable sur les architectures materielles.Celui de Cuda est casiment similaire.

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 20 / 54

Page 21: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Modelisation de la memoire

Memoire privee : chaque work-item dispose d’une memoire priveequi est la plus rapide d’acces, sans primitive de synchronisation, et estallouee/partitionnee a la compilation pour ledit kernel et ladite carte :sa taille est inconnue

Memoire locale : Memoire partagee par tout un work group :chaque workitem du meme work group peut y acceder. Generallementsur ship

Memoire globale accessible par tous les workgroup, est nonsynchronisee, possiblement constant (c-a-d en lecture seule) :memoire la plus large (GB),

Memoire globale de l’hote la plus lente d’acces mais la plusconsequente. Memoire a eviter (temps de chargement important :mieux vaut garder le maximum possible, le plus longtemps possiblesur le GPU)

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 21 / 54

Page 22: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Acces a la memoire

Espace d’adressage: private (au work-item), local (workitems d’unmeme workgoup), global (accessible par tous les workitems de tousles work groups), constante (read only pour la memoire globale)

Gestion explicite de la memoire: les types de memoire doivent etreexplicitement definis au niveau du code en raison

I du manque de memoireI des transbordements dont le cout differe suivant le type de memoire

Modele relaxe d’acces a une memoire partageeI La vision d’un work-item n’est pas toujours celle des autresI Necessite de ce synchroniser avec des barrieres. Exemple: attendre que

tous les work-items aient ecris avant de lire. Cette synchronisation esttres couteuse.

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 22 / 54

Page 23: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Vocabulaire

Definition

host = le systeme de calcul = CPU (Central Processing Unit)traditionnel equipe de nombreux arithmetic execution units.

device = GPU

Un programmeur definie des fonctions devant s’executer sur le device.Chaque fonction est appelee un kernel

Organisation du programme

Un programme OpenCL est divise en deux parties :

une partie s’execute sur l’hote (partie non parrallelisee)

Une partie s’executant sur le GPU (partie parallelisee)

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 23 / 54

Page 24: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Modele d’execution

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 24 / 54

Page 25: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Modele d’execution

Work-item: equivalent d’un thread (= plus petite entited’execution). L’execution d’un kernel se fait sur un ensemble dework-items dont le nombre est parametre par le developpeur. Chaquework-item execute le meme code. Chaque work item est identifie (ID),

Work-group: ensemble de work-items cooperant ensemble au seind’un work-groups. Reflete l’organisation des work-items en grille de 1,2, 3 dimensions. Est identifie par un ID

ND-Range : niveau d’organisation des work-groups = 1, 2 ou 3dimensions

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 25 / 54

Page 26: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Premier programme

Objectif : ajouter deux vecteurs1 Developper une fonction=kernel appelee vector add qui ajoute deux

vecteurs. Cette fonction est placee un fichier appele vecteur .cl .2 Developper toute le code permettant de lancer en parallele les threads

permettant d’ajouter les deux vecteurs. Placer ce code dans un fichiervecteur .c .

3 Compiler + executer

Consulter : https://www.khronos.org/developers/reference-cards/

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 26 / 54

Page 27: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Kernel ajoutant deux vecteurs

__kernel void vector_add(__global const float* src_a,

__global const float* src_b, __global float* res,

const int num)

{

const int idx = get_global_id(0);

if (idx < num)

{

res[idx] = src_a[idx] + src_b[idx];

}

}

2 vecteurs en entrees src a src b, un resultat res, #threads s’executent

get local id renvoie l’identifiant du workitem s’executant

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 27 / 54

Page 28: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Kernel ajoutant deux vecteurs

__kernel void vector_add(__global const float* src_a,

__global const float* src_b, __global float* res,

const int num)

{

const int idx = get_global_id(0);

if (idx < num)

{

res[idx] = src_a[idx] + src_b[idx];

}

}

2 vecteurs en entrees src a src b, un resultat res, #threads s’executent

get local id renvoie l’identifiant du workitem s’executant

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 27 / 54

Page 29: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Kernel - DeveloppementLe language utilise est base sur l’ANSI C99. Lors du developpement d’unkernel 3 aspects sont a considerer :

1 Il faut determiner lors du passage des arguments le type de memoireutilise, c’est a dire de l’espace d’adressage qui est soit :

I global : espace d’adressage globalI constant : region de la memoire en lecture seulementI local : memoire partagee par le work-group.I private: memoire du work-item.

2 Attention: chaque type d’adressage est distinct, ce qui signifie quetous les mouvements de donnees doivent etre explicites.

3 Les methodes fournissant un acces au domaine de calcul

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 28 / 54

Page 30: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Premier programme : programmation de l’hote (host)

Vous devez imperativement consulter la specification du language tres bienresumee par l’ OpenCL Quick Reference Card disponible a l’url :https://www.khronos.org/developers/reference-cards/ Ce guide contient les types

de base, les fonctions mathematiques, geometriques ... dont il faut privilegier

l’utilisation

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 29 / 54

Page 31: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Premier programme : programmation de l’hote (host)

Etape suivante

developer l’environnement autours permettant d’executer le kernel :fichier separe : vecteur.c

Pour compiler et executer, taper en ligne de commande :

$ gcc -o vect vecteur.c -lOpenCL

$ ./vect

#include <stdio.h>

#include <stdlib.h>

#ifdef __APPLE__

#include <OpenCL/opencl.h>

#else

#include <CL/cl.h>

#endif

int main(void) {...}F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 30 / 54

Page 32: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Premier programme : programmation de la plateforme

Platform

hote + ensemble de devices geres par OpenCL.

Permet a une application de partager les ressources et d’executer leskernels sur les devices au sein de la plateforme

Est represente par l’objet a cl latform object initialise par la fonctionsuivante :

cl_int oclGetPlatformID (cl_platform_id *platforms)

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 31 / 54

Page 33: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Premier programme : initialisation du device

Device

Deux types de devices sont geres par OpenCl: device type=CL DEVICE TYPE GPU pour GPU, CL DEVICE TYPE CPU pourCPU

Le nombre de devices (typiquement 1) est defini num entries

Le(s) device(s) sont initialises par la fonction ci-dessous :

cl_int clGetDeviceIDs (cl_platform_id platform,

cl_device_type device_type, cl_uint num_entries,

cl_device_id *devices, //pointeur : liste des devices

cl_uint *num_devices) //#devices dont le type a ete defini

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 32 / 54

Page 34: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Premier programme : initialisation du context

Context

est utilise par l’environnement d’execution d’OpenCL (ses kernels,devices, gestionnaire de memoire, queue(s) de commandes)

est reference par l’objet cl context object, initialise par la fonctionci-dessous:

cl_context clCreateContext (const cl_context_properties *properties,

// Bitwise with the properties CL_CONTEXT_PLATFORM

cl_uint num_devices, //#devices

const cl_device_id *devices, // Pointeur sur les devices

void *pfn_notify(const char *errinfo, const void

*private_info, size_t cb, void *user_data), //fonction de call back

utilisee pour les notifications

void *user_data, // parametres de la fonction ci-dessus

cl_int *errcode_ret) // erreur renvoyee (aucune si = NULL)

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 33 / 54

Page 35: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Premier programme : queue de commande

CommandQueue

est utilise pour empiler les commandes a executer.

Plusieurs queues peuvent etre crees (les commandes sont alorsindependantes et non synchronisees)

est reference par l’objet cl command queue, initialise par la fonctionci-dessous:

cl_command_queue clCreateCommandQueue (cl_context context,

cl_device_id device,

cl_command_queue_properties properties, //bitwise

cl_int *errcode_ret) //erreur renvoyee (aucune si = NULL)

Les elements basiques de l’hote sont maintenant configures

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 34 / 54

Page 36: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Premier programme : plateforme, contexte, queue

cl_platform_id platform;

cl_context context;

cl_command_queue queue;

cl_device_id device;

//cl_int error = 0;

// Platform

error = oclGetPlatformID(&platform);

//if (error != CL_SUCCESS) exit(error);

// Device

clGetDeviceIDs(platform,CL_DEVICE_TYPE_GPU,1,&device,NULL);

// Context

context = clCreateContext(0, 1, &device, NULL, NULL, &error);

// Command-queue

queue = clCreateCommandQueue(context, device, 0, &error);

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 35 / 54

Page 37: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Premier programme : allocation de la memoire

Memoire

les variables a passer au kernel (entrees et sorties) doivent etre definies

La memoire allouee sur le device est de type:I CL MEM READ WRITEI CL MEM WRITE ONLYI CL MEM READ ONLYI CL MEM USE HOST PTR : utilisation de la memoire de l’hoteI CL MEM ALLOC HOST PTR : memoire de l’hote allouee et rendue

accessibleI CL MEM COPY HOST PTR :copie la memoire pointee par host ptr

cl_mem clCreateBuffer (cl_context context,

cl_mem_flags flags, //type de memoire

size_t size, // taille exprimee en octets

void *host_ptr, cl_int *errcode_ret)

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 36 / 54

Page 38: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Premier programme : allocation de la memoire

Memoire

Allocation de 3 vecteurs src a d , src b d , res d , initialisation desrc a d , src b d

Allocation des buffers: 2 en lecture et 1 en ecriture (resultat)

const int size = 1234567;

float* src_a_h = new float[size];

float* src_b_h = new float[size];

float* res_h = new float[size];

for(int i=0; i<size; i++) {src_a_h = src_b_h = (float) i;}

const int mem_size = sizeof(float)*size;

cl_mem src_a_d = clCreateBuffer(context, CL_MEM_READ_ONLY |

CL_MEM_COPY_HOST_PTR, mem_size, src_a_h, &error);

cl_mem src_b_d = clCreateBuffer(context, CL_MEM_READ_ONLY |

CL_MEM_COPY_HOST_PTR, mem_size, src_b_h, &error);

cl_mem res_d = clCreateBuffer(context, CL_MEM_WRITE_ONLY,

mem_size, NULL, &error);F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 37 / 54

Page 39: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Premier programme: remarques

Il existe deux facons de compiler :

Compilation en ligne : le fichier source contenant le kernel est lu dansle code de l’hote (solution que nous adoptons par la suite)

I Built du kernel lors de l’execution (OpenCL runtime library)I Avantage : portabilite, facilite les tests du kernelI Inconvenient : la compilation du kernel doit etre effectue par le

terminal ou il est deploye (solution inadaptee aux systemes embarques)

Compilation hors ligne : le fichier binaire du kernel est lu par le codede l’hote

I Pre-built du kernel par le compilateur OpenCL . Le binaire genere estcharge (OpenCL API).

I Avantage : rapiditeI Inconvenient : portabilite

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 38 / 54

Page 40: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Premier programme : lancement du programme

Programme

Un programme (= ensemble de kernels) est cree puis compile

// Creation du programme

cl_program clCreateProgramWithSource (cl_context context,

cl_uint count/*#fichiers*/, const char **strings /*noms

fichiers*/, const size_t *lengths/*longueurs des fichiers*/,

cl_int *errcode_ret)

//Compilation du programme

cl_int clBuildProgram(cl_program program, cl_uint num_devices

, const cl_device_id *device_list,

const char *options, // options compilation

void (*pfn_notify)(cl_program, void *user_data),

void *user_data)

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 39 / 54

Page 41: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Premier programme : lancer le kernelUne fois cree, le kernel est lance apres definission des arguments. Sacompilation a lieu lors de l’execution

// 1. Creation de kernel :

cl_kernel clCreateKernel (cl_program program,

const char *kernel_name, cl_int *errcode_ret)

//2. Definition de chaque argument

cl_int clSetKernelArg(cl_kernel kernel, cl_uint arg_index,//quel

argument size_t arg_size,//taille PROCHAIN argument

const void *arg_value) // Valeur

// 3. Appel du kernel

cl_int clEnqueueNDRangeKernel(cl_command_queue command_queue,

cl_kernel kernel, cl_uint work_dim /*1D,2D,3D*/, const size_t

*global_work_offset, const size_t *global_work_size//#work-items total

, const size_t *local_work_size, //#work-items par work-group

cl_uint num_events_in_wait_list, const cl_event

*event_wait_list, cl_event *event)F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 40 / 54

Page 42: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Premier programme : lancer le kernel

// 1. Creation du programme

size_t src_size = 124;

const char* path = shrFindFilePath("vecteur.cl", NULL);

const char* source = oclLoadProgSource(path, "", &src_size);

cl_program program = clCreateProgramWithSource(context, 1,

&source, &src_size, &error);

error = clBuildProgram(program, 1, &device,NULL,NULL,NULL);

cl_kernel vector_add_kernel = clCreateKernel(program,

"vector_add_gpu", &error);

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 41 / 54

Page 43: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Premier programme : lancer le kernel

// Arguments places dans la queue

clSetKernelArg(vector_add_k, 0, sizeof(cl_mem), &src_a_d);

clSetKernelArg(vector_add_k, 1, sizeof(cl_mem), &src_b_d);

clSetKernelArg(vector_add_k, 2, sizeof(cl_mem), &res_d);

clSetKernelArg(vector_add_k, 3, sizeof(size_t), &size);

// Lancement du kernel

const size_t local_ws = 512; // #work-items par work-group

//shrRoundUp renvoie le + petit multiple de local_ws > size

const size_t global_ws = shrRoundUp(local_ws, size);

//#work-items total

error = clEnqueueNDRangeKernel(queue, vector_add_k, 1, NULL,

&global_ws, &local_ws, 0, NULL, NULL);

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 42 / 54

Page 44: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Premier programme : lecture des resultats, liberation

cl_int clEnqueueReadBuffer (cl_command_queue command_queue,

cl_mem buffer, // a partir de quel buffer

cl_bool blocking_read, // lecture bloquante ou non

size_t offset, // offset depuis le debut

size_t cb, // combien d’octets lire

void *ptr, // pointer sur la memoire de l’hote

cl_uint num_events_in_wait_list,

const cl_event *event_wait_list, cl_event *event)

lecture des resultats et liberation des ressources allouees :

float* check = new float[size];

clEnqueueReadBuffer(queue, res_d, CL_TRUE, 0, mem_size,

check, 0, NULL, NULL);

clReleaseKernel(vector_add_k);

clReleaseCommandQueue(queue);

clReleaseContext(context);

clReleaseMemObject(src_a_d); clReleaseMemObject(src_b_d);

clReleaseMemObject(res_d);F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 43 / 54

Page 45: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Premier bilan: restriction

Le parallelisme des donnees : il existe une correlation entre lesidentifiants et l’organisation des work-items et les acces en memoire.Controle de flot: il est important que les meme instructions soientexecutees. Si plusieurs chemins peuvent etre empruntes, les differentschemins seront serialisesRestrictions :

pas de pointeur passe en argument au kernel,

pas de tableau de taille variable,

pas de recursion (pour les GPUs anciens)

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 44 / 54

Page 46: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Premier bilan: mise en garde

Le GPU parallelise efficacement si :

la meme operation est effectuee sur un ensemble de donnees (de taillerelativement moderee)

Chaque work-item fait des acces coherents en memoire GLOBALE :acces regroupes et sequentiels

La memoire globale est une sucession de mots de 16 ou 32 bits. Ici,chaque thread accede a un float (= 32 bits) en memoire Cas 1: accessequentiel aligne : 1 transaction Cas 2: acces sequentiel non aligne = 2transactions Cas 3: acces sequentiel espace = 2 transactions

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 45 / 54

Page 47: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Premier bilan: calcul de la bande passante theoriqueLe GPU parallelise efficacement si :

la meme operation est effectuee sur un ensemble de donnees (de taillerelativement moderee)Les echanges d’informations entre l’hote et le device sont minimisescar le bus PCI manque de bande passanteLe cout de chargement des donnees de l’hote vers le device (et visversa) est justifie. Cout injustifiable pour l’addition de 2 vecteurs.Pour l’addition de 2 matrices? le carre d’une matrice?

Hypotheses : NVIDIA GeForce GTX 280 DDR (Double Data Rate) RAMavec une cadence d’horloge (memory clock) de 1,107 MHz et une interfacememoire a 512-bitsQuestion: Quelle est la bande passance theorique (max)?Reponse : 1107.106.(512/8).2)/109 = 141.6Gbytes/secBande passante effective = ((Br + Bw)/109)/timeBr : nb d’octets lus par kernel, Bw : nb d’octets ecris par kernel i , time :exprime en seconde.Exemple : pour la copie d’une matrice 2048 x 2048,bande passante effective = 10482.4.2/109/timeF. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 46 / 54

Page 48: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

A vous de jouer

Objectif: multiplier une matrice par un vecteur, voir deux matricesRappel: multiplication matrice par vecteura b c

d e fg h i

123

=

a + 2.b + 3.cd + 2.e + 3.fg + 2.h + 3.i

Rappel: multiplication de 2 matricesa b c

d e fg h i

j k lm n op q r

=a.j + b.m + c.p a.k + b.n + c .q a.l + b.o + c .rd .j + e.m + f .p d .k + e.n + f .q d .l + e.o + f .rg .j + h.m + i .p g .k + h.n + i .q g .l + h.o + i .r

Strategie: sachant que l’acces a la memoire globale est tres lent,maximisez le nombre d’acces a la memoire partagee (locale)

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 47 / 54

Page 49: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Rappel: fonction multipliant la matrice M par le vecteur V

La fonction ci-dessous n’est pas parallelisee

matrix_vector_mul(const float* M, uint width, uint height,

const float* V, float* W) {

for (uint y = 0; y < height; ++y)

{

const float* row = M + y * width;

float dotProduct = 0;

for (uint x = 0; x < width; ++x)

dotProduct += row[x] * V[x];

W[y] = dotProduct;

}

}

row pointe au debut de chaque ligne identifiee par y

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 48 / 54

Page 50: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Rappel: fonction multipliant la matrice M par le vecteur V

La fonction ci-dessous n’est pas parallelisee

matrix_vector_mul(const float* M, uint width, uint height,

const float* V, float* W) {

for (uint y = 0; y < height; ++y)

{

const float* row = M + y * width;

float dotProduct = 0;

for (uint x = 0; x < width; ++x)

dotProduct += row[x] * V[x];

W[y] = dotProduct;

}

}

row pointe au debut de chaque ligne identifiee par y

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 48 / 54

Page 51: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Work-item multipliant une matrice par un vecteur

__kernel void MatrixVectorMul0(const __global float* M,

uint width, uint height, const __global float*

V,__global float* W) {

uint y = get_global_id(0);

const float* row = M + y * width;

float dotProduct = 0;

for (uint x = 0; x < width; ++x)

dotProduct += row[x] * V[x];

W[y] = dotProduct;

}

Invonvenient : un work-item calcul une ligne et risque d’etre inoccupe

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 49 / 54

Page 52: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Work-item multipliant une matrice par un vecteur

__kernel void MatrixVectorMul1(const __global float* M,

uint width, uint height, const __global float* V,

__global float* W) {

unint y;

for (y=get_global_id(0); y<height; y+=get_global_size(0))

{

const float* row = M + y * width;

float dotProduct = 0;

for (uint x = 0; x < width; ++x)

dotProduct += row[x] * V[x];

W[y] = dotProduct;

}

}

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 50 / 54

Page 53: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Premier bilan

Le nombre d’elements calcule par chaque work-item = height/ #work-items (+1 pour certains work-items si height n’est pas unmultiple du # work-items)

Avantage : decouplage entre la taille de la matrice et le nombre dework-item s’executant

Remarque: un kernel doit s’executer sur un #work-items≥ #multiprocesseurs.

centaines de work-items par multiprocessor qui seraient un multiple dela taille de warp (= 32).

Le meilleur NDRange depend du kernel, du #registres et doit etre fixepar des experimentations

Autres optimisations : l’acces contigu a la memoire permettant uneseule transaction memoire

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 51 / 54

Page 54: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Acces memoire, multiplication matrice par un vecteur

__kernel void MatrixVectorMul1(...) {

unint y;

for(y=get_global_id(0);y<height;y+=get_global_size(0))

{

const float* row = M + y * width;

float dotProduct = 0;

for (uint x = 0; x < width; ++x)

dotProduct += row[x] * V[x];

W[y] = dotProduct;

}

}

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 52 / 54

Page 55: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Acces memoire, multiplication matrice par un vecteur

__kernel void mul(__global float*M, uint width,uint height,

__global float* V, __global float* W,__local float* partprod)) {unint y;

for(y=get_group_id(0); y<height; y +=get_num_groups(0)){

float sum = 0;

for(uint x=get_local_id(0);x<width;x+=get_local_size(0))

sum += row[x] * V[x];

partprod[get_local_id(0)]=sum;

if (get_local_id(0) == 0) {

float dotProduct = 0;

for (uint t = 0; t < get_local_size(0); ++t)

dotProduct += partprod[t];

W[y] = dotProduct; }

barrier(CLK_LOCAL_MEM_FENCE);}}

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 53 / 54

Page 56: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

Conclusion: GPU for ever?

Nous assistons a une renaissance du calcul parallele caracterise par uneutilisation efficace de toutes les ressources, une utilisation avisee de laconcurrence. Critere primordiale : selectionner le bon materiel en fonctionde l’algorithme

GPU = processeur massivement multi-coeur caracterise par uneexecution SIMD

I GPU = special purpose hardware (parallelisme des donnees)I Implication multiples: les algorithmes doivent etre imperativement

designes pour eviter toute divergence au niveau des branchements.I Leur massivite implique de les maintenir occupesI Difficulte a debuger le code

CPU = general purpose hardwareI parfait pour un code serie ou un faible parallelisme avec de petites

unites de travail dont les taches a effectuer ne sont pas reliees,I facile a debuger, outils mature

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 54 / 54

Page 57: Introduction a la programmation massivement …cedric.cnam.fr/~sailhanf/enseignements/p2p/gpu.pdfF. Sailhan (CNAM, d epartement informatique)Introduction a la programmation massivement

David B. Kirk and Wen-mei W. HwuProgramming massively parallel processors A Hands-on approachlaurel.datsi.fi.upm.es/ media/proyectos/gopac/programming massively parallel processors.pdf

Kronos group

https://www.khronos.org

Kronos grouphttps://www.khronos.org

NvidiaOpenCL Best Practices Guide www.nvidia.com

F. Sailhan (CNAM, departement informatique)Introduction a la programmation massivement parallele November 21, 2014 54 / 54