High-Performance Fork/Join - под капотом паралеллизма в ... ·...

75
High-Performance Fork/Join под капотом паралеллизма в платформе Алексей Шипилёв [email protected], @shipilev

Transcript of High-Performance Fork/Join - под капотом паралеллизма в ... ·...

Page 1: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

High-Performance Fork/Joinпод капотом паралеллизма в платформе

Алексей Шипилёв[email protected], @shipilev

Page 2: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

The following is intended to outline our generalproduct direction. It is intended for informationpurposes only, and may not be incorporated into anycontract. It is not a commitment to deliver anymaterial, code, or functionality, and should not berelied upon in making purchasing decisions. Thedevelopment, release, and timing of any features orfunctionality described for Oracle’s products remainsat the sole discretion of Oracle.

Slide 2/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 3: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Введение

Slide 3/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 4: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Введение: предпосылки

Мы, человеки, хорошо умеем писатьпоследовательный софт

Писать паралелльный софт сложноСохранить иллюзию последовательности?Хардвар всё равно последовательный?

«Разделяй и властвуй»Разбить большую задачу на подзадачиВыполнить подзадачи параллельноПоклеить результаты

Slide 4/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 5: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Введение: уже и так всё ясно

Каждый девелопер уже писал Fork/Join:

Slide 5/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 6: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Введение: проблемы

Привет, закон Амдала:Порезка задачи последовательнаСклейка результатов последовательна(доминирует время исполнения)

Балансировка нагрузкиПоднятие потоковРаздача работы

Иерархические декомпозицииГарантии прогресса

Slide 6/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 7: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Введение: общий вид

Result solve(Problem problem) {if (problem.smallEnough ())

return solveDirectly(problem );else {

(task1 , task2) =split(problem );

(result1 , result2) =invokeAll(task1 , task2);

return merge(result1 , result2 );}

}

Slide 7/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 8: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Введение: банальные проблемы

Для N-арного дерева глубины K:в худшем случае 𝑁𝐾−1

𝑁−1 + 1 потоков

Slide 8/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 9: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Введение: суть

Блокирующее ожиданиетеряет активный потокИдея: join() не должензанимать поток!Заставим «застрявшие»потоки работать:требуется нехилаякоординация

Slide 9/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 10: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Для начинающих

Slide 10/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 11: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Для начинающих: API

ForkJoinPool...extends ExecutorServiceпринимает в себя Runnable’ы, Callable’ыи вообще работает как обычный пул

ForkJoinTask<V>общий предок всех задач в FJPудобнее стандартные подклассы:RecursiveTask<V> – с газомRecursiveAction – без газа

Slide 11/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 12: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Для начинающих: API

ForkJoinPool fjp = new ForkJoinPool ();

fjp.submit(new MyRunnable ());fjp.invoke(new MyCallable ());fjp.invoke(new MyRecursiveTask ());

class MyRunnableimplements Runnable { ... };

class MyCallable <T>implements Callable <T> { ... };

class MyRecursiveTask <T>extends RecursiveTask <T> { ... };

Slide 12/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 13: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Балансировка задач: подходы

балансировка хорошо решается в динамике

три базовых подхода:

1. Work arbitrage: общий арбитр, раздающийзадачи; часто обычная blocking queue

2. Work dealing: у каждого свой набор задач,перегруженные потоки отдают свои задачи насторону

3. Work stealing: у каждого свой набор задач,свободные потоки «крадут» задачи уперегруженных

Slide 13/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 14: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Балансировка задач: очередь?

0

10

20

30

0 10 20 30submitter threads

wo

rke

r th

rea

ds

0.5 1.0 1.5 2.0 2.5throughput, ops/usec

TPE(ABQ) submission throughput

2x8x2 SandyBridge, RHEL 5.5, JDK 8b89 + jsr166 2013-05-15Slide 14/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 15: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Балансировка задач: Work stealing

Локальная очередь для каждого потокаlock-free WorkQueue ∼ ForkJoinTask<?>[]тщательно изолирована от остальных данных

Владелец работает с головой очередибез синхронизации!

Другие потоки могут «тырить» из хвоста«stealing» с минимальной синхронизацией

Slide 15/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 16: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Балансировка задач: submit

Куда происходит submit() внешних задач?

в голову случайной очереди? синхронизация!в хвост случайной очереди? FIFO!

Отдельная очередь для внешних задач?Расклеить очереди входных задач!

Slide 16/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 17: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Балансировка задач: submit

Куда происходит submit() внешних задач?в голову случайной очереди? синхронизация!в хвост случайной очереди? FIFO!

Отдельная очередь для внешних задач?Расклеить очереди входных задач!

Slide 16/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 18: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Балансировка задач: результат

0

10

20

30

0 10 20 30submitter threads

wo

rke

r th

rea

ds

5 10 15 20throughput, ops/usec

FJP submission throughput

2x8x2 SandyBridge, RHEL 5.5, JDK 8b89 + jsr166 2013-05-15Slide 17/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 19: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Балансировка задач: результат

0

10

20

30

0 10 20 30submitter threads

wo

rke

r th

rea

ds

0 500 1000 1500 2000 2500%change

FJP vs. TPE(ABQ) submission throughput ratio

2x8x2 SandyBridge, RHEL 5.5, JDK 8b89 + jsr166 2013-05-15Slide 18/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 20: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Типичная задача: в кодеprivate static class StandardTask extends RecursiveTask <Long > {

private final Problem problem;private final int l;private final int r;

public StandardTask(Problem p, int l, int r) {this.problem = p;this.l = l;this.r = r;

}

@Overrideprotected Long compute () {

if (r - l <= THRESHOLD) {return problem.solve(l, r);

}

int mid = (l + r) >>> 1;ForkJoinTask <Long > t1 = new StandardTask(problem , l, mid);ForkJoinTask <Long > t2 = new StandardTask(problem , mid , r);t1.fork (); // fork 1t2.fork (); // fork 2

long res = 0;res += t2.join (); // join 2res += t1.join (); // join 1return res;

}}

Slide 19/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 21: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Типичная задача: в коде, поближе

ForkJoinTask <Long > t1 , t2;

int mid = (l + r) >>> 1;t1 = new StandardTask(problem , l, mid);t2 = new StandardTask(problem , mid , r);t1.fork (); // fork 1t2.fork (); // fork 2

long res = 0;res += t2.join (); // join 2res += t1.join (); // join 1return res;

Slide 20/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 22: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Типичная задача: ещё ближе

ForkJoinTask <Long > t1 , t2;

int mid = (l + r) >>> 1;t1 = new StandardTask(problem , l, mid);t2 = new StandardTask(problem , mid , r);

ForkJoinTask.invokeAll(t1, t2);

long res = 0;res += t2.join (); // get result 1res += t1.join (); // get result 2return res;

Slide 21/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 23: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Типичная задача: fork().join()

fork()кладёт в очередь и возвращаетсядаёт возможность «украсть» задачу

join()«ждать, пока закончится»даёт возможность занять поток ещё чем-нибудь

Slide 22/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 24: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Типичная задача: join()

магия начинается здесь!

можно сделать одно из действий:1. выполнить эту join-ящуюся задачу2. найти в очереди задачу и выполнить3. пойти в чужую очередь и «украсть» задачу4. ...5. заблокироваться

Slide 23/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 25: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Главный козырь: идеи

обычно в локальной очереди куча задачпочти все потоки почти всегда занятыбалансировка требуется редко«украденная» задача засевает очередь

Slide 24/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 26: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Главный козырь: Task Trees

2x8x2 SandyBridge, RHEL 5.5, JDK 8b89 + jsr166 2013-05-15Slide 25/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 27: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Главный козырь: Queue Occupancy

2x8x2 SandyBridge, RHEL 5.5, JDK 8b89 + jsr166 2013-05-15Slide 26/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 28: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Главный козырь: Workers State

2x8x2 SandyBridge, RHEL 5.5, JDK 8b89 + jsr166 2013-05-15Slide 27/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 29: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Выбор ширины: проблема

protected Long compute () {if (r - l <= THRESHOLD) {

return seq();}return par();

}

как выбрать THRESHOLD?слишком маленький = куча объектов-задачслишком большой = мало параллелизма

Slide 28/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 30: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Выбор ширины: наивный подход

𝑇 = 𝑁𝐶 ,

где𝑁 – размер задачи,𝐶 – количество CPU

Плохо работает при неравномерных задачах,несимметричных потоках, непредсказуемых

задержках.

Slide 29/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 31: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Выбор ширины: наивный подход

𝑇 = 𝑁𝐶 ,

где𝑁 – размер задачи,𝐶 – количество CPU

Плохо работает при неравномерных задачах,несимметричных потоках, непредсказуемых

задержках.

Slide 29/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 32: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Выбор ширины: правильный метод

𝑇 = 𝑁𝐶𝐿,

где𝑁 – размер задачи,𝐶 – количество CPU,

𝐿 – load factor

Load factor даёт «запас» задач, которыеамортизируют задержки и неравномерности.

Обычное значение 𝐿 ∈ [10..100]

Slide 30/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 33: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Выбор ширины: правильный метод

𝑇 = 𝑁𝐶𝐿,

где𝑁 – размер задачи,𝐶 – количество CPU,

𝐿 – load factor

Load factor даёт «запас» задач, которыеамортизируют задержки и неравномерности.

Обычное значение 𝐿 ∈ [10..100]

Slide 30/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 34: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Выбор ширины: threshold

0

5

10

15

101

103

105

107

threshold

para

llel speedup, X

Cold Hot Seq x16 Seq x1

FJP: Throughput vs. Threshold (problem size = 10M)

Slide 31/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 35: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Выбор ширины: load factor

0

5

10

15

100

102

104

106

load factor

pa

ralle

l sp

ee

du

p,

X

Cold Hot Seq x16 Seq x1

FJP: Throughput vs. Load Factor (problem size = 10M)

Slide 32/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 36: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Для продолжающих

Slide 33/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 37: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: зачем

WTF: заблокированные потоки в хвосте?

Slide 34/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 38: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: зачем

WTF: заблокированные потоки в хвосте?

Slide 34/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 39: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: помельче

Рекурсивные join()-ы в хвосте!

Slide 35/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 40: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: идея

в отсутствие работы потоки блокируютсяразбудить поток – целое делочем глубже разбиение, тем больше будитьна мелких задачах пожирает время

Идея: вот бы у нас были continuation-ы...

Slide 36/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 41: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: идея

в отсутствие работы потоки блокируютсяразбудить поток – целое делочем глубже разбиение, тем больше будитьна мелких задачах пожирает время

Идея: вот бы у нас были continuation-ы...

Slide 36/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 42: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: их есть у нас!

public abstract class CountedCompleter <T>extends ForkJoinTask <T> {

// bind to parentpublic CountedCompleter(CountedCompleter <?> parent) { ... }

// compute as usualpublic abstract void compute () { ... }

// pending count = how many subtasks are still alivepublic void setPendingCount(int count) { ... }

// try to completepublic void tryComplete () { ... }

// to be called on completionpublic void onCompletion () { ... }

}

Slide 37/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 43: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: логика

образуют дерево назадачахУ каждой задачиесть pendingCount= количествоневыполненныхподзадач

Slide 38/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 44: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: логика

void tryComplete () {pendingCount --;if (pendingCount <= 0) {

onCompletion ();if (parent != null) {

parent.tryComplete ();}

}}

Slide 39/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 45: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: логика

void tryComplete () {pendingCount --;if (pendingCount <= 0) {

onCompletion ();if (parent != null) {

parent.tryComplete ();}

}}

Slide 39/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 46: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: логика

void tryComplete () {pendingCount --;if (pendingCount <= 0) {

onCompletion ();if (parent != null) {

parent.tryComplete ();}

}}

Slide 39/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 47: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: логика

void tryComplete () {pendingCount --;if (pendingCount <= 0) {

onCompletion ();if (parent != null) {

parent.tryComplete ();}

}}

Slide 39/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 48: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: логика

void tryComplete () {pendingCount --;if (pendingCount <= 0) {

onCompletion ();if (parent != null) {

parent.tryComplete ();}

}}

Slide 39/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 49: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: логика

void tryComplete () {pendingCount --;if (pendingCount <= 0) {

onCompletion ();if (parent != null) {

parent.tryComplete ();}

}}

Slide 39/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 50: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: логика

void tryComplete () {pendingCount --;if (pendingCount <= 0) {

onCompletion ();if (parent != null) {

parent.tryComplete ();}

}}

Slide 39/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 51: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: логика

void tryComplete () {pendingCount --;if (pendingCount <= 0) {

onCompletion ();if (parent != null) {

parent.tryComplete ();}

}}

Slide 39/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 52: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: логика

void tryComplete () {pendingCount --;if (pendingCount <= 0) {

onCompletion ();if (parent != null) {

parent.tryComplete ();}

}}

Slide 39/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 53: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: логика

void tryComplete () {pendingCount --;if (pendingCount <= 0) {

onCompletion ();if (parent != null) {

parent.tryComplete ();}

}}

Slide 39/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 54: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: логика

void tryComplete () {pendingCount --;if (pendingCount <= 0) {

onCompletion ();if (parent != null) {

parent.tryComplete ();}

}}

Slide 39/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 55: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: в коде

public static class MyTask extends CountedCompleter <Void > {

public MyTask(CountedCompleter <?> parent , ...) {super(parent );...

}

@Overridepublic void compute () {

if (size < thresh) {seq (...);

} else {setPendingCount (2); // expect two subtasksnew MyTask(this , size / 2, thresh ).fork ();new MyTask(this , size / 2, thresh ).fork ();

}tryComplete (); // increment and try to call completion

}}

Slide 40/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 56: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: получилось

«никаких разрывов»Slide 41/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 57: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: рецепты

сильно лучше на мелких задачахrecursive: 450± 15 𝜇𝑠

completers: 290± 10 𝜇𝑠

так же быстры на крупных задачах

сильно усложняют логику сборки результатов(упражнение читателю)

Slide 42/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 58: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

CountedCompleter: рецепты

сильно лучше на мелких задачахrecursive: 450± 15 𝜇𝑠

completers: 290± 10 𝜇𝑠

так же быстры на крупных задачах

сильно усложняют логику сборки результатов(упражнение читателю)

Slide 42/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 59: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Over-signalling: проблема

разбудить весь пул –большая проблемана мелких задачаххарактерное времядля одного потока∼ 50𝜇𝑠

для 𝑁 потоковможет съесть кучувремени∼ 50 𝑙𝑜𝑔(𝑁) 𝜇𝑠

Slide 43/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 60: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Over-signalling: решение

∼ 50 𝑙𝑜𝑔(𝑁) 𝜇𝑠

константа от нас независит, только OSможно только базулогарифмауменьшить«полундра!»-mode:будить всех и всяпри всяком удобномслучае

Slide 44/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 61: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Common Pool: проблема

в конце концов:первый hand-off впул тормозит всёхарактерное времяот первого wakeup’адо полногопараллелизма∼ 200𝜇𝑠

Slide 45/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 62: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Common Pool: решение

Заставить submitter-ыработать на нас!

...они будят пул

...и вообще на насработают

Выигрываем 100𝜇𝑠 ибольше!

Slide 46/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 63: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Common Pool: реализация

submitter-у нужно прикинуться FJPThread-омгде-то держать WorkQueue?занять WorkQueue у ForkJoinPool?у какого ForkJoinPool?

Сделаем общесистемный пул по умолчанию= FJP common pool.

Slide 47/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 64: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Common Pool: реализация

submitter-у нужно прикинуться FJPThread-омгде-то держать WorkQueue?занять WorkQueue у ForkJoinPool?у какого ForkJoinPool?

Сделаем общесистемный пул по умолчанию= FJP common pool.

Slide 47/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 65: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Common Pool: APIpublic class MyTask

extends RecursiveAction { ... }

// submit to the pool.pool.submit(new MyTask ());

// implicitly runs in caller.// may submit to common pool.new MyTask (). invoke ();

// fire and forgetnew MyTask (). fork ();

Fork/Join – неиллюзорная часть платформы.

Slide 48/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 66: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Common Pool: APIpublic class MyTask

extends RecursiveAction { ... }

// submit to the pool.pool.submit(new MyTask ());

// implicitly runs in caller.// may submit to common pool.new MyTask (). invoke ();

// fire and forgetnew MyTask (). fork ();

Fork/Join – неиллюзорная часть платформы.

Slide 48/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 67: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Для проклятых

Slide 49/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 68: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Для проклятых: False Sharing

WorkQueue чувствительны к memory layoutfalse sharing ⇒ 1-10x slowerособенно из-за WorkQueue[] ← лягут рядом

Нас это задолбало, и мы форсировалиработы по @Contended:

@sun.misc.Contendedclass MyClass {

private int myIsolatedField;}

Slide 50/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 69: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Для проклятых: False Sharing

WorkQueue чувствительны к memory layoutfalse sharing ⇒ 1-10x slowerособенно из-за WorkQueue[] ← лягут рядом

Нас это задолбало, и мы форсировалиработы по @Contended:

@sun.misc.Contendedclass MyClass {

private int myIsolatedField;}

Slide 50/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 70: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Для проклятых: TLR

FJP нуждается в быстром ThreadLocalRandomTLR.current() ∼ ThreadLocal.get()Для критичного кода это очень плохо

Поэтому мы утащили TLR в Thread:

class Thread {long threadLocalRandomSeed;int threadLocalRandomProbe;int threadLocalRandomSecondarySeed;

}

Slide 51/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 71: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Для проклятых: TLR

FJP нуждается в быстром ThreadLocalRandomTLR.current() ∼ ThreadLocal.get()Для критичного кода это очень плохо

Поэтому мы утащили TLR в Thread:

class Thread {long threadLocalRandomSeed;int threadLocalRandomProbe;int threadLocalRandomSecondarySeed;

}

Slide 51/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 72: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Для проклятых: new intrinsics

из соображений атомарности:class ForkJoinPool {

// packed statevolatile long state;...

}

часто нужно делать апдейт конкретных битовприходится делать CAS loop

Поэтому у нас теперь естьUnsafe.getAndAddLong() сотоварищи.

Slide 52/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 73: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

Для проклятых: new intrinsics

из соображений атомарности:class ForkJoinPool {

// packed statevolatile long state;...

}

часто нужно делать апдейт конкретных битовприходится делать CAS loop

Поэтому у нас теперь естьUnsafe.getAndAddLong() сотоварищи.

Slide 52/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 74: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

: Параллелизм в моей Джаве

Fork/Join:Путь к параллелизму на платформеВсегда есть, всегда доступен, всегда готовЖёстко затюнен и тюнитсяПоддерживается платформой на всех уровняхМножество подсистем уже использует

Миллионы леммингов не могут ошибаться:JDK 8, Scala/Akka, GPars, Clojure, X10, Fortress

Slide 53/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 75: High-Performance Fork/Join - под капотом паралеллизма в ... · High-Performance Fork/Join под капотом паралеллизма в платформе

: Ссылки

JSR 166 Interest:http://g.oswego.edu/dl/concurrency-interest/

java-forkjoin-trace:https://github.com/shipilev/java-forkjoin-trace/

Slide 54/54. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.