153

Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Embed Size (px)

DESCRIPTION

Ces nouvelles fonctionnalités introduites à partir de Java 7 nous permettent de parallèliser nos traitements simplement, voire gratuitement. Nous allons donc pouvoir utiliser pleinement nos multicoeurs avec un minimum d'efforts. Quels sont ces nouveaux patterns, quels gains en performance pouvons-nous en attendre, à quels nouveaux bugs serons-nous confrontés ? Une heure pour répondront à chacun de ces points, en introduisant les nouveaux problèmes et leurs solutions. Une heure pour comprendre comment nos habitudes de programmation vont devoir évoluer, et à quoi la programmation parallèle en Java ressemblera-t-elle demain.

Citation preview

Page 1: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 2: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 3: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 4: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 5: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 6: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 7: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 8: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 9: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 10: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 11: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 12: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Pourquoi développer des algorithmes parallèles ?

Page 13: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Pourquoi développer des algorithmes parallèles ?

Pourquoi développer des applications multithread ?

Page 14: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Pourquoi développer des algorithmes parallèles ?

Pourquoi développer des applications multithread ?

=

Page 15: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Pour exploiter la puissance des processeurs modernes.

Page 16: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Depuis 2005 bla bla bla

Page 17: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Depuis 2005 bla bla bla

Conséquence :

Page 18: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Il va falloir faire preuve d’intelligence

pour écrire des applications performantes !

Page 19: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Depuis 2005

Pour développer des applications perfomantes, il faut :

Page 20: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Depuis 2005

Pour développer des applications perfomantes, il faut :

1) Ecrire des traitements multithreads

2) Programmer chaque traitement (algorithme) en parallèle

Page 21: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Boite à outils

1) Ecrire des traitements multithreads : Java.util.concurrent

2) Programmer chaque traitement (algorithme) en parallèle

???

Page 22: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Boite à outils

Jusqu’en JDK 6 : rien…

Page 23: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Boite à outils

Jusqu’en JDK 6 : rien…

À partir de JDK 7 :

- Fork / Join

- Parallel Arrays : rend le Fork / Join compatible JDK 6

À partir de JDK 8 : les lambdas !

Page 24: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Fork / Join JDK 7 & 6

Page 25: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 26: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 27: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 28: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 29: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 30: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 31: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 32: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 33: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 34: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 35: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 36: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 37: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 38: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 39: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Que programme-t-on ?

Initialisation du pool

ForkJoinPool pool = new ForkJoinPool() ;

PrimeFactorsFinderRecursiveTask task =

new PrimeFactorsFinderRecursiveTask(1, 4000) ;

ForkJoinTask<PrimeFactors> pfsTask = pool.submit(task) ;

PrimeFactors pfs = pfsTask.get() ; // Eq join

Page 40: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

public class PrimeFactorsFinderRecursiveTask

extends RecursiveTask<PrimeFactors> {

private int start, end ;

protected PrimeFactors compute() {

PrimeFactors pfs = new PrimeFactors() ;

if (end - start > MAX_ITERATIONS) { // I’m too big

// processing

ForkJoinTask<PrimeFactors> task = ... ;

task.fork() ;

PrimeFactors pfs = task.get() ;

...

} else {

...

}

return pfs ;

}

}

Page 41: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

public class PrimeFactorsFinderRecursiveTask

extends RecursiveTask<PrimeFactors> {

private int start, end ;

protected PrimeFactors compute() {

PrimeFactors pfs = new PrimeFactors() ;

if (end - start > MAX_ITERATIONS) { // I’m too big

// processing

ForkJoinTask<PrimeFactors> task = ... ;

task.fork() ;

PrimeFactors pfs = task.get() ;

...

} else {

...

}

return pfs ;

}

}

Sous-tâche

envoyée au pool

Page 42: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

public class PrimeFactorsFinderRecursiveTask

extends RecursiveTask<PrimeFactors> {

private int start, end ;

protected PrimeFactors compute() {

PrimeFactors pfs = new PrimeFactors() ;

if (end - start > MAX_ITERATIONS) { // I’m too big

// processing

ForkJoinTask<PrimeFactors> task = ... ;

task.fork() ;

PrimeFactors pfs = task.get() ;

...

} else {

...

}

return pfs ;

}

}

Appel à get()

bloquant

Page 43: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

public class PrimeFactorsFinderRecursiveTask

extends RecursiveTask<PrimeFactors> {

private int start, end ;

protected PrimeFactors compute() {

PrimeFactors pfs = new PrimeFactors() ;

if (end - start > MAX_ITERATIONS) { // I’m too big

// processing

ForkJoinTask<PrimeFactors> task = ... ;

task.fork() ;

PrimeFactors pfs = task.get() ;

...

} else {

...

}

return pfs ;

}

}

Calcul

proprement dit

Page 44: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Quelle stratégie de découpage ?

Page 45: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 46: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 47: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 48: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 49: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 50: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 51: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Au niveau du code // 1ère strategie

if (end - start > MAX_ITERATIONS) { // Trop gros !

int m = (start + end) / 2 ;

PrimeFactorsFinderTask task1 =

new PrimeFactorsFinderTask(start, m) ;

PrimeFactorsFinderTask task2 =

new PrimeFactorsFinderTask(m, end) ;

task1.fork() ;

task2.fork() ;

PrimeFactors pfs1 = task1.join() ;

PrimeFactors pfs2 = task2.join() ;

pfs.add(pfs1) ;

pfs.add(pfs2) ;

}

Page 52: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

// 2ème strategie

if (end - start > MAX_ITERATIONS) { // Trop gros !

List<ForkJoinTask<PrimeFactors>> pfsList = new ArrayList<ForkJoinTask<PrimeFactors>>() ; for (int i = start ; i < end – MAX_ITERATIONS ; i += MAX_ITERATIONS) { PrimeFactorsFinderRecursiveTask task = new PrimeFactorsFinderRecursiveTask( i, i + MAX_ITERATIONS) ; task.fork() ; pfsList.add(task) ; } for (ForkJoinTask<PrimeFactors> task : pfsList) { PrimeFactors pfsElement = task.join() ; pfs.add(pfsElement) ; } }

30% plus rapide…

Page 53: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Pièges du Fork / Join

La Java doc nous dit :

Computations should avoid synchronized blocks or methods

Donc si une tâche a un état, cet état doit être transmis aux sous-tâches par copie

Page 54: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Pièges du Fork / Join

La Java doc nous dit :

Computations should avoid synchronized blocks or methods

Donc si une tâche a un état, cet état doit être transmis aux sous-tâches par copie

Quelles conséquences sur les tableaux ?

Page 55: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 56: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 57: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 58: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 59: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 60: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 61: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Impossible avec le Fork / Join

Page 62: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Parallel Arrays JDK 6 & 7

Page 63: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Parallel Arrays

Parallel Arrays : JSR 166y, package extra166y

Dispo en Java 6, embarque le Fork / Join

Inconvénient : en Java 7 on a 2 classes ForkJoinPool, dans deux packages différents

Permet le calcul sur des tableaux de nombres (long ou double)

http://g.oswego.edu/dl/concurrency-interest/

Page 64: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Parallel Arrays

Initialisation

ForkJoinPool pool = new ForkJoinPool() ; // package !

ParralelLongArray a = ParralelLongArray.create(pool) ;

Page 65: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Parallel Arrays

Map :

Ops.LongOp add2 = new Ops.LongOp() {

@Override

public long op(long l1) {

return l1 + 2 ;

}

} ;

a2 = a.withMapping(add2) ;

Page 66: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Parallel Arrays

Filter :

Ops.LongPredicate filter = new Ops.LongPredicate() {

@Override

public boolean op(long l1) {

return l1 > 50 ;

}

}

a2 = a.withFilter(filter) ;

a2.all() ;

Page 67: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Parallel Arrays

Reduce :

Ops.LongReducer reducer = new Ops.LongReducer() {

@Override

public long op(long l1, long l2) {

return l1 + l2 ;

}

}

long reducedValue = a.reduce(reducer, 0L) ;

Page 68: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Parallel Arrays

Idée :

1) On définit des opérations

2) On « pousse » ces opérations vers le ParallelArrays, qui effectue le calcul, en parallèle !

Approche qui ressemble à la programmation fonctionnelle

Page 69: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Bilan pour les JDK 6 & 7

2 outils disponibles :

- Fork / Join, dans le JDK

- Les parallel arrays, API séparée

Page 70: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Pourquoi l’API Parallel Arrays n’est-elle pas dans le JDK ?

Page 71: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Bicoze, dans le JDK 8, on a les …

Page 72: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 73: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Et avec les lambdas…

… des nouveaux patterns arrivent !

Page 74: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Et avec les lambdas…

Map :

List<Personne> personnes = new ArrayList<>() ; personnes.stream() .map(person -> person.getAge())

Page 75: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Et avec les lambdas…

Filter :

List<Personne> personnes = new ArrayList<>() ; personnes.stream() .map(person -> person.getAge()) .filter(age -> age > 20)

Page 76: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Et avec les lambdas…

Reduce :

List<Personne> personnes = new ArrayList<>() ; int somme = personnes.stream() .map(person -> person.getAge()) .filter(age -> age > 20) .reduce(0, (a1, a2) -> a1 + a2) ;

Page 77: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Et avec les lambdas…

Et si on le veut en parallèle :

List<Personne> personnes = new ArrayList<>() ; int somme = personnes.parallelStream() .map(person -> person.getAge()) .filter(age -> age > 20) .reduce(0, (a1, a2) -> a1 + a2) ;

Page 78: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

API Stream & Collector

Arrivée de deux API : Stream et Collector

Permettent tous les calculs imaginables sur les collections de grande taille…

En parallèle !

Page 79: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Exemple : tri d’une liste

Stream<String> stream = Stream.generate( () -> Long.toHexString(ThreadLocalRandom.current().nextLong()) ) ; Stream stream = stream1 .map(s -> s.substring(0, 10)) .limit(10_000_000) .sorted() ; Object [] sorted = stream.toArray() ;

Exécution : 14 s

Page 80: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Exemple : tri d’une liste

Stream<String> stream = Stream.generate( () -> Long.toHexString(ThreadLocalRandom.current().nextLong()) ) ; Stream stream = stream1.parallel() .map(s -> s.substring(0, 10)) .limit(10_000_000) .sorted() ; Object [] sorted = stream.toArray() ;

En parallèle : 3,5 s

Exécution : 14 s

Page 81: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Fork / Join, Lambdas

Comment utiliser ces outils efficacement ?

Page 82: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Utilisation

Malheureusement, il ne suffit pas d’appeler parallel() pour que ça marche …

Page 83: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Problèmes

1) Écrire des réductions « correctes »

2) Régler « correctement » l’algorithmique

3) Utiliser des algorithmes « corrects »

Page 84: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

1er problème : associativité

Une réduction doit être associative

red(a, red(b, c)) = red(red(a, b), c)

Page 85: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

1er problème : associativité

Une réduction doit être associative

red(a, red(b, c)) = red(red(a, b), c)

a + (b + c) = (a + b) + c Correct

Page 86: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

1er problème : associativité

Une réduction doit être associative

red(a, red(b, c)) = red(red(a, b), c)

a + (b + c) = (a + b) + c Correct

(a + (b + c)2)2 = ((a + b) 2 + c)2 Oops !

Page 87: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

1er problème : associativité

Une réduction doit être associative

red(a, red(b, c)) = red(red(a, b), c)

a + (b + c) = (a + b) + c Correct

(a + (b + c)2)2 = ((a + b) 2 + c)2 Oops !

Le compilateur ou la JVM vont-ils m’aider ?

Page 88: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

2ème problème : performance

Le calcul parallèle est-il vraiment plus rapide ?

• Exemple : tri d’une liste de long

long begin = System.nanoTime() ; List<String> hugeList = new ArrayList<>(N) ; // N = 16_000_000 for (int i = 0 ; i < N ; i++) { long l = random.nextLong() ; l = l > 0 ? l : -l ; hugeList.add(Long.toString(l, 32)) ; }

Page 89: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Tri en parallèle

Déroulement :

• Division de la liste en N sous-listes

• Tri de chaque liste sur un cœur : QuickSort

• Fusion des listes triés : MergeSort

Coût : calcul + déplacement des données de cœur en cœur

Page 90: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 91: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 92: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 93: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 94: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 95: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 96: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 97: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 98: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Performances

2 stratégies de découpage :

• Boucle for

• Dyadique

• Tri avec Collections.sort

CPU Intel core i7, 8 cœurs

Page 99: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Performances

4M

2M

1M

4M

2M

1M

2 tableaux : 16M et 32M de long

Page 100: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Performances

4M 13

2M 12

1M 20

4M

2M

1M

1) La bonne taille du paquet

Page 101: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Performances

4M 13

2M 12

1M 20

4M 33

2M 54

1M 93

1) La bonne taille du paquet … dépend de la taille du tableau !

Page 102: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Performances

4M 13 18

2M 12 20

1M 20 35

4M 33

2M 54

1M 93

2) La stratégie de division est importante !

Page 103: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Performances

4M 13 18

2M 12 20

1M 20 35

4M 33 47

2M 54 125

1M 93 211

2) La stratégie de division est importante ! et dépend de la taille du tableau !

Page 104: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

4M 13 18

2M 12 20

1M 20 35

4M 33 47

2M 54 125

1M 93 211

MAIS…

Page 105: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Quelles sont les performances sans parallélisation ?

4M 13 18

2M 12 20

1M 20 35

4M 33 47

2M 54 125

1M 93 211

Page 106: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

4M 13 18

2M 12 20

1M 20 35

4M 33 47

2M 54 125

1M 93 211

16M 18

32M 36

Page 107: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Écrire du code parallèle est complexe et coûteux

mais n’amène pas toujours des gains en performance !

Page 108: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

3ème problème

Une anecdote

• Le 24/2/2012, Heinz Kabutz défie les lecteurs de son (excellent) blog Java Specialists :

• Calculer les 10 premiers et 10 derniers chiffres du nombre de Fibonacci d’indice 1 milliard

Page 109: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

3ème problème

Nombre de Fibonacci

• F0 = 0, F1 = 1

• Fn = Fn – 1 + Fn – 2

F1_000_000 est un nombre trrrès grand !

Page 110: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

3ème problème

Record à battre : 5800s (ou 2500 ?) sur un Core i7 à 8 cœurs

Page 111: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

3ème problème

Record à battre : 5800s (ou 2500 ?) sur un Core i7 à 8 cœurs

1ère amélioration : 3300s sur 4 cœurs

Page 112: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

3ème problème

Record à battre : 5800s (ou 2500 ?) sur un Core i7 à 8 cœurs

1ère amélioration : 3300s sur 4 cœurs

2ème amélioration : 51s sur 1 cœur (pas de parallélisation)

Page 113: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Où est le miracle ?

Pas de miracle…

- Utilisation de la librairie GNU GMP

- Utilisation d’une bonne implémentation de BigInteger

- Meilleur algorithme de calcul des nombres de Fibonacci

- Suppression de la récursivité

Page 114: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Où est le miracle ?

Pas de miracle…

- Utilisation de la librairie GNU GMP

- Utilisation d’une bonne implémentation de BigInteger

- Meilleur algorithme de calcul des nombres de Fibonacci

- Suppression de la récursivité

Quel rapport avec le parallélisme ??

Page 115: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Algorithmes

Entre 1990 et 2005, l’optimisation linéaire a gagné un facteur 43M

- 1k est du à la rapidité des processeurs

- 43k sont dus à celle des algorithmes

Page 116: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Avant de paralléliser mieux vaut s’assurer

que l’on utilise le bon algorithme

Page 117: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

4ème problème

Étude de cas : le voyageur de commerce

Comment résoudre ce problème ?

Page 118: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

4ème problème

Étude de cas : le voyageur de commerce

Comment résoudre ce problème

Pas d’algorithme direct, il nous faut une approche « stochastique » (= avec de l’aléatoire)

Et c’est encore un problème de tableaux !

Page 119: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 120: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 121: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 122: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 123: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 124: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 125: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 126: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 127: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 128: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 129: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 130: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 131: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 132: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 133: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013
Page 134: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Comment paralléliser ?

Problème de tableau, donc facile !

• On coupe le tableau en morceaux

• On déroule sur chaque morceau

• Et on fusionne

Page 135: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Sauf que …

Ca ne marche pas !

• Les propriétés de convergence sont perdues en parallèle

Page 136: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Sauf que …

Ca ne marche pas !

• Les propriétés de convergence sont perdues en parallèle

Le code compile

Il s’exécute

Le résultat est faux…

Page 137: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Conclusion

Page 138: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Conclusion

• 1975 : le langage C permet de ne plus gérer la pile à la main

Page 139: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Conclusion

• 1975 : le langage C permet de ne plus gérer la pile à la main

• 1995 : Java permet de ne plus gérer la mémoire à la main

Page 140: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Conclusion

• 1975 : le langage C permet de ne plus gérer la pile à la main

• 1995 : Java permet de ne plus gérer la mémoire à la main

• 2013 : Java (encore lui) permet de ne plus gérer le multicœur à la main !

Page 141: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Conclusion

Aujourd’hui le CPU lui-même devient une ressource parmi d’autres, au même titre que la mémoire

Les applications vont pouvoir s’exécuter en parallèle de façon transparente

Page 142: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Conclusion

Oui la parallélisation devient facile, comme elle ne l’a jamais été

• On appele parallel(), et en voiture !

Page 143: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Conclusion

Oui la parallélisation devient facile, comme elle ne l’a jamais été

• On appele parallel(), et en voiture !

Mais…

Page 144: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Conclusion

Oui la parallélisation devient facile, comme elle ne l’a jamais été

• On appele parallel(), et en voiture !

Mais…

• Mon traitement est-il plus rapide ?

• Mes résultats sont-ils corrects ?

Page 145: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Conclusion

Il y a quelques années on disait :

« un bon programmeur doit apprendre un nouveau langage tous les N mois / années »

Page 146: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Conclusion

Aujourd’hui mon conseil :

Page 147: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Conclusion

Aujourd’hui mon conseil :

• 1er mois : apprendre le fonctionnement interne des CPU

Page 148: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Conclusion

Aujourd’hui mon conseil :

• 1er mois : apprendre le fonctionnement interne des CPU

• 2ème mois : apprendre à programmer les algorithmes complexes

Page 149: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Conclusion

Aujourd’hui mon conseil :

• 1er mois : apprendre le fonctionnement interne des CPU

• 2ème mois : apprendre à programmer les algorithmes complexes

• 3ème mois : apprendre la version parallèle de ces algorithmes

Page 150: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Conclusion

La parallélisation des traitements / algorithmes amène

- De nouvelles opportunités

- Des nouveaux problèmes

- De nouvelles catégories de bugs

Page 151: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Conclusion

La parallélisation des traitements / algorithmes amène

- De nouvelles opportunités

- Des nouveaux problèmes

- De nouvelles catégories de bugs

Et donc de nouveaux challenges !

Page 152: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Merci !

Page 153: Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) facile ! - José paumard Codeurs en seine 2013

Q/R