Vous êtes sur la page 1sur 75

Introduction au calcul parallle

avec OpenCL
Julien Dehos

Sminaire du 05/01/2012

Sommaire

Introduction

Le calculateur du CGR/LISIC/LMPA

Gnralits sur OpenCL

Modles

Programmation

Optimisation

Conclusion

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

Sommaire

Introduction

Le calculateur du CGR/LISIC/LMPA

Gnralits sur OpenCL

Modles

Programmation

Optimisation

Conclusion

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

Introduction

Problmatique :

Calcul haute performance (HPC)

Tendance actuelle : calculs en parallle

Diffrentes architectures matrielles

Diffrentes technologies logicielles

Pas de consensus, volutions

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

Introduction

Architectures matrielles :

CPU :

Plusieurs CPU sur la carte mre


Plusieurs curs par CPU
Plusieurs threads par cur : hyperthreading
Plusieurs donnes par instructions (SIMD) : SSE, AVX

quelques units de calcul


pour des calculs complexes
Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

Introduction

Architectures matrielles :

GPU :

Plusieurs cartes graphiques


Plusieurs GPU par carte graphique
Plusieurs curs par GPU
Curs vectoriels (ou pas)

nombreuses units de calcul


pour des calculs simples
Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

Introduction

Architectures matrielles :

CPU + GPU :

Toutes sortes de combinaisons possibles


Mais souvent les CPU servent uniquement
contrler les GPU

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

Introduction

Architectures matrielles :

Comparaisons GPU/CPU :

Prendre en compte les temps de transfert GPU


Comparer avec une version CPU optimise

"Debunking the 100X GPU vs. CPU Myth: An


Evaluation of Throughput Computing on CPU and
GPU", Lee et al., ISCA, 2010

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

Introduction

Technologies logicielles :

CPU : pthread, OpenMP, SSE

Shaders GPU : HLSL, GLSL, Cg

GPGPU : Brooks, Sh, Cuda, ATI Stream

Gnriques : MPI, HMPP, OpenCL

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

Sommaire

Introduction

Le calculateur du CGR/LISIC/LMPA

Gnralits sur OpenCL

Modles

Programmation

Optimisation

Conclusion

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

10

Le calculateur du CGR/LISIC/LMPA

Caractristiques du calculateur :

2 CPU Intel Xeon X5660

144 Go de mmoire vive DDR3

2 disques dur SATA II 500 Go 7200 trs/min

8 cartes Tesla C2050

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

11

Le calculateur du CGR/LISIC/LMPA

Caractristiques du X5660 :

Architecture Gulftown

6 curs 2,8 GHz (soit 12 threads en HT)

12 Mo de cache L3

SSE 4.2

3 Bus DDR3-1333 32 Go/s

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

12

Le calculateur du CGR/LISIC/LMPA

Caractristiques du C2050 :

1 GPU GF100 585 MHz

448 thread processors

3 Go de mmoire vive

Bus GDDR5 144 Go/s

MAD (SP) : 1,030 TFLOPs

FMA (DP) : 0,515 TFLOPs

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

13

Le calculateur du CGR/LISIC/LMPA

Systme :

Debian 6 "squeeze"

NFS (comptes rseaux)

1 disque pour les donnes de calculs : /data

Cuda, pycuda, debugger, profiler, bibliothques

OpenCL, pyopencl

NVIDIA_GPU_COMPUTING_SDK

c.f. la doc sur le rseau


Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

14

Le calculateur du CGR/LISIC/LMPA

Accs :

baru.univ-littoral.fr

193.49.192.7

ssh depuis le rseau du CGR

Penser utiliser /data

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

15

Le calculateur du CGR/LISIC/LMPA

Avant d'excuter sur le calculateur, il est sage


de tester sur votre machine (si possible)
Attention la disponibilit des paquetages
OpenCL

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

16

Le calculateur du CGR/LISIC/LMPA

Installation automatise (Archlinux + NVIDIA) :

Installer le driver NVIDIA

Installer le runtime OpenCL

Installer les enttes OpenCL

Installer pyopencl

Pacman

-S nvidia opencl-nvidia opencl-headers python2-opencl

NVIDIA_GPU_COMPUTING_SDK (attention cuda


requiert gcc <= 4.4)

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle 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

Rcuprer les includes OpenCL (+ cl.hpp)

Installer python-setuptools (via apt-get)

Installer pyopencl

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

18

Sommaire

Introduction

Le calculateur du CGR/LISIC/LMPA

Gnralits sur OpenCL

Modles

Programmation

Optimisation

Conclusion

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

19

Gnralits sur OpenCL

Historique :

Initi par Apple

En collaboration avec AMD, IBM, Intel, NVIDIA

Puis gr par le Kronos group

Version 1.0 (08/12/2008)

Version 1.1 (14/06/2010)

Version 1.2 (15/11/2011)

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

20

Gnralits sur OpenCL

Principe :

Standard ouvert
Framework pour crire des programmes
de calcul parallle

Excution sur des systmes htrognes

Paralllisme de taches et de donnes

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

21

Gnralits sur OpenCL

Architectures :
UAL

UAL

UC
UAL

UAL

Cache

UC
Cache
UC
Cache
UC
Cache
UC
Cache
UC
Cache
UC
Cache

UAL
UAL
UAL
UAL
UAL
UAL

DRAM

DRAM

CPU

GPU

Architecture gnraliste
Sminaire LISIC du 05/01/2012

Paralllisme massif de donnes

Introduction au calcul parallle avec OpenCL

22

Gnralits sur OpenCL

Mise en uvre (en thorie) :

Installer les drivers matriels

Installer le runtime OpenCL

Installer le SDK OpenCL

Problme (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

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

23

Gnralits sur OpenCL

Avantages de OpenCL :

Standard ouvert

Systmes htrognes

Mcanisme de file d'attente volu

Avantages de Cuda :

Haut niveau (cuBLAS, cuFFT)

Mature (debugger, profiler...)

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

24

Sommaire

Introduction

Le calculateur du CGR/LISIC/LMPA

Gnralits sur OpenCL

Modles

Programmation

Optimisation

Conclusion

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

25

Modles

Architecture OpenCL
Application
Kernel OCL
API OCL

Langage OCL

Framework OCL
Runtime OCL

Runtime OCL

Runtime OCL

Driver

Driver

Driver

Device

Device

Device

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

26

Modles

Architecture OpenCL

CPU hte

Application
Kernel OCL
API OCL

Langage OCL

Framework OCL
Runtime OCL

Runtime OCL

Runtime OCL

Driver

Driver

Driver

Device

Device

Device

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

27

Modles

Architecture OpenCL

Baru (actuellement) :

Driver NVIDIA 285.05.09


Framework CUDA 4.1.1
OpenCL version 1.1
pyopencl 2011.2

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

28

Modles

Modle de plate-forme

Host

Processing Element
(thread processor)
Sminaire LISIC du 05/01/2012

Compute Unit
(cur)

Compute Device
(GPU ou CPU)

Introduction au calcul parallle avec OpenCL

29

Modles

Modle 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

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

30

Modles

Modle d'excution :

L'application (host) envoie les kernels sur les


devices o ils sont instancis en work-items
Chaque work-item a un identifiant qui lui permet de
trouver ses donnes utiliser
Notions de work-group, nD-range, warp

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

31

Modles

Modle d'excution
WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WG

WG

WG

WG

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WG

WG

WG

WG

nD-range
Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

32

Modles

Modle d'excution

Processing
Element
Compute
Unit
Warp

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WG

WG

WG

WG

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WI

WG
Device
Sminaire LISIC du 05/01/2012

WG

WG

WG

nD-range
Introduction au calcul parallle avec OpenCL

33

Modles

Modle mmoire :

Global : accessible tous les work-items

Constant : mmoire globale constante

Local : restreinte aux work-items d'un work-group

Private : restreinte au work-item

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

34

Modles

Modle mmoire

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

35

Modles

Modle mmoire

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

36

Modles

Modle de programmation :

Paralllisme de donnes :

Un mme calcul (kernel) est effectu sur des donnes


diffrentes ( work-items)
Souvent : 1 work-item 1 donnes

GPU, CPU

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

37

Modles

Modle de programmation :

Paralllisme de taches :

Le kernel est indpendant de l'espace de donnes


Revient dfinir un kernel pour un seul work-item

CPU

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

38

Sommaire

Introduction

Le calculateur du CGR/LISIC/LMPA

Gnralits sur OpenCL

Modles

Programmation

Optimisation

Conclusion

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

39

Programmation

SDK OpenCL :

Host : API en C ; interfaces C++, java et python

Kernel : C99 + built-in functions

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

40

Programmation

Rfrences :

http://www.khronos.org/opencl/

NVIDIA_GPU_COMPUTING_SDK/OpenCL/doc/

http://mathema.tician.de/software/pyopencl/

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

41

Programmation

tapes :

crire le programme host

crire le kernel

Compiler, excuter

NB : le kernel est compil puis excut sur le


device l'excution du programme host
(compilation just-in-time).

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

42

Programmation

Programme type :

Importer OpenCL

Crer un contexte

Crer une file de commandes

Allouer et initialiser la mmoire du device

Charger et compiler le kernel

Insrer le kernel dans la file de commandes

Rcuprer les donnes dans la mmoire du device

Librer les ressources

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

43

Programmation

Application type (paralllisme de donnes) :


Pour i de 0 a 3 :
res[i] := f(i)
Squentiel

Parallle

res[0] := f(0)

buf :=

res[1] := f(1)

kernel_f

res[2] := f(2)

res :=

f(0) f(1) f(2) f(3)

res[3] := f(3)
temps
Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

44

Programmation

Exemple :

Ajouter 42 tous les lments d'un tableau de rels

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle 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)

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle 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"

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle 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;",
"}"
};

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle 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);

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle 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);

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle 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;

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle 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;

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle 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);

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle 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);
}

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle 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;
}

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

55

Programmation

Exemple en C++ (5) :

Avantages par rapport l'interface C :

(Hirarchie de classes)
Syntaxe un peu plus lgre
Mcanisme d'exceptions
Libration automatique des ressources

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

56

Programmation

Synchronisation :

Principe du calcul parallle :

L'utilisateur envoie des requtes (calculs, transferts


mmoire)
Le systme calcule en parallle en maximisant
l'utilisation des units de calculs (plus de calculs en
parallle = temps de calcul total plus court)
Cohrence, synchronisation

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

57

Programmation

Synchronisation :

Command queue :

File de commandes (calculs, transferts, barrires de


synchronisation)
Plusieurs files possibles
File in-order ou out-of-order (pour le lancement des
commandes)

Event :

vnement associ une commande

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

58

Programmation

Synchronisation :

Mcanismes 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
antrieures)
clEnqueueWaitForEvents (le device attend la fin d'une
commande)

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

59

Programmation

Objets mmoire :

Types d'objet :

Buffer 1D
Image 2D ou 3D

Types de donnes :

Scalaire
Vectoriel
Structure dfinie par l'utilisateur

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

60

Programmation

Transferts mmoire :

Coteux

Lors de l'allocation ou via la file de commandes

Bloquants ou non-bloquants

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

61

Sommaire

Introduction

Le calculateur du CGR/LISIC/LMPA

Gnralits sur OpenCL

Modles

Programmation

Optimisation

Conclusion

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

62

Optimisation

Rfrences (SDK NVIDIA) :

NVIDIA OpenCL Best Practices


NVIDIA OpenCL Programming Guide for the CUDA
Architecture

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

63

Optimisation

Gnralits :

Mthode gnrale :

Valider l'implmentation
Mesurer/profiler l'excution
Si ncessaire, optimiser les sections de code coteuses
Boucler

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

64

Optimisation

Gnralits :

OpenCL :

Le code est portable (presque)


Mais pas les performances
Quelques principes gnraux
Spcificits bas niveau

Remarques sur les GPU actuels :

ATI : units vectorielles, accs mmoire par blocs


NV : units scalaires, accs mmoire coalescents

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

65

Optimisation

Quelques pistes :

Divergence :

i.e. part d'units de calcul inoccupes


minimiser :

Utiliser plusieurs files


Files out-of-order
Anticiper les accs/transferts mmoire
...

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle 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
Dpendent du matriel

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

67

Optimisation

Quelques pistes :

Mmoire "local" :

Accs global = environ 600 cycles


Accs local = environ 4 cycles
Mais local au work-group

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

68

Optimisation

Quelques pistes :

Coalescing :

WI

Accs contigu la mmoire


Souvent plus rapide (moins de translations d'adresse)

WI

WI

WI

NDRange

WI

WI

WI

WI

Mmoire "global"
Accs coalescent
Sminaire LISIC du 05/01/2012

Accs non-coalescent
Introduction au calcul parallle avec OpenCL

69

Optimisation

Quelques pistes :

Unrolling

Pipelining

Vectorisation

...

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

70

Optimisation

Exemple :

Multiplication de matrices

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

71

Sommaire

Introduction

Le calculateur du CGR/LISIC/LMPA

Gnralits sur OpenCL

Modles

Programmation

Optimisation

Conclusion

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

72

Conclusion

OpenCL :

Standard ouvert pour le calcul parallle

Systmes de calcul htrognes

Mcanismes intressants (command queue)

Mais :

En maturation (API, runtime, outils)


Pas de portabilit des performances
Effort d'apprentissage (OpenCL, matriel)
Intgration propre dans un projet ?

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

73

Conclusion

Remarques :

long terme : paralllisme

Actuellement GPU intressant

Choix Cuda/OpenCL :

Technologies trs proches


Effort d'apprentissage

volution vers du CPU massif ?

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

74

Sminaire LISIC du 05/01/2012

Introduction au calcul parallle avec OpenCL

75