Средства распараллеливания в Java 1.7 (jsr166y...) Михаил Пономаренко, Tech Lead компании Sigma Ukraine

Содержание

Слайд 2

немного истории

до java 1.5 были
wait
notify
synchonized
в 1.5 - jsr166
java.util.concurrent
Future, ThreadExecutor
ConcurrentMap - асинхронные итераторы

немного истории до java 1.5 были wait notify synchonized в 1.5 -

Слайд 3

немного истории

в 1.6 - jsr166x
 BlockingDeque
ConcurrentNavigableMap, NavigableMap
в 1.7 - jsr166y
ForkJoinPool
Phaser
ParallelArray (jsr166y extra)

немного истории в 1.6 - jsr166x BlockingDeque ConcurrentNavigableMap, NavigableMap в 1.7 -

Слайд 4

java.util.concurrent.Phaser

java.util.concurrent.Phaser

Слайд 5

java.util.concurrent.Phaser

void startTasks(List tasks, final int iterations) {
final Phaser phaser = new

java.util.concurrent.Phaser void startTasks(List tasks, final int iterations) { final Phaser phaser =
Phaser() {
protected boolean onAdvance(int phase, int registeredParties) {
return phase >= iterations || registeredParties == 0; }
};
phaser.register();
for (final Runnable task : tasks) {
phaser.register();
new Thread() { public void run() {
do {
task.run();
phaser.arriveAndAwaitAdvance();
} while (!phaser.isTerminated());
} }.start();
}
phaser.arriveAndDeregister(); // deregister self, don't wait
}

Слайд 6

Fork Join – рекурсивная декомпозиция   

если задача маленькая - посчитать
если большая разбить и

Fork Join – рекурсивная декомпозиция если задача маленькая - посчитать если большая
посчитать рекурсивно

дробить

Возможно дробить

считать все вместе

Слайд 7

JDK7 дает возможность дробить мелко
Минимум взаимодействия

Fork Join – рекурсивная декомпозиция   

JDK7 дает возможность дробить мелко Минимум взаимодействия Fork Join – рекурсивная декомпозиция

Слайд 8

ForkJoin

задача

1

2

3

ответ

4

ForkJoin задача 1 2 3 ответ 4

Слайд 9

Детали реализации

дополнительной сихронизации не требуется
старые разбиения "больше“
Поэтому: 
У каждого потока свой дек задачь
поток

Детали реализации дополнительной сихронизации не требуется старые разбиения "больше“ Поэтому: У каждого
выполнения берет задачу из дека
задача добавляет подзадачи в дэк или производит вычисления
если задачи кончилисть - "украсть" задачу у другого потока

Слайд 10

Детали реализации

готово

100

100

готово

готово

Готово

50

50

Детали реализации готово 100 100 готово готово Готово 50 50

Слайд 11

ForkJoinTask

protected abstract boolean exec()
ForkJoinTask fork()
Не ждет
public final V join()
То же но без исключений
public

ForkJoinTask protected abstract boolean exec() ForkJoinTask fork() Не ждет public final V
static void invokeAll(ForkJoinTask... tasks))
Invoke = fork(); join();

Слайд 12

RecursiveAction

extends ForkJoinTask
protected void compute()
Посчитать
Поделить
Вызвать invokeAll
Сделать join
Нужно что то сделать, но нет возвращаемого

RecursiveAction extends ForkJoinTask protected void compute() Посчитать Поделить Вызвать invokeAll Сделать join
значения
RecursiveTask – есть возаращаемое значение – его вернет join

Слайд 13

Примеры Doug Lea

Примеры Doug Lea

Слайд 14

Результаты Doug Lea

Быстрее раз

процессоров

Результаты Doug Lea Быстрее раз процессоров

Слайд 15

Пример

2^28 произвольных чисел double (2 гб)

ForkJoinPool pool = new ForkJoinPool(p);
SinCosHuge task =

Пример 2^28 произвольных чисел double (2 гб) ForkJoinPool pool = new ForkJoinPool(p);
new SinCosHuge(randomData);
pool.execute(task);
Double rz = task.join();

Слайд 16

Пример

import java.util.concurrent.RecursiveTask;
public class SinCosHuge extends RecursiveTask {

protected Double compute() {
if (to -

Пример import java.util.concurrent.RecursiveTask; public class SinCosHuge extends RecursiveTask { … protected Double
from < threshold) {
double rz = 0;
for (int i = from; i < to; i++) {
rz += Math.sin(data[i]) + Math.atan(data[i]);
}
return rz;
} else {
int i = (from + to) / 2;
SinCosHuge right = new SinCosHuge(data, from, i);
SinCosHuge left = new SinCosHuge(data, i, to);
invokeAll(left,right);
return right.join() + left.join();
}
}

Слайд 17

Мои измерения

Загрузка процессора 100%
температура

Мои измерения Загрузка процессора 100% температура

Слайд 18

Мои измерения, время выполнения.

потоков

время

Мои измерения, время выполнения. потоков время

Слайд 19

потоков

Во сколько раз медленнее минус один

потоков Во сколько раз медленнее минус один

Слайд 20

Мои измерения – относительно самого быстрого

потоков

Относительная разница в скорости. %

Мои измерения – относительно самого быстрого потоков Относительная разница в скорости. %

Слайд 21

А если по старому?

ThreadExecutorPool
Result
add(double)
waitDone
fork

ThreadPoolExecutor tpe = new ThreadPoolExecutor(p, p, 10,SECONDS, workQueue);
Result rz

А если по старому? ThreadExecutorPool Result add(double) waitDone fork ThreadPoolExecutor tpe =
= new Result();
tpe.submit(new SinCosHugePool(randomData, tpe, rz));
rz.waitDone();

Слайд 22

Runnable.run

if (to - from < treshold) {
double rz = 0;
for (int i

Runnable.run if (to - from double rz = 0; for (int i
= from; i < to; i++) {
rz += Math.sin(data[i]) + Math.atan(data[i]);
}
result.add(rz);
} else {
int i = (from + to) / 2;
SinCosHugePool right = new SinCosHugePool(data, from, i, executor,result);
SinCosHugePool left = new SinCosHugePool(data, i, to, executor,result);
result.fork();
executor.execute(left);
executor.execute(right);
}

Слайд 23

А если по старому?

потоков

Во сколько раз медленнее минус один

А если по старому? потоков Во сколько раз медленнее минус один

Слайд 24

А если по старому

Относительная разница в скорости. %
Ниже = лучше

потоков

А если по старому Относительная разница в скорости. % Ниже = лучше потоков

Слайд 25

ParallelArray

Судя по всему НЕ попадет в JDK 1.7, но исходники доступны
MapReduce в

ParallelArray Судя по всему НЕ попадет в JDK 1.7, но исходники доступны
пределах одной машины

Слайд 26

Пример IBM

ParallelArray students = new ParallelArray(fjPool, data);
double bestGpa = students.withFilter(isSenior).withMapping(selectGpa).max();
public class Student

Пример IBM ParallelArray students = new ParallelArray (fjPool, data); double bestGpa =
{
String name; int graduationYear; double gpa;
}
static final Ops.Predicate isSenior = new Ops.Predicate() {
public boolean op(Student s) { return s.graduationYear == Student.THIS_YEAR; }
};
static final Ops.ObjectToDouble selectGpa = new Ops.
ObjectToDouble() {
public double op(Student student) { return student.gpa; }
};

Слайд 27

Мой пример

new long[16384 * 16384/8] - 1 гб рабочей памяти,
double[16384 * 16384/2]

Мой пример new long[16384 * 16384/8] - 1 гб рабочей памяти, double[16384
– 6гб рабочей

import jsr166y.ForkJoinPool;
import extra166y.ParallelLongArray;
…..
long[] randomData = new long[16384 * 16384/8];
ForkJoinPool pool = new ForkJoinPool(p);
ParallelLongArray arr = ParallelLongArray.createUsingHandoff(randomData, pool);
int uniqueCount = arr.allUniqueElements().size();
ParallelLongArray.SummaryStatistics summary = arr.summary();

Слайд 28

Результаты

потоков

Во сколько раз медленнее

Результаты потоков Во сколько раз медленнее
Имя файла: Средства-распараллеливания-в-Java-1.7-(jsr166y...)-Михаил-Пономаренко,-Tech-Lead-компании-Sigma-Ukraine.pptx
Количество просмотров: 697
Количество скачиваний: 1