Introduction au calcul parallèle avec OpenCL

Documents pareils
Introduction à la programmation des GPUs

Initiation au HPC - Généralités

Une bibliothèque de templates pour CUDA

Introduction à CUDA.

Introduction au langage C

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

. Plan du cours. . Architecture: Fermi ( ), Kepler (12-?)

Brefs rappels sur la pile et le tas (Stack. / Heap) et les pointeurs

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

Architecture des ordinateurs

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Introduction à la Programmation Parallèle: MPI

Contrôle Non Destructif : Implantation d'algorithmes sur GPU et multi-coeurs. Gilles Rougeron CEA/LIST Département Imagerie Simulation et Contrôle

Le langage C++ est un langage de programmation puissant, polyvalent, on serait presque tenté de dire universel, massivement utilisé dans l'industrie

Le prototype de la fonction main()

OS Réseaux et Programmation Système - C5

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

Gestion de la mémoire

Architecture des calculateurs

Généralités sur le Langage Java et éléments syntaxiques.

CAHIER DES CHARGES D IMPLANTATION

Segmentation d'images à l'aide d'agents sociaux : applications GPU

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

Programmer en JAVA. par Tama

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE


Structure d un programme et Compilation Notions de classe et d objet Syntaxe

INITIATION AU LANGAGE JAVA

Sanity Check. bgcolor mgcolor fgcolor

Infrastructures Parallèles de Calcul

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

I. Introduction aux fonctions : les fonctions standards

03/04/2007. Tâche 1 Tâche 2 Tâche 3. Système Unix. Time sharing

ACTIVITÉ DE PROGRAMMATION

Plan du cours. Historique du langage Nouveautés de Java 7

IFT Systèmes d exploitation - TP n 1-20%

Compression de Données - Algorithme de Huffman Document de Conception

Quantification d incertitude et Tendances en HPC

Le langage C. Séance n 4

Tests de performance du matériel

Java - la plateforme

Architecture des ordinateurs

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

Initiation. àl algorithmique et à la programmation. en C

as Architecture des Systèmes d Information

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

Cours d Algorithmique et de Langage C v 3.0

Algorithmique I. Algorithmique I p.1/??

Programmation système I Les entrées/sorties

Concept de machine virtuelle

DNS Server RPC Interface buffer overflow. Céline COLLUMEAU Nicolas BODIN

Langage C. Patrick Corde. 22 juin Patrick Corde ( Patrick.Corde@idris.fr ) Langage C 22 juin / 289

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

3IS - Système d'exploitation linux - Programmation système

Architecture des Ordinateurs. Partie II:

Hiérarchie matériel dans le monde informatique. Architecture d ordinateur : introduction. Hiérarchie matériel dans le monde informatique

Dans le chapitre 1, nous associions aux fichiers ouverts des descripteurs de fichiers par lesquels nous accédions aux fichiers.

M2-Images. Rendu Temps Réel - OpenGL 4 et compute shaders. J.C. Iehl. December 18, 2013

Programmation C. Apprendre à développer des programmes simples dans le langage C

Derrière toi Une machine virtuelle!

Le Langage C Version 1.2 c 2002 Florence HENRY Observatoire de Paris Université de Versailles florence.henry@obspm.fr

TP Composants Java ME - Java EE. Le serveur GereCompteBancaireServlet

Programmation impérative

Cours Programmation Système

Le système de gestion des fichiers, les entrées/sorties.

Génération de code binaire pour application multimedia : une approche au vol

I00 Éléments d architecture

Algorithmique et Programmation, IMA

Conventions d écriture et outils de mise au point

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

WEA Un Gérant d'objets Persistants pour des environnements distribués

Java Licence Professionnelle CISII,

Systèmes et traitement parallèles

Table des matières PRESENTATION DU LANGAGE DS2 ET DE SES APPLICATIONS. Introduction

RMI. Remote Method Invocation: permet d'invoquer des méthodes d'objets distants.

Programmation en Java IUT GEII (MC-II1) 1

Institut Supérieure Aux Etudes Technologiques De Nabeul. Département Informatique

Chapitre V : La gestion de la mémoire. Hiérarchie de mémoires Objectifs Méthodes d'allocation Simulation de mémoire virtuelle Le mapping

Cours Langage C/C++ Programmation modulaire

Programmation système en C/C++

Introduction à la programmation orientée objet, illustrée par le langage C++ Patrick Cégielski

IRL : Simulation distribuée pour les systèmes embarqués

Cours de C. Petits secrets du C & programmation avancée. Sébastien Paumier

Gestion de clusters de calcul avec Rocks

Remote Method Invocation Les classes implémentant Serializable

Potentiels de la technologie FPGA dans la conception des systèmes. Avantages des FPGAs pour la conception de systèmes optimisés

Une introduction à Java

Lier Erlang avec d autres langages de programmation

Programmation système de commandes en C

Structure fonctionnelle d un SGBD

Cahier des charges. driver WIFI pour chipset Ralink RT2571W. sur hardware ARM7

Java c est quoi? Java. Java. Java : Principe de fonctionnement 31/01/ Vue générale 2 - Mon premier programme 3 - Types de Programme Java

Introduction à la programmation concurrente

Environnements de développement (intégrés)

PROGRAMMATION PAR OBJETS

Les processus légers : threads. Système L3, /31

Cours 6 : Tubes anonymes et nommés

MODULE I1. Plan. Introduction. Introduction. Historique. Historique avant R&T 1ère année. Sylvain MERCHEZ

Programmation C. J.-F. Lalande. 15 novembre 2012

Transcription:

Introduction au calcul parallèle avec OpenCL Julien Dehos Séminaire du 05/01/2012

Sommaire Introduction Le calculateur du CGR/LISIC/LMPA Généralités sur OpenCL Modèles Programmation Optimisation Conclusion Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 2

Sommaire Introduction Le calculateur du CGR/LISIC/LMPA Généralités sur OpenCL Modèles Programmation Optimisation Conclusion Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 3

Introduction Problématique : Calcul haute performance (HPC) Tendance actuelle : calculs en parallèle Différentes architectures matérielles Différentes technologies logicielles Pas de consensus, évolutions Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 4

Introduction Architectures matérielles : CPU : Plusieurs CPU sur la carte mère Plusieurs cœurs par CPU Plusieurs threads par cœur : hyperthreading Plusieurs données par instructions (SIMD) : SSE, AVX quelques unités de calcul pour des calculs complexes Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 5

Introduction Architectures matérielles : GPU : Plusieurs cartes graphiques Plusieurs GPU par carte graphique Plusieurs cœurs par GPU Cœurs vectoriels (ou pas) nombreuses unités de calcul pour des calculs simples Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 6

Introduction Architectures matérielles : CPU + GPU : Toutes sortes de combinaisons possibles Mais souvent les CPU servent uniquement à contrôler les GPU Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 7

Introduction Architectures matérielles : Comparaisons GPU/CPU : Prendre en compte les temps de transfert GPU Comparer avec une version CPU optimisée "Debunking the 100X GPU vs. CPU Myth: An Evaluation of Throughput Computing on CPU and GPU", Lee et al., ISCA, 2010 Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 8

Introduction Technologies logicielles : CPU : pthread, OpenMP, SSE Shaders GPU : HLSL, GLSL, Cg GPGPU : Brooks, Sh, Cuda, ATI Stream Génériques : MPI, HMPP, OpenCL Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 9

Sommaire Introduction Le calculateur du CGR/LISIC/LMPA Généralités sur OpenCL Modèles Programmation Optimisation Conclusion Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 10

Le calculateur du CGR/LISIC/LMPA Caractéristiques du calculateur : 2 CPU Intel Xeon X5660 144 Go de mémoire vive DDR3 2 disques dur SATA II 500 Go 7200 trs/min 8 cartes Tesla C2050 Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 11

Le calculateur du CGR/LISIC/LMPA Caractéristiques du X5660 : Architecture Gulftown 6 cœurs à 2,8 GHz (soit 12 threads en HT) 12 Mo de cache L3 SSE 4.2 3 Bus DDR3-1333 32 Go/s Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 12

Le calculateur du CGR/LISIC/LMPA Caractéristiques du C2050 : 1 GPU GF100 à 585 MHz 448 thread processors 3 Go de mémoire vive Bus GDDR5 à 144 Go/s MAD (SP) : 1,030 TFLOPs FMA (DP) : 0,515 TFLOPs Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 13

Le calculateur du CGR/LISIC/LMPA Système : Debian 6 "squeeze" NFS (comptes réseaux) 1 disque pour les données de calculs : /data Cuda, pycuda, debugger, profiler, bibliothèques OpenCL, pyopencl NVIDIA_GPU_COMPUTING_SDK c.f. la doc sur le réseau Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 14

Le calculateur du CGR/LISIC/LMPA Accès : baru.univ-littoral.fr 193.49.192.7 ssh depuis le réseau du CGR Penser à utiliser /data Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 15

Le calculateur du CGR/LISIC/LMPA Avant d'exécuter sur le calculateur, il est sage de tester sur votre machine (si possible) Attention à la disponibilité des paquetages OpenCL Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 16

Le calculateur du CGR/LISIC/LMPA Installation automatisée (Archlinux + NVIDIA) : Installer le driver NVIDIA Installer le runtime OpenCL Installer les entêtes OpenCL Installer pyopencl Pacman -S nvidia opencl-nvidia opencl-headers python2-opencl NVIDIA_GPU_COMPUTING_SDK (attention cuda requiert gcc <= 4.4) Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 17

Le calculateur du CGR/LISIC/LMPA Installation manuelle (Debian + NVIDIA) : Installer les linux-headers (via apt-get) Installer le driver NVIDIA Installer Cuda Installer le NVIDIA_GPU_COMPUTING_SDK Récupérer les includes OpenCL (+ cl.hpp) Installer python-setuptools (via apt-get) Installer pyopencl Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 18

Sommaire Introduction Le calculateur du CGR/LISIC/LMPA Généralités sur OpenCL Modèles Programmation Optimisation Conclusion Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 19

Généralités sur OpenCL Historique : Initié par Apple En collaboration avec AMD, IBM, Intel, NVIDIA Puis géré par le Kronos group Version 1.0 (08/12/2008) Version 1.1 (14/06/2010) Version 1.2 (15/11/2011) Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 20

Généralités sur OpenCL Principe : Standard ouvert Framework pour écrire des programmes de calcul parallèle Exécution sur des systèmes hétérogènes Parallélisme de taches et de données Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 21

Généralités sur OpenCL Architectures : UC UAL UAL Cache UAL UAL UC Cache UC Cache UC Cache UC Cache UC Cache UC Cache UAL UAL UAL UAL UAL UAL DRAM DRAM CPU GPU Architecture généraliste Parallélisme massif de données Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 22

Généralités sur OpenCL Mise en œuvre (en théorie) : Installer les drivers matériels Installer le runtime OpenCL Installer le SDK OpenCL Problème (en pratique) : Pour l'instant, pas de cohabitation des runtimes SDK Intel CPU Intel SDK NV GPU NV SDK ATI GPU ATI + CPU Intel/AMD Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 23

Généralités sur OpenCL Avantages de OpenCL : Standard ouvert Systèmes hétérogènes Mécanisme de file d'attente évolué Avantages de Cuda : Haut niveau (cublas, cufft) Mature (debugger, profiler...) Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 24

Sommaire Introduction Le calculateur du CGR/LISIC/LMPA Généralités sur OpenCL Modèles Programmation Optimisation Conclusion Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 25

Modèles Architecture OpenCL Application Kernel OCL API OCL Langage OCL Runtime OCL Driver Device Framework OCL Runtime OCL Driver Device Runtime OCL Driver Device Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 26

Modèles Architecture OpenCL Application Kernel OCL CPU hôte API OCL Langage OCL Runtime OCL Driver Device Framework OCL Runtime OCL Driver Device Runtime OCL Driver Device Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 27

Modèles Architecture OpenCL Baru (actuellement) : Driver NVIDIA 285.05.09 Framework CUDA 4.1.1 OpenCL version 1.1 pyopencl 2011.2 Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 28

Modèles Modèle de plate-forme Host Processing Element (thread processor) Compute Unit (cœur) Compute Device (GPU ou CPU) Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 29

Modèles Modèle de plate-forme Baru : 8 devices (GPU) 14 compute units par device 32 processing elements par compute unit NB : 14x32 = 448 thread processors par device Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 30

Modèles Modèle d'exécution : L'application (host) envoie les kernels sur les devices où ils sont instanciés en work-items Chaque work-item a un identifiant qui lui permet de trouver ses données à utiliser Notions de work-group, nd-range, warp Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 31

Modèles Modèle d'exécution WG WG WG WG WG WG WG WG nd-range Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 32

Modèles Modèle d'exécution Processing Element Compute Unit WG WG WG WG Warp WG WG WG WG Device nd-range Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 33

Modèles Modèle mémoire : Global : accessible à tous les work-items Constant : mémoire globale constante Local : restreinte aux work-items d'un work-group Private : restreinte au work-item Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 34

Modèles Modèle mémoire Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 35

Modèles Modèle mémoire Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 36

Modèles Modèle de programmation : Parallélisme de données : Un même calcul (kernel) est effectué sur des données différentes ( work-items) Souvent : 1 work-item 1 données GPU, CPU Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 37

Modèles Modèle de programmation : Parallélisme de taches : Le kernel est indépendant de l'espace de données Revient à définir un kernel pour un seul work-item CPU Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 38

Sommaire Introduction Le calculateur du CGR/LISIC/LMPA Généralités sur OpenCL Modèles Programmation Optimisation Conclusion Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 39

Programmation SDK OpenCL : Host : API en C ; interfaces C++, java et python Kernel : C99 + built-in functions Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 40

Programmation Références : http://www.khronos.org/opencl/ NVIDIA_GPU_COMPUTING_SDK/OpenCL/doc/ http://mathema.tician.de/software/pyopencl/ Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 41

Programmation Étapes : Écrire le programme host Écrire le kernel Compiler, exécuter NB : le kernel est compilé puis exécuté sur le device à l'exécution du programme host (compilation just-in-time). Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 42

Programmation Programme type : Importer OpenCL Créer un contexte Créer une file de commandes Allouer et initialiser la mémoire du device Charger et compiler le kernel Insérer le kernel dans la file de commandes Récupérer les données dans la mémoire du device Libérer les ressources Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 43

Programmation Application type (parallélisme de données) : Pour i de 0 a 3 : res[i] := f(i) Séquentiel Parallèle res[0] := f(0) res[1] := f(1) buf := kernel_f 0 1 2 3 res[2] := f(2) res := f(0) f(1) f(2) f(3) res[3] := f(3) temps Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 44

Programmation Exemple : Ajouter 42 à tous les éléments d'un tableau de réels Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 45

Programmation Exemple en Python (1) : #!/usr/bin/python import numpy # importer opencl import pyopencl as cl # creer un contexte mycontext = cl.create_some_context() # creer une file de commandes myqueue = cl.commandqueue(mycontext) # allouer et initialiser la memoire du device inputdata = numpy.random.rand(50000).astype(numpy.float32) outputdata = numpy.empty_like(inputdata) myflags = cl.mem_flags inputbuffer = cl.buffer(mycontext, myflags.read_only myflags.copy_host_ptr, hostbuf=inputdata) outputbuffer = cl.buffer(mycontext, myflags.write_only, inputdata.nbytes) Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 46

Programmation Exemple en Python (2) : # charger et compiler le kernel myprogram = cl.program(mycontext, """ kernel void add42( global const float *data, global float *result) { int gid = get_global_id(0); result[gid] = data[gid] + 42.f; } """).build() # ajouter le kernel dans la file de commandes # recuperer les donnees dans la memoire du device myprogram.add42(myqueue, inputdata.shape, None, inputbuffer, outputbuffer) cl.enqueue_copy(myqueue, outputdata, outputbuffer) # verifier le resultat du calcul if abs(numpy.linalg.norm(outputdata (inputdata + 42))) < 1e-6 : print "passed" else: print "failed" Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 47

Programmation Exemple en C (1) : // importer opencl #include <CL/cl.h> #include <math.h> #include <stdio.h> #include <stdlib.h> // initialise les donnees a traiter #define DATA_SIZE 50000 void filldata(float *data, unsigned int size) { int i; for (i=0; i<size; i++) data[i] = i; } // code du kernel const char *kernelsource[] = { " kernel void add42( global float* data, global float* result) {", " unsigned int i = get_global_id(0);", " result[i] = data[i] + 42.f;", "}" }; Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 48

Programmation Exemple en C (2) : int main (int argc, char **argv) { // creer un contexte cl_platform_id platform; clgetplatformids (1, &platform, NULL); cl_device_id device; clgetdeviceids (platform, CL_DEVICE_TYPE_ALL, 1, &device, NULL); cl_context context = clcreatecontext (0, 1, &device, NULL, NULL, NULL); //creer une file de commandes cl_command_queue commandqueue = clcreatecommandqueue(context, device,0,0); // allouer et initialiser la memoire du device float inputdatahost[data_size]; filldata(inputdatahost, DATA_SIZE); cl_mem inputbufferdevice = clcreatebuffer (context, CL_MEM_READ_ONLY CL_MEM_COPY_HOST_PTR, sizeof(float) * DATA_SIZE, inputdatahost, 0); cl_mem outputbufferdevice = clcreatebuffer (context, CL_MEM_WRITE_ONLY, sizeof (float) * DATA_SIZE, 0, 0); Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 49

Programmation Exemple en C (3) : // charger et compiler le kernel cl_program kernelprogram = clcreateprogramwithsource (context, 4, kernelsource, 0, 0); clbuildprogram (kernelprogram, 0, NULL, NULL, NULL, NULL); cl_kernel kernel = clcreatekernel (kernelprogram, "add42", NULL); clsetkernelarg (kernel, 0, sizeof (cl_mem), (void *) &inputbufferdevice); clsetkernelarg (kernel, 1, sizeof (cl_mem), (void *) &outputbufferdevice); // ajouter le kernel dans la file de commandes size_t WorkSize[1] = { DATA_SIZE }; clenqueuendrangekernel (commandqueue, kernel, 1, 0, WorkSize, 0, 0, 0, 0); // recuperer les donnees calculees dans la memoire du device float outputdatahost[data_size]; clenqueuereadbuffer (commandqueue, outputbufferdevice, CL_TRUE, 0, DATA_SIZE * sizeof (float), outputdatahost, 0, NULL, NULL); Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 50

Programmation Exemple en C (4) : // liberer les ressources clreleasekernel (kernel); clreleaseprogram (kernelprogram); clreleasecommandqueue (commandqueue); clreleasememobject (inputbufferdevice); clreleasememobject (outputbufferdevice); clreleasecontext (context); // validation int i; for (i=0; i<data_size; i++) if (fabs((inputdatahost[i] + 42.f) - outputdatahost[i]) > 1e-2) break; if (i == DATA_SIZE) printf ("passed\n"); else printf ("failed\n"); } return 0; Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 51

Programmation Exemple en C++ (1) : // importer opencl #define CL_ENABLE_EXCEPTIONS #include <CL/cl.hpp> #include <iostream> #include <cmath> #define DATA_SIZE 50000 // code du kernel const char kernelsource[] = " kernel void add42( global float* data, global float* result) {"\ " unsigned int i = get_global_id(0);"\ " result[i] = data[i] + 42.f;"\ "}"; int main() { // initialise les donnees a traiter float inputdatahost[data_size]; float outputdatahost[data_size]; for (int i=0; i<data_size; i++) inputdatahost[i] = i; Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 52

Programmation Exemple en C++ (2) : try { // creer un contexte std::vector<cl::platform> platforms; cl::platform::get(&platforms); std::vector<cl::device> devices; platforms[0].getdevices(cl_device_type_all, &devices); cl::context context(devices); // creer une file de commandes cl::commandqueue queue(context, devices[0]); // allouer et initialiser la memoire du device cl::buffer inputbufferdevice(context, CL_MEM_READ_ONLY CL_MEM_COPY_HOST_PTR, sizeof(float) * DATA_SIZE, inputdatahost); cl::buffer outputbufferdevice(context, CL_MEM_WRITE_ONLY, sizeof(float) * DATA_SIZE); Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 53

Programmation Exemple en C++ (3) : // charger et compiler le kernel cl::program::sources source(1, std::make_pair(kernelsource, strlen(kernelsource))); cl::program program = cl::program(context, source); program.build(devices); cl::kernel kernel(program, "add42"); kernel.setarg(0, inputbufferdevice); kernel.setarg(1, outputbufferdevice); // ajouter le kernel dans la file de commandes queue.enqueuendrangekernel(kernel, cl::nullrange, cl::ndrange(data_size), cl::nullrange); } // recuperer les donnees calculees dans la memoire du device queue.enqueuereadbuffer(outputbufferdevice, CL_TRUE, 0, DATA_SIZE * sizeof (float), outputdatahost); Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 54

Programmation Exemple en C++ (4) : catch (cl::error err) { std::cerr << "ERROR: " << err.what() << "(" << err.err() << ")\n"; } } // validation for (int i=0; i<data_size; i++) if (fabs((inputdatahost[i] + 42.f) - outputdatahost[i]) > 1e-2) { printf ("failed\n"); return EXIT_FAILURE; } printf ("passed\n"); return EXIT_SUCCESS; Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 55

Programmation Exemple en C++ (5) : Avantages par rapport à l'interface C : (Hiérarchie de classes) Syntaxe un peu plus légère Mécanisme d'exceptions Libération automatique des ressources Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 56

Programmation Synchronisation : Principe du calcul parallèle : L'utilisateur envoie des requêtes (calculs, transferts mémoire) Le système calcule en parallèle en maximisant l'utilisation des unités de calculs (plus de calculs en parallèle = temps de calcul total plus court) Cohérence, synchronisation Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 57

Programmation Synchronisation : Command queue : File de commandes (calculs, transferts, barrières de synchronisation) Plusieurs files possibles File in-order ou out-of-order (pour le lancement des commandes) Event : Événement associé à une commande Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 58

Programmation Synchronisation : Mécanismes de synchronisation (par granularité decroissante) : clfinish (le host attend la fin de la file) clwaitforevent (le host attend la fin d'une commande) clenqueuebarrier (le device attend la fin des commandes antérieures) clenqueuewaitforevents (le device attend la fin d'une commande) Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 59

Programmation Objets mémoire : Types d'objet : Buffer 1D Image 2D ou 3D Types de données : Scalaire Vectoriel Structure définie par l'utilisateur Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 60

Programmation Transferts mémoire : Coûteux Lors de l'allocation ou via la file de commandes Bloquants ou non-bloquants Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 61

Sommaire Introduction Le calculateur du CGR/LISIC/LMPA Généralités sur OpenCL Modèles Programmation Optimisation Conclusion Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 62

Optimisation Références (SDK NVIDIA) : NVIDIA OpenCL Best Practices NVIDIA OpenCL Programming Guide for the CUDA Architecture Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 63

Optimisation Généralités : Méthode générale : Valider l'implémentation Mesurer/profiler l'exécution Si nécessaire, optimiser les sections de code coûteuses Boucler Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 64

Optimisation Généralités : OpenCL : Le code est portable (presque) Mais pas les performances Quelques principes généraux Spécificités bas niveau Remarques sur les GPU actuels : ATI : unités vectorielles, accès mémoire par blocs NV : unités scalaires, accès mémoire coalescents Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 65

Optimisation Quelques pistes : Divergence : i.e. part d'unités de calcul inoccupées à minimiser : Utiliser plusieurs files Files out-of-order Anticiper les accès/transferts mémoire... Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 66

Optimisation Quelques pistes : Tailles des work-groups : Doivent être un multiple de la taille du warp Influencent beaucoup l'efficacité des GPU Dépendent du matériel Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 67

Optimisation Quelques pistes : Mémoire "local" : Accès global = environ 600 cycles Accès local = environ 4 cycles Mais local au work-group Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 68

Optimisation Quelques pistes : Coalescing : Accès contigu à la mémoire Souvent plus rapide (moins de translations d'adresse) NDRange Mémoire "global" Accès coalescent Accès non-coalescent Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 69

Optimisation Quelques pistes : Unrolling Pipelining Vectorisation... Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 70

Optimisation Exemple : Multiplication de matrices Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 71

Sommaire Introduction Le calculateur du CGR/LISIC/LMPA Généralités sur OpenCL Modèles Programmation Optimisation Conclusion Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 72

Conclusion OpenCL : Standard ouvert pour le calcul parallèle Systèmes de calcul hétérogènes Mécanismes intéressants (command queue) Mais : En maturation (API, runtime, outils) Pas de portabilité des performances Effort d'apprentissage (OpenCL, matériel) Intégration propre dans un projet? Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 73

Conclusion Remarques : À long terme : parallélisme Actuellement GPU intéressant Choix Cuda/OpenCL : Technologies très proches Effort d'apprentissage Évolution vers du CPU massif? Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 74

Séminaire LISIC du 05/01/2012 Introduction au calcul parallèle avec OpenCL 75