SlideShare une entreprise Scribd logo
GPGPU facile avec JavaCL...
 ... et trivial avec ScalaCL
          by Olivier Chafik
             @ochafik




                               1
Monstres de puissance




                        2
Répartition inéquitable


•



                              3
Mettons les GPUs au travail !


•   Concepts de base d’OpenCL

•   JavaCL en quelques lignes de code

•   Pour les paresseux et les pressés : ScalaCL




                                                  4
Speaker

Olivier Chafik (@ochafik)

•Développeur C++ / Java (3D, finance)
•Hobby = interopérabilité
 • JNAerator, BridJ : des bindings en 1 minute-chrono
 • JavaCL, ScalaCL
                                                        5
OpenCL
             =
OpenGL pour calculs généralistes


                                   6
OpenCL
              =
environnement d’exécution
      multi-plateforme

                            7
Pourquoi OpenCL ?

•   Puissance gratuite (x10 à x100)

•   Standard multi-vendeur, CPU + GPU

•   Close-to-metal : parallélisme boucles + SIMD
    Pousse les multi-coeurs à bout !

•   Interaction DirectX / OpenGL



                                                   8
Charge utile d’OpenCL


•   Task : appel unique

•   Kernel : appels massivement parallèles N-dimensions




                                                          9
Orienté événement

•   Opérations asynchrones & enchaînables

•   Renvoient events, en attendre d’autres

    Écriture buffer  Exec 1  Exec 2  Lecture buffer

•   Files d’exécutions attachées à un device



                                                         10
Exemple de boucle C
Calcul de sinus & cosinus en boucle 

void scos(
    const double* params,
    double* out,
    int length
){
    for (int i = 0; i < length; i++)
    {
        double param = params[i];
        out[2 * i] = sin(param);
        out[2 * i + 1] = cos(param);
    }
}




                                                 11
Kernel OpenCL équivalent
Calcul de sinus & cosinus parallèle (simplifié)

#pragma OpenCL EXTENSION cl_khr_fp64 : enable
kernel void scos(
    global const double* params,
    global double2* out,
    int length
){
    int i = get_global_id(0); // indice parallèle
    if (i >= length) return; // dépassements possibles
    {
        double param = params[i];
        double c, s = sincos(param, &c); // calcul sin & cos rapide
        out[i] = (double2)(s, c);
    }
}


                                                                      12
Kernels

•   Dialecte du C

•   Fonctions math vectorielles (SIMD sur float4, int8…)

•   Code connait sa position d’exécution

•   Lecture / écriture buffers / images

•   Synchronisation avec voisins (working group)


                                                           13
Code hôte
•   Choix devices + création contexte

•   Création file d’exécution

•   Compilation kernels

•   Allocation buffers / images

•   Scheduling des exécutions

•   Lecture / écriture buffers

                                        14
JavaCL (BSD)

•   1ers bindings OpenCL

•   API orientée-objet

•   Maven Central (jar unique)

•   Communauté active



                                        15
Démo
Hello World




              16
Sous le capot…
OpenCL bindings générés par JNAerator :




BridJ fournit la “colle” à l’exécution


                                          17
Plus que des bindings

•   Gestion mémoire débrayable

•   Cache automatique des binaires

•   Inclusion depuis URLs

•   Générateur de wrappers typés

•   Parallel Reduction (min, max, sum, product)


                                                  18
Plus que des bindings (2)
• FFT complexe d'un tableau de primitives :
 DoubleFFTPow2 fft = new DoubleFFTPow2();
 double[] transformed = fft.transform(data);


• Chargement (+ conversion) d'une image :
 CLImage2D img = context.createImage2D(Usage.Input, ImageIO.read(file));


• Multiplication de matrices UJMP :
 Matrix a = new CLDenseFloatMatrix2D(n, m),
 Matrix b = new CLDenseFloatMatrix2D(m, q);
 Matrix c = a.times(b);



                                                                           19
Démo
Interactive Image Editor




                           20
Les pièges d’OpenCL

•   Coût des transferts RAM / GPU

•   Contextes mixtes CPU / GPU :
    seulement sur APU AMD

•   Branchements conditionnels lents sur GPU

•   Besoin de tests d’arrêt



                                               21
Encore des pièges


•   Peu de formats d’image garantis

•   Endianness parfois différente entre hôte & device

•   Apple ne supporte qu’OpenCL 1.0




                                                        22
Chasse à la performance sur GPU


•   Groupes d’exécution : memoire locale, barrières…

•   Répartition de charge multi-GPU

•   Exécutions pyramidales pour réductions associatives




                                                          23
JavaCL 1.0.0-RC2

•   32 & 64 bits / Windows, Linux, MacOS X

•   NVIDIA, AMD, Intel & Apple

•   OpenCL 1.0 / 1.1
    (1.2 peu répandu)




                                             24
Rendre OpenCL plus facile ?

•   Éviter d’écrire les kernels en C

•   Cacher l’asynchronicité

•   Accepter performance sub-optimale
    (> 10x plus rapide que Java)




                                        25
OpenCL “traduit”

•   Apapapi (AMD)

    •   Java

    •   Cache beaucoup (trop ?) de détails

•   ScalaCL (votre serviteur)



                                             26
ScalaCL


•   Collections Scala asynchrones

•   Stockage + Opérations OpenCL (map, filter, sum…)

•   Traduction Scala / OpenCL




                                                       27
Qu'est-ce que Scala ?

•   Saint-Graal des langages (impératif, fonctionnel, objet…)

•   Tuples + Collections mutables / immutables

•   Syntaxe familière

•   JVM



                                                                28
Quelques lignes de Scala…

val intervalle = (0 until 100000)

val cosSinCol = intervalle.map(i => {
   val f = 0.2
   (cos(i * f), sin(i * f))
})

val sum = cosSinCol.map({ case (c, s) => c * s }).sum


                                                        29
Les mêmes lignes sur GPU
import scalacl._
implicit val context = Context.best(DoubleSupport)
val intervalle = (0 until 100000).cl

val cosSinCol = intervalle.map(i => {
   val f = 0.2
   (cos(i * f), sin(i * f))
})

val sum = cosSinCol.map({ case (c, s) => c * s }).sum


                                                        30
Démo
Console GPU




              31
Comment ça marche
•   Conversion fonctions Scala => code OpenCL

•   3 collections

    •   CLRange : intervalle

    •   CLArray : tableau de tuploïdes

    •   CLFilteredArray : tableau filtré, compactable en parallèle


                                                                     32
Des collections asynchrones


•   Contrainte : les collections Scala ont l’air synchrones

•   Principe : single writer, multiple reader




                                                              33
Des collections asynchrones

val tab = Array(1, 2, 3, 4).cl

val resultat = tab.map(x => x * 2).map(x – 5)

// resultat pas encore calculé

resultat(i) = 10 // attente avant écriture



                                                34
Traduire Scala en OpenCL ?




                             35
Traduire Scala en OpenCL ?

•   Limitations (pas de classes)

•   Élimination des tuples

•   Élimination du code “objet”




                                      36
Ceci est du code objet
for (i <- 0 until 100)
{
    …
}


                                  37
Une lambda peut en cacher une autre
(0 until 100).foreach(i =>
{
     …
})


                                      38
Des boucles 5x plus rapides
(0 until 100).foreach(i =>   var i = 0
{                            while (i < 100) {
     …                           …
})                           }


                                                 39
Aller plus vite : flot d’opérations

col.map(f).filter(g).map(h).reduceLeft(i)

•Collections intermédiaires + lambdas
•f, g, h sans effet de bord ?

                                            40
ScalaCL : encore un prototype
• Scalaxy : spin-off généraliste plutôt stable
• Fonctionalités expérimentales :
  captures, random, reduce

• Macros Scala 2.10
                                                 41
OpenCL
• Votre GPU se tourne les pouces
• Write once, run (almost) everywhere
         http://javacl.googlecode.com
         http://scalacl.googlecode.com


                                         42
Questions



            43
44
CLFilteredArray[T]
•   Tableau de valeurs + Bitmap de présence

•   Compactage :

    •   Somme préfixée

    •   Recopie aux incréments

•   Exemple : filtrage pairs
    f: x => ((x % 2) == 0)

                                              45
JavaCL : générateur de code
LinearAlgebraKernels.cl :




LinearAlgebraKernels.java :




                                     46
JavaCL : hôte minimaliste
• Choix d'un contexte + file d'exécution :
  CLContext context = JavaCL.createBestContext(DoubleSupport);
  CLQueue queue = context.createDefaultQueue();

• Création de tableaux :
  DoubleBuffer values = ...;
  CLDoubleBuffer params = context.createDoubleBuffer(Usage.Input, values);

• Compilation=du programme :
  CLKernel scos context.createProgram(src).createKernel("scos");

• Exécution parallèle : length);
  scos.setArgs(params, out,
  CLEvent evt = scos.enqueueNDRange(queue, new int[] { length });




                                                                             47

Contenu connexe

PPTX
Présentation Javascript à l'ESI (Alger)
KEY
Introduction à MacRuby
KEY
Introduction à MacRuby - OSDC.fr 2009
PPTX
Rouabhi algiers meetup
PPTX
Présentation de ECMAScript 6
PPTX
The Future of Javascript
PDF
Javascript les générateurs (generators)
PPTX
Introduction au lock-free programming avec std::atomics
Présentation Javascript à l'ESI (Alger)
Introduction à MacRuby
Introduction à MacRuby - OSDC.fr 2009
Rouabhi algiers meetup
Présentation de ECMAScript 6
The Future of Javascript
Javascript les générateurs (generators)
Introduction au lock-free programming avec std::atomics

Tendances (19)

PDF
Enib cours c.a.i. web - séance #5 : scala play! framework
PDF
Cours JavaScript
KEY
Présentation LMAX Disruptor So@t
PDF
Les fonctions lambdas en C++11 et C++14
PPT
Programmation sur GPU avec CUDA
PPTX
Java - Support etudiant - Tronc Commun Deuxième année ISIMA - 2018
PPTX
Javascript un langage supérieur
PPTX
Change mind about JS
PPTX
Présentation JavaScript
PPTX
Nouveautés JavaScript dans le monde Microsoft
PDF
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
PPTX
Les secrets de la JVM pour les algos à haute fréquence
PDF
I le langage java d'una manière avancée introduction
PPTX
Cours de C++ / Tronc commun deuxième année ISIMA
PDF
Introduction à scala
PPTX
Javascript proprement
PPTX
Nouveautés de java 8
PPTX
Barbie explique IEEE754 : pourquoi les calculs informatiques sont faux?
Enib cours c.a.i. web - séance #5 : scala play! framework
Cours JavaScript
Présentation LMAX Disruptor So@t
Les fonctions lambdas en C++11 et C++14
Programmation sur GPU avec CUDA
Java - Support etudiant - Tronc Commun Deuxième année ISIMA - 2018
Javascript un langage supérieur
Change mind about JS
Présentation JavaScript
Nouveautés JavaScript dans le monde Microsoft
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
Les secrets de la JVM pour les algos à haute fréquence
I le langage java d'una manière avancée introduction
Cours de C++ / Tronc commun deuxième année ISIMA
Introduction à scala
Javascript proprement
Nouveautés de java 8
Barbie explique IEEE754 : pourquoi les calculs informatiques sont faux?
Publicité

En vedette (18)

ODP
Linea Del Tiempo De La Computacion
PDF
ObserveIt Produit Information
PDF
Green IT BB Award 2012 - Megware
PDF
Green IT BB Award 2012 - Megware (2)
PDF
AMD Business-2013
PPT
La playsation 4
PDF
Dallenbach Amd Jenkis 1924 Forgrtting In Ltm
PDF
Tipps & Tricks für den erfolgreichen Einsatz von GPU-Computing
PPT
Amd education citoyenné_oejaj
PPT
Techdays 2009 - La virtualisation de machines avec Hyper-V
PPT
Banking in the us
PPTX
Whats New in AMD - 2015
PDF
An Introduction to OpenCL™ Programming with AMD GPUs - AMD & Acceleware Webinar
PDF
Amd Ryzen December 2016 Update
PDF
Open compute technology
 
PDF
AMD Analyst Day 2009: Rick Bergman
 
PDF
AMD CFO Commentary slides 14Q4
PPTX
Case study Of $2500 TATA NANO
Linea Del Tiempo De La Computacion
ObserveIt Produit Information
Green IT BB Award 2012 - Megware
Green IT BB Award 2012 - Megware (2)
AMD Business-2013
La playsation 4
Dallenbach Amd Jenkis 1924 Forgrtting In Ltm
Tipps & Tricks für den erfolgreichen Einsatz von GPU-Computing
Amd education citoyenné_oejaj
Techdays 2009 - La virtualisation de machines avec Hyper-V
Banking in the us
Whats New in AMD - 2015
An Introduction to OpenCL™ Programming with AMD GPUs - AMD & Acceleware Webinar
Amd Ryzen December 2016 Update
Open compute technology
 
AMD Analyst Day 2009: Rick Bergman
 
AMD CFO Commentary slides 14Q4
Case study Of $2500 TATA NANO
Publicité

Similaire à GPGPU facile avec JavaCL, et trivial avec ScalaCL ! (20)

PPTX
La programmation GPU avec C++ AMP pour les performances extrêmes
PPTX
Cassandra pour les développeurs java
PPTX
Java SE 7
PDF
Seren
PPT
Agl2012
PDF
Algo vol.2 sujets
PDF
soft-shake.ch - Clojure Values
PDF
Jug gpgpu
PPT
Chapitre 1 (algorithme)
PDF
Opencl In Action How To Accelerate Graphics And Computations Matthew Scarpino
PDF
OWF12/PAUG Conf Days Render script, sylvain galand, software engineer at geny...
PDF
JAVA Chapitre4
PPTX
.NET Microframework: du code, de l&rsquo;électronique, de la robotique
PPTX
.NET Microframework, les joies de l'électronique et du code pour tous
PPTX
Vivre en parallèle - Softshake 2013
PPTX
Softshake 2013 - Vivre en parallèle
PPTX
Du hard et des réseaux: Les outils pour construire l'internet des objets chez...
PDF
Mix it 2011 - Clojure
PPTX
Les nouveautés de C++11 : Ecrire du C++ Moderne
PPTX
Introduction Clojure - Geneva JUG - Octobre 2012
La programmation GPU avec C++ AMP pour les performances extrêmes
Cassandra pour les développeurs java
Java SE 7
Seren
Agl2012
Algo vol.2 sujets
soft-shake.ch - Clojure Values
Jug gpgpu
Chapitre 1 (algorithme)
Opencl In Action How To Accelerate Graphics And Computations Matthew Scarpino
OWF12/PAUG Conf Days Render script, sylvain galand, software engineer at geny...
JAVA Chapitre4
.NET Microframework: du code, de l&rsquo;électronique, de la robotique
.NET Microframework, les joies de l'électronique et du code pour tous
Vivre en parallèle - Softshake 2013
Softshake 2013 - Vivre en parallèle
Du hard et des réseaux: Les outils pour construire l'internet des objets chez...
Mix it 2011 - Clojure
Les nouveautés de C++11 : Ecrire du C++ Moderne
Introduction Clojure - Geneva JUG - Octobre 2012

GPGPU facile avec JavaCL, et trivial avec ScalaCL !

  • 1. GPGPU facile avec JavaCL... ... et trivial avec ScalaCL by Olivier Chafik @ochafik 1
  • 4. Mettons les GPUs au travail ! • Concepts de base d’OpenCL • JavaCL en quelques lignes de code • Pour les paresseux et les pressés : ScalaCL 4
  • 5. Speaker Olivier Chafik (@ochafik) •Développeur C++ / Java (3D, finance) •Hobby = interopérabilité • JNAerator, BridJ : des bindings en 1 minute-chrono • JavaCL, ScalaCL 5
  • 6. OpenCL = OpenGL pour calculs généralistes 6
  • 7. OpenCL = environnement d’exécution multi-plateforme 7
  • 8. Pourquoi OpenCL ? • Puissance gratuite (x10 à x100) • Standard multi-vendeur, CPU + GPU • Close-to-metal : parallélisme boucles + SIMD Pousse les multi-coeurs à bout ! • Interaction DirectX / OpenGL 8
  • 9. Charge utile d’OpenCL • Task : appel unique • Kernel : appels massivement parallèles N-dimensions 9
  • 10. Orienté événement • Opérations asynchrones & enchaînables • Renvoient events, en attendre d’autres Écriture buffer  Exec 1  Exec 2  Lecture buffer • Files d’exécutions attachées à un device 10
  • 11. Exemple de boucle C Calcul de sinus & cosinus en boucle  void scos(     const double* params,     double* out,     int length ){     for (int i = 0; i < length; i++)     {         double param = params[i];         out[2 * i] = sin(param);         out[2 * i + 1] = cos(param);     } } 11
  • 12. Kernel OpenCL équivalent Calcul de sinus & cosinus parallèle (simplifié) #pragma OpenCL EXTENSION cl_khr_fp64 : enable kernel void scos(     global const double* params,     global double2* out,     int length ){     int i = get_global_id(0); // indice parallèle     if (i >= length) return; // dépassements possibles     {         double param = params[i];         double c, s = sincos(param, &c); // calcul sin & cos rapide         out[i] = (double2)(s, c);     } } 12
  • 13. Kernels • Dialecte du C • Fonctions math vectorielles (SIMD sur float4, int8…) • Code connait sa position d’exécution • Lecture / écriture buffers / images • Synchronisation avec voisins (working group) 13
  • 14. Code hôte • Choix devices + création contexte • Création file d’exécution • Compilation kernels • Allocation buffers / images • Scheduling des exécutions • Lecture / écriture buffers 14
  • 15. JavaCL (BSD) • 1ers bindings OpenCL • API orientée-objet • Maven Central (jar unique) • Communauté active 15
  • 17. Sous le capot… OpenCL bindings générés par JNAerator : BridJ fournit la “colle” à l’exécution 17
  • 18. Plus que des bindings • Gestion mémoire débrayable • Cache automatique des binaires • Inclusion depuis URLs • Générateur de wrappers typés • Parallel Reduction (min, max, sum, product) 18
  • 19. Plus que des bindings (2) • FFT complexe d'un tableau de primitives : DoubleFFTPow2 fft = new DoubleFFTPow2(); double[] transformed = fft.transform(data); • Chargement (+ conversion) d'une image : CLImage2D img = context.createImage2D(Usage.Input, ImageIO.read(file)); • Multiplication de matrices UJMP : Matrix a = new CLDenseFloatMatrix2D(n, m), Matrix b = new CLDenseFloatMatrix2D(m, q); Matrix c = a.times(b); 19
  • 21. Les pièges d’OpenCL • Coût des transferts RAM / GPU • Contextes mixtes CPU / GPU : seulement sur APU AMD • Branchements conditionnels lents sur GPU • Besoin de tests d’arrêt 21
  • 22. Encore des pièges • Peu de formats d’image garantis • Endianness parfois différente entre hôte & device • Apple ne supporte qu’OpenCL 1.0 22
  • 23. Chasse à la performance sur GPU • Groupes d’exécution : memoire locale, barrières… • Répartition de charge multi-GPU • Exécutions pyramidales pour réductions associatives 23
  • 24. JavaCL 1.0.0-RC2 • 32 & 64 bits / Windows, Linux, MacOS X • NVIDIA, AMD, Intel & Apple • OpenCL 1.0 / 1.1 (1.2 peu répandu) 24
  • 25. Rendre OpenCL plus facile ? • Éviter d’écrire les kernels en C • Cacher l’asynchronicité • Accepter performance sub-optimale (> 10x plus rapide que Java) 25
  • 26. OpenCL “traduit” • Apapapi (AMD) • Java • Cache beaucoup (trop ?) de détails • ScalaCL (votre serviteur) 26
  • 27. ScalaCL • Collections Scala asynchrones • Stockage + Opérations OpenCL (map, filter, sum…) • Traduction Scala / OpenCL 27
  • 28. Qu'est-ce que Scala ? • Saint-Graal des langages (impératif, fonctionnel, objet…) • Tuples + Collections mutables / immutables • Syntaxe familière • JVM 28
  • 29. Quelques lignes de Scala… val intervalle = (0 until 100000) val cosSinCol = intervalle.map(i => { val f = 0.2 (cos(i * f), sin(i * f)) }) val sum = cosSinCol.map({ case (c, s) => c * s }).sum 29
  • 30. Les mêmes lignes sur GPU import scalacl._ implicit val context = Context.best(DoubleSupport) val intervalle = (0 until 100000).cl val cosSinCol = intervalle.map(i => { val f = 0.2 (cos(i * f), sin(i * f)) }) val sum = cosSinCol.map({ case (c, s) => c * s }).sum 30
  • 32. Comment ça marche • Conversion fonctions Scala => code OpenCL • 3 collections • CLRange : intervalle • CLArray : tableau de tuploïdes • CLFilteredArray : tableau filtré, compactable en parallèle 32
  • 33. Des collections asynchrones • Contrainte : les collections Scala ont l’air synchrones • Principe : single writer, multiple reader 33
  • 34. Des collections asynchrones val tab = Array(1, 2, 3, 4).cl val resultat = tab.map(x => x * 2).map(x – 5) // resultat pas encore calculé resultat(i) = 10 // attente avant écriture 34
  • 35. Traduire Scala en OpenCL ? 35
  • 36. Traduire Scala en OpenCL ? • Limitations (pas de classes) • Élimination des tuples • Élimination du code “objet” 36
  • 37. Ceci est du code objet for (i <- 0 until 100) { … } 37
  • 38. Une lambda peut en cacher une autre (0 until 100).foreach(i => { … }) 38
  • 39. Des boucles 5x plus rapides (0 until 100).foreach(i => var i = 0 { while (i < 100) { … … }) } 39
  • 40. Aller plus vite : flot d’opérations col.map(f).filter(g).map(h).reduceLeft(i) •Collections intermédiaires + lambdas •f, g, h sans effet de bord ? 40
  • 41. ScalaCL : encore un prototype • Scalaxy : spin-off généraliste plutôt stable • Fonctionalités expérimentales : captures, random, reduce • Macros Scala 2.10 41
  • 42. OpenCL • Votre GPU se tourne les pouces • Write once, run (almost) everywhere http://javacl.googlecode.com http://scalacl.googlecode.com 42
  • 43. Questions 43
  • 44. 44
  • 45. CLFilteredArray[T] • Tableau de valeurs + Bitmap de présence • Compactage : • Somme préfixée • Recopie aux incréments • Exemple : filtrage pairs f: x => ((x % 2) == 0) 45
  • 46. JavaCL : générateur de code LinearAlgebraKernels.cl : LinearAlgebraKernels.java : 46
  • 47. JavaCL : hôte minimaliste • Choix d'un contexte + file d'exécution : CLContext context = JavaCL.createBestContext(DoubleSupport); CLQueue queue = context.createDefaultQueue(); • Création de tableaux : DoubleBuffer values = ...; CLDoubleBuffer params = context.createDoubleBuffer(Usage.Input, values); • Compilation=du programme : CLKernel scos context.createProgram(src).createKernel("scos"); • Exécution parallèle : length); scos.setArgs(params, out, CLEvent evt = scos.enqueueNDRange(queue, new int[] { length }); 47

Notes de l'éditeur

  • #2: Bonjour à tous Aujourd’hui je suis venu vous parler de GPGPU, c’est à dire de l’utilisation des cartes graphiques pour effectuer des calculs généralistes.
  • #3: Les cartes graphiques haut de gamme actuelles sont de vrais monstres, Y compris par rapport aux meilleurs CPUs.
  • #4: Mais en dehors des jeux dernier-cri, les cartes graphiques sont rarement exploitées en mesure avec leurs capacités
  • #5: Du coup il est temps de mettre les cartes graphiques au travail ! Dans cette courte intervention je vais donc vous présenter les principes d’OpenCL, et comment l’exploiter en Java. Je terminerai en vous présentant ScalaCL, qui ouvre de nouveaux horizons aux paresseux et aux pressés
  • #6: Tout d’abord un mot sur moi : Développeur C++ / Java avec un background dans la 3D et la finance. Je passe beaucoup de mon temps libre sur des projets Open-Source d’interopérabilité Java / C / C++. J’ai notamment créé JNAerator et BridJ, qui permettent d’obtenir des bindings natifs très facilement. Je me suis basé sur ces deux projets pour créér JavaCL et ScalaCL, qui poussent les limites de l’interopérabilité d’une autre manière.
  • #7: Alors, pour simplifier à l’extrême, OpenCL c’est comme un OpenGL non graphique, où on ne fait que des shaders.
  • #8: Pour ceux à qui OpenGL ne parle pas, On peut aussi voir ça comme un environnement d’exécution de code multi-plateforme (la ressemblance avec Java s’arrête là !)
  • #9: Que gagneriez vous à utiliser OpenCL ? Rendre les parties critiques de vos programmes 10 à 100 fois plus rapides. Exploiter non seulement les GPUs, mais aussi les CPUs (bien plus efficacement qu’en Java !), en particulier en profitant au max du SSE et des multi-coeurs ca peut éventuellement accélérer la visualisation dans votre appli, partage données avec 3D
  • #10: Donc qu’est-ce qu’on exécute au juste, dans OpenCL ? En gros y’a 2 types de charge utiles : Des taches, qui sont juste des fonctions appelées une fois, classiquement Des kernels, qui sont appelés des milliers / millions de fois, partiellement en parallèle, avec un indice qui varie à chaque appel
  • #11: Ces tâches et ces kernels sont asynchrones &amp; enchaînables Chaque opération renvoie un évenement de complétion, et peut attendre d’autres événements avant de s’exécuter On peut donc créer un workflow qui implique des lectures, des écritures, et des éxécutions, et être notifié quand les résultats sont prêts
  • #12: Pour rendre ça un peu plus concret, Prenons un exemple de code C qui calcule des sinus et cosinus de chaque valeur d’un tableau d’entrée, Et les écrit dans un tableau de sortie 2 fois plus grand
  • #13: La version OpenCL de ce code est très proche La boucle for disparait, la fonction / kernel sera appelée length fois Chaque itération pourra connaître son indice i pour savoir quelle inputs prendre et où mettre son output
  • #14: Donc on écrit les kernels dans un dialecte du C Dans lequel on dispose de fonctions mathématiques sur des types vectoriels Le kernel connait sa position d’exécution en N-dimensions Et son activité principale, c’est de lire et d’écrire des données Remarquons au passage que ça peut se compliquer car plusieurs exécutions peuvent être regrouper et utiliser de la synchronisation entre eux
  • #15: Ces kernels doivent être pris en charge et mis en scene par un code hôte, en C ou en Java
  • #16: JavaCL nous permet d’ écrire ce code hôte facilement Ce sont historiquement les premiers bindings java On a pas mal travaillé sur la doc, et il y a meme un chapitre d’un livre qui lui est consacré
  • #17: Faisons donc une pause dans le bla-bla, regardons du code
  • #18: Voila pour un exemple simple. Au passage j’en profite pour dire que JavaCL utilise des bindings autogeneres par JNAerator, Et qu’ils sont linkés dynamiquement par BridJ, qui est compétitif avec JNI.
  • #19: Il faut savoir que JavaCL fournit plus que de simples bindings
  • #20: JavaCL fournit en outre quelques briques utiles, telles que Des transformees de fourier rapides, Des conversions de format d’images Du calcul matriciel
  • #21: Et un éditeur de kernels interactif, que je vais vous montrer rapidement
  • #22: Bon, maintenant que vous pensez qu’OpenCL est trop facile pour etre vrai, passons en revue certains de ses pieges
  • #23: Peu de formats d’images garantis, mais JavaCL fait de son mieux ATI Radeon = Big Endian X86 = little endian
  • #24: Enfin, pour obtenir du code optimal, il faut un peu d’huile de coude
  • #25: Pour terminer sur JavaCL, Dispo sur les plateformes les plus répandues Compatible avec 1.1 (1.2 pas sous mac)
  • #26: OpenCL est assez facile à utiliser, mais on aimerait parfois… … Quitte à accepter une performance sub-optimale
  • #27: Il y a au moins 2 solutions pour la JVM : Aparapi cache cout des transferts de memoire ScalaCL n’a pas (encore) le soutien d’un géant de l’IT
  • #32: import scalacl._ import math._ implicit val context = Context.best val r = (0 until 100000).cl
  • #33: Alors comment ça marche ? Plugin de compilateur Collections stockées sur GPU
  • #34: Y’a une particularité : La contrainte… Donc on respecte le principe Chaque collection maintient une liste d’opérations de lecture et d’écriture en cours
  • #35: Du coup, dans cet exemple : on obtient un resultat pas encore calculé Et on doit attendre avant de pouvoir y écrire
  • #36: Une autre particularité est evidemment la conversion de Scala a OpenCL : y’a qq differences
  • #37: On accepte donc certaines limitations, Et on élimine tout ce qui ne fait pas C : les tuples et les objets en general
  • #38: Quand je dis objet en general…
  • #39: Ce code utilise en fait secretement une closure, qui le rend tres lent
  • #40: En réecrivant les boucles par leur while equivalent, on obtient du code convertible en C Et on rend le scala plus rapide en general !