SlideShare a Scribd company logo
Многопоточность в JS :

Миф или реальность?
1
SAFE HARBOR
• Контент этого доклада не является
единственной истинной в последней инстанции.
• Если вы увидели что-то, что считаете
неправдой - не бойтесь сказать об этом
докладчику.
2
Кто я такой
• Меня зовут Александр.
• Software Engineer в Aeneas Platform.
• Студент в КНУ, кибернетика.
• Пишу на Scala, Java/Kotlin, C++ и JS.
• github.com/Fly-Style
3
О чем доклад
• Многопоточность

+ производительности

- сложность кода
• JS и многопоточность
4
План доклада
Memory Model
Synchronization Actions
Thread Design
Allocations
Garbage Collection
DOM Interaction
5
Текущее положение дел
• JS-engines – однопоточные.
• Неблокирующий I/O в одном потоке.
• Web-worker – не панацея.
• ChakraCore !-> napa.js.
6
Thread support : Pros
• Несколько выполняемых задач одновременно на
железе.
• Скорость выполнения программы
увеличивается.
7
Пример
!// 1

new Thread(function() { 

console.log("Hello, threads!"); 

}).join();
!// 2

new Thread(() !=> { 

console.log("Hello, lambdas inside!"); 

}).join();
8
Thread support : Pros
• Специальные структуры данных в языке для
пользовательских приложений.
• Многопоточность в помощь асинхронному
программированию.
9
Пример
async function task1() = { … };
async function task2() = { … };
const finalResult = task(await task1(), await task2());
10
Пример
const threadPool = new ThreadPool(2);
const result1 = threadPool.accept(task1);
const result2 = threadPool.accept(task2);
const finalResult = task(await result1,await result2);
11
Thread support : Cons
• Усложняется код.
• Синхронизация потоков над общими данными.
• Сложно для восприятия.
12
Давайте пофантазируем…
• Что делать инженерам V8 (JSCore, ChakraCore,
SpiderMonkey, TeaVM)?
• Сначала обратимся к основам CS.
13
Архитектура фон Неймана
• Память однородна : команды и данные
хранятся в одной памяти.
• Адресность памяти : память разделена на
нумерованные ячейки.
• Программное управление памятью : все
вычисления должны быть представлены в виде
программы, состоящей из последовательности
управляющих слов — команд.
14
Как устроена память
• Процессор (708 байт в x86-64)
• Кэши L1-L3 (1 - 16 Mб)
• RAM (4 - 64 Гб) – доступна разработчикам.
• Внешние накопители
15
Но люди не пишут
прямые команды
процессору!
16
Люди оперируют
моделями!
17
Абстрактная машина
• Абстрактная машина исполняет код на
высокоуровневом языке.
• Вас не должно волновать, каким именно
образом достигается результат.
• А вот инженеров этой самой машины - как раз
очень должно волновать.
18
Memory Model
Synchronization Actions
Thread Design
Allocations
Garbage Collection
DOM Interaction
19
Memory Model
• В последовательных программах все команды
исполняются последовательно.
• Обращения к памяти тоже происходят
последовательно.
• В многопоточных же программах все иначе : 

потоки обращаются к общей памяти, из-за чего
ожидаемого результата может и не быть!
20
Memory Model
• Формализованная модель памяти нужна для
того, чтобы специфицировать поведение
программы отношениями порядка записи и
чтения.
• А именно ответить на вопрос :
• Какое конкретное значение может увидеть
конкретное чтение в программе?
21
IRIW
atomic var a, b
Thread 1 Thread 2 Thread 3 Thread 4
a = 1 b = 1
let r1 = a
let r2 = b
let r3 = b
let r4 = a
• Какие допустимые значения кортежа 

(r1, r2, r3, r4)?
22
IRIW
atomic var a, b
Thread 1 Thread 2 Thread 3 Thread 4
a = 1 b = 1
let r1 = a
let r2 = b
let r3 = b
let r4 = a
• Например, (r1, r2, r3, r4) = (0, 1, 0, 1)
нежелателен, потому что теряется порядок
применения операций load / store.
23
IRIW
atomic var a, b
Thread 1 Thread 2 Thread 3 Thread 4
a = 1 b = 1
let r1 = a
let r2 = b
let r3 = b
let r4 = a
• В зрелых моделях памяти это ограничение
называется «multiple copy atomicity» – запись
видят или все потоки, или никакой из потоков.
24
Memory Model
• Модель памяти про определение отношений
порядков между действиями чтения/записи в
программе
• … и наложения ограничений на исполнение
программы через т.н. «барьеры чтения/записи».
25
Без ограничений на исполнение программы в каждом из
перечисленных типов порядков, получим С89 в миниатюре. 



Поэтому это нам нужно (глава 27)
26
Memory Model
Synchronization Actions
Thread Design
Allocations
Garbage Collection
DOM Interaction
27
Lock
• Для блокировки необходимы объекты
синхронизации.
• Такими объектами являются локи.
28
29
Lock
• Для блокировки необходимы объекты
синхронизации.
• Такими объектами являются локи.
• Примерами локов являются : mutex,
lock_guard, unique_lock из С++.
30
Пример Lock
let lock = new Mutex();



!//…
lock.lock();



doSomeTask();



lock.unlock();
31
Monitors
• Условные переменные (conditional variable) или
монитор.
• Храним информацию о блокировке в метаинформации
объекта, например.
32
Пример
let condVar = new СonditionalVariable();
condVar.wait(lock);



doSomeTask();



condVar.notify(); !// Notify one thread or promise.
condVar.notifyAll(); !// Notify all threads and promises.
33
Lockless / Atomic
• Хитрые хардверщики в своих изыскахЪ
подвезли нам возможность за одну инструкцию
дешево, безопасно и почти безболезненно
сделать запись в память.
• Правда есть одно «но» : применимо только для
примитивов и ссылок.
34
Пример
let atomicInt = new AtomicInteger();
atomicInt.compareAndExchange(1, 2);
!// !=> true, atomic = 2.
atomicInt.compareAndExchange(1, 3);
!// !=> false, atomic = 2.



35
Lockless / Atomic
mov %eax, 0х1

mov %rbx, 0х2

mov %rcx, 0х1

cmpxchg %rcx, %rbx
36
Lockless / Atomic : Pros
• Лучше масштабируемость.
• Применяется в lock-free структурах данных, где
важна производительность.
37
Transactional Memory
• Технология транзакционной памяти упрощает
параллельное программирование, выделяя группы
инструкций в атомарные транзакции.
• В этом случае мы считаем, что потоки работают
независимо друг от друга и в редких случаях изменяют
одни и те же данные.
38
И вот если принести вот это все
абстрактному инженеру этой самой
виртуальной машины для JS, то …
39
40
Lock`и & Atomic`и - необходимая часть языка для
того, чтобы работа с многопоточностью не
напоминала АДЪ.



Посему, оно нам надо.
41
Memory Model
Synchronization Actions
Thread Design
Allocations
Garbage Collection
DOM Interaction
42
Дизайн потоков
• Поток – это отдельная единица выполнения
кода, связанная с остальными только общей
памятью.
• Каждый поток должен иметь свои виртуальные
регистры, stack pointer и program counter.
43
Выбор «бэкэнда» для
потока
• Есть два варианта :
• Kernel thread – полноценная и отдельная нить
исполнения.
• Fiber a.k.a. Волокна – легкая нить, не
выполняется явно параллельно!
44
Варианты реализации
• Нативная вытесняющая многопоточность 

(Java, C#)
• Кооперативная многопоточность внутри VM

(Erlang).
• Виртуальная многопоточность (Python, Ruby)
45
Варианты реализации
• Нативная вытесняющая многопоточность 

(Java, C#)
• Кооперативная многопоточность внутри VM

(Erlang).
• Виртуальная многопоточность (Python, Ruby)
46
Нативная вытесняющая
многопоточность
• Каждый поток выполняется поверх
назначенному ему нативному потоку ОС.
• Переключение и планировка потоков
осуществляется планировщиком ОС.
• Так как переключения VM не контролирует,
часто внутри кода VM нужны критические
секции.
47
Дизайн класса потока
• Если дизайнить Thread как класс, то в прототипе
необходимо определить :
1. конструктор с функцией в качестве параметра, в
которой будет определён блок с параллельным
кодом.
2. метод, который будет исполнять параллельный код.
3. метод, который будет дожидаться конца
исполнения и «парковать» освободившийся поток.
48
Дизайн класса потока
class Thread {



constructor(runner: function) {…}

join(thread: Thread) {…}

start() {…}



}
49
Пример
!// 1

new Thread(() !=> { 

console.log("Hello, Thread!"); 

}).join();

!// !=> Hello, Thread!



!// 2

let print = () !=> console.log("Hello");

let thread = new Thread(print).start();

thread.join();

!// !=> Hello!
50
Memory Model
Synchronization Actions
Thread Design
Allocations
Garbage Collection
DOM Interaction
51
Выделение памяти :
проблемы
• Диспетчеры памяти обычно пишутся на языке,
отличном от языка таргета (С++ и JS).
• Поэтому выделение памяти одному потоку имеет
более-менее оправданную скорость, а вот многим -
скорее всего нет.
52
Выделение памяти :
проблемы
• Для оптимизации надо позволить потокам выделять
целые блоки памяти для своих нужд.
• Такие блоки памяти называются Thread-Local
Allocation Buffers (a.k.a. TLAB).
53
Bump pointer allocation
• Аллоцируем по адресу текущего указателя TLAB +
размер объекта.
• Если мы запрашиваем выделение объекта, который
превышает размер TLAB, мы выделяем напрямую.
54
TLAB уже реализованы.
Осталось только научить V8 отдавать эти TLAB 

в рантайм, а не только GC.
55
Memory Model
Synchronization Actions
Thread Design
Allocations
Garbage Collection
DOM Interaction
56
VM safepoint : Ideas
• Иметь безопасный доступ к памяти.
• Кооперативно остановить потоки.
• Знать, когда нам точно надо уйти на GC паузу.
57
VM safepoint : Problems
• Остановить потоки не так-то и просто.
• Во время критической секции, например.
• Или во время т.н. «короткого» цикла.
58
GC : Problems
• Определение rootset становится еще большей
проблемой : надо сканировать стеки всех потоков.
• Анализ достижимости объектов и hidden классов.
• Достижимость кода из Code Space.
59
Reachability Analysis
function f() {

let person = {age: 21, name: "Alex"};

!// GC safepoint

register(person);

}



60
Это не полный список изменений.
Полный список вызовет у вас желание плакать и
плавать в Океане Отчаянья.
Инженеров тоже.
61
Memory Model
Synchronization Actions
Thread Design
Allocations
Garbage Collection
DOM Interaction
62
DOM Interaction
• ConcurrentAccessError при попытке записи из
пользовательских потоков.
• Также запретить concurrent доступ ко всем
глобальным объектам.
• Но console, пожалуй, стоит пожалеть :)
63
В моде глобальное состояние приложения.
Concurrent DOM Interaction не нужен 🙁.
64
Conclusion
65
• Создавать виртуальные машины сложно!
• Вносить изменения в VM ещё сложнее!
• Мечтать – приятно и очень познавательно!
• Многопоточность – сложно!
• Бенефит от использования перевешивает минусы!
66
Useful books and links
1. Блог WebKit о JS Concurrency.
2. Xiao Feng Li – Advanced Design and Implementation of VM.
3. Richard Jones, Antony Hosking, Eliot Moss – GC Handbook.
67
Q/A?
68

More Related Content

What's hot

Опыт эксплуатации большого проекта на Ruby
Опыт эксплуатации большого проекта на RubyОпыт эксплуатации большого проекта на Ruby
Опыт эксплуатации большого проекта на RubyAlex Chistyakov
 
Доклад в Mail.ru 01.11.12
Доклад в Mail.ru 01.11.12Доклад в Mail.ru 01.11.12
Доклад в Mail.ru 01.11.12Alex Tutubalin
 
Лев Валкин — Кое-что про Erlang
Лев Валкин — Кое-что про ErlangЛев Валкин — Кое-что про Erlang
Лев Валкин — Кое-что про Erlang
Yury Yurevich
 
Что и почему писать на Erlang
Что и почему писать на ErlangЧто и почему писать на Erlang
Что и почему писать на Erlang
Max Lapshin
 
Modern neural net architectures - Year 2019 version
Modern neural net architectures - Year 2019 versionModern neural net architectures - Year 2019 version
Modern neural net architectures - Year 2019 version
Grigory Sapunov
 
Пишем самый быстрый хеш для кэширования данных
Пишем самый быстрый хеш для кэширования данныхПишем самый быстрый хеш для кэширования данных
Пишем самый быстрый хеш для кэширования данных
Roman Elizarov
 
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
Ontico
 
Erlang for Yandex
Erlang for YandexErlang for Yandex
Erlang for Yandex
Max Lapshin
 
Опыт использования Erlang в разработке многопользовательской игры
Опыт использования Erlang в разработке многопользовательской игрыОпыт использования Erlang в разработке многопользовательской игры
Опыт использования Erlang в разработке многопользовательской игры
Yuri Zhloba
 
"Распределенные" вычисления на мобильных платформах. Зачем еще нужен "металли...
"Распределенные" вычисления на мобильных платформах. Зачем еще нужен "металли..."Распределенные" вычисления на мобильных платформах. Зачем еще нужен "металли...
"Распределенные" вычисления на мобильных платформах. Зачем еще нужен "металли...
Ontico
 
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
Ruby Meditation
 
Клиентская Java вне браузера. Делаем нативные клиенты на Java
Клиентская Java вне браузера. Делаем нативные клиенты на JavaКлиентская Java вне браузера. Делаем нативные клиенты на Java
Клиентская Java вне браузера. Делаем нативные клиенты на Java
Nikita Lipsky
 
Вебинар: Основы распараллеливания С++ программ при помощи OpenMP
Вебинар: Основы распараллеливания С++ программ при помощи OpenMPВебинар: Основы распараллеливания С++ программ при помощи OpenMP
Вебинар: Основы распараллеливания С++ программ при помощи OpenMP
FlyElephant
 
Алексей Туля - А нужен ли вам erlang?
Алексей Туля - А нужен ли вам erlang?Алексей Туля - А нужен ли вам erlang?
Алексей Туля - А нужен ли вам erlang?
Minsk Linux User Group
 
Erlang мгновенное просветление
Erlang  мгновенное просветлениеErlang  мгновенное просветление
Erlang мгновенное просветлениеMaxim Sokhatsky
 
C++ Core Guidelines
C++ Core Guidelines C++ Core Guidelines
C++ Core Guidelines
Sergey Zubkov
 
разработка бизнес приложений (8)
разработка бизнес приложений (8)разработка бизнес приложений (8)
разработка бизнес приложений (8)
Alexander Gornik
 
BlackBox testing
BlackBox testingBlackBox testing
BlackBox testing
beched
 

What's hot (20)

Опыт эксплуатации большого проекта на Ruby
Опыт эксплуатации большого проекта на RubyОпыт эксплуатации большого проекта на Ruby
Опыт эксплуатации большого проекта на Ruby
 
Доклад в Mail.ru 01.11.12
Доклад в Mail.ru 01.11.12Доклад в Mail.ru 01.11.12
Доклад в Mail.ru 01.11.12
 
Лев Валкин — Кое-что про Erlang
Лев Валкин — Кое-что про ErlangЛев Валкин — Кое-что про Erlang
Лев Валкин — Кое-что про Erlang
 
Что и почему писать на Erlang
Что и почему писать на ErlangЧто и почему писать на Erlang
Что и почему писать на Erlang
 
Modern neural net architectures - Year 2019 version
Modern neural net architectures - Year 2019 versionModern neural net architectures - Year 2019 version
Modern neural net architectures - Year 2019 version
 
Пишем самый быстрый хеш для кэширования данных
Пишем самый быстрый хеш для кэширования данныхПишем самый быстрый хеш для кэширования данных
Пишем самый быстрый хеш для кэширования данных
 
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
 
Erlang for Yandex
Erlang for YandexErlang for Yandex
Erlang for Yandex
 
Опыт использования Erlang в разработке многопользовательской игры
Опыт использования Erlang в разработке многопользовательской игрыОпыт использования Erlang в разработке многопользовательской игры
Опыт использования Erlang в разработке многопользовательской игры
 
"Распределенные" вычисления на мобильных платформах. Зачем еще нужен "металли...
"Распределенные" вычисления на мобильных платформах. Зачем еще нужен "металли..."Распределенные" вычисления на мобильных платформах. Зачем еще нужен "металли...
"Распределенные" вычисления на мобильных платформах. Зачем еще нужен "металли...
 
Sivko
SivkoSivko
Sivko
 
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
 
Клиентская Java вне браузера. Делаем нативные клиенты на Java
Клиентская Java вне браузера. Делаем нативные клиенты на JavaКлиентская Java вне браузера. Делаем нативные клиенты на Java
Клиентская Java вне браузера. Делаем нативные клиенты на Java
 
Вебинар: Основы распараллеливания С++ программ при помощи OpenMP
Вебинар: Основы распараллеливания С++ программ при помощи OpenMPВебинар: Основы распараллеливания С++ программ при помощи OpenMP
Вебинар: Основы распараллеливания С++ программ при помощи OpenMP
 
Алексей Туля - А нужен ли вам erlang?
Алексей Туля - А нужен ли вам erlang?Алексей Туля - А нужен ли вам erlang?
Алексей Туля - А нужен ли вам erlang?
 
Erlang мгновенное просветление
Erlang  мгновенное просветлениеErlang  мгновенное просветление
Erlang мгновенное просветление
 
C++ Core Guidelines
C++ Core Guidelines C++ Core Guidelines
C++ Core Guidelines
 
JPHP
JPHPJPHP
JPHP
 
разработка бизнес приложений (8)
разработка бизнес приложений (8)разработка бизнес приложений (8)
разработка бизнес приложений (8)
 
BlackBox testing
BlackBox testingBlackBox testing
BlackBox testing
 

Similar to Multithreading in JS. Myth or reality?

CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper
CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере ResharperCodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper
CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере ResharperCodeFest
 
How to cook a blockchain and not get burned
How to cook a blockchain and not get burned How to cook a blockchain and not get burned
How to cook a blockchain and not get burned
Alexander Syrotenko
 
Константин Осипов
Константин ОсиповКонстантин Осипов
Константин Осипов
CodeFest
 
Dz Java Hi Load 0.4
Dz Java Hi Load 0.4Dz Java Hi Load 0.4
Dz Java Hi Load 0.4HighLoad2009
 
Javascript-фреймворки:
 должен остаться только один
Javascript-фреймворки:
 должен остаться только одинJavascript-фреймворки:
 должен остаться только один
Javascript-фреймворки:
 должен остаться только один
Sergey Xek
 
Javascript-фреймворки: должен остаться только один / Аверин Сергей (Acronis)
Javascript-фреймворки: должен остаться только один / Аверин Сергей (Acronis)Javascript-фреймворки: должен остаться только один / Аверин Сергей (Acronis)
Javascript-фреймворки: должен остаться только один / Аверин Сергей (Acronis)
Ontico
 
Daemons In Web on #devrus
Daemons In Web on #devrusDaemons In Web on #devrus
Daemons In Web on #devrusAlex Chistyakov
 
Excelsior JET в действии
Excelsior JET в действииExcelsior JET в действии
Excelsior JET в действии
Nikita Lipsky
 
Роман Еникеев - PHP обязан умирать
Роман Еникеев - PHP обязан умиратьРоман Еникеев - PHP обязан умирать
Роман Еникеев - PHP обязан умиратьDataArt
 
SECON'2016. Сергей Аверин. Javascript-фреймворки:
 должен остаться только один
SECON'2016. Сергей Аверин. Javascript-фреймворки:
 должен остаться только одинSECON'2016. Сергей Аверин. Javascript-фреймворки:
 должен остаться только один
SECON'2016. Сергей Аверин. Javascript-фреймворки:
 должен остаться только один
SECON
 
SECON'2016. Аверин Сергей, Javascript-фреймворки:
 должен остаться только один
SECON'2016. Аверин Сергей, Javascript-фреймворки:
 должен остаться только одинSECON'2016. Аверин Сергей, Javascript-фреймворки:
 должен остаться только один
SECON'2016. Аверин Сергей, Javascript-фреймворки:
 должен остаться только один
SECON
 
CodeFest 2014. Каплуновский Б. — Использование асинхронного I/O для снижения ...
CodeFest 2014. Каплуновский Б. — Использование асинхронного I/O для снижения ...CodeFest 2014. Каплуновский Б. — Использование асинхронного I/O для снижения ...
CodeFest 2014. Каплуновский Б. — Использование асинхронного I/O для снижения ...CodeFest
 
20 апреля, DEV {highload}, "Демоны в большом проекте – проблемы и их решения ...
20 апреля, DEV {highload}, "Демоны в большом проекте – проблемы и их решения ...20 апреля, DEV {highload}, "Демоны в большом проекте – проблемы и их решения ...
20 апреля, DEV {highload}, "Демоны в большом проекте – проблемы и их решения ...
IT-Portfolio
 
2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один
2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один
2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один
HappyDev
 
андрей паньгин
андрей паньгинандрей паньгин
андрей паньгинkuchinskaya
 
2014.12.23 Александр Андреев, Parallels
2014.12.23 Александр Андреев, Parallels2014.12.23 Александр Андреев, Parallels
2014.12.23 Александр Андреев, Parallels
Nikolay Samokhvalov
 
CodeFest 2012. Липский Н. — JIT vs. AOT. Единство и борьба динамического и ст...
CodeFest 2012. Липский Н. — JIT vs. AOT. Единство и борьба динамического и ст...CodeFest 2012. Липский Н. — JIT vs. AOT. Единство и борьба динамического и ст...
CodeFest 2012. Липский Н. — JIT vs. AOT. Единство и борьба динамического и ст...CodeFest
 
CodeFest 2013. Бурмако Е. — Макросы в Скале
CodeFest 2013. Бурмако Е. — Макросы в СкалеCodeFest 2013. Бурмако Е. — Макросы в Скале
CodeFest 2013. Бурмако Е. — Макросы в СкалеCodeFest
 
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...
Ontico
 
Lab5
Lab5Lab5

Similar to Multithreading in JS. Myth or reality? (20)

CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper
CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере ResharperCodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper
CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper
 
How to cook a blockchain and not get burned
How to cook a blockchain and not get burned How to cook a blockchain and not get burned
How to cook a blockchain and not get burned
 
Константин Осипов
Константин ОсиповКонстантин Осипов
Константин Осипов
 
Dz Java Hi Load 0.4
Dz Java Hi Load 0.4Dz Java Hi Load 0.4
Dz Java Hi Load 0.4
 
Javascript-фреймворки:
 должен остаться только один
Javascript-фреймворки:
 должен остаться только одинJavascript-фреймворки:
 должен остаться только один
Javascript-фреймворки:
 должен остаться только один
 
Javascript-фреймворки: должен остаться только один / Аверин Сергей (Acronis)
Javascript-фреймворки: должен остаться только один / Аверин Сергей (Acronis)Javascript-фреймворки: должен остаться только один / Аверин Сергей (Acronis)
Javascript-фреймворки: должен остаться только один / Аверин Сергей (Acronis)
 
Daemons In Web on #devrus
Daemons In Web on #devrusDaemons In Web on #devrus
Daemons In Web on #devrus
 
Excelsior JET в действии
Excelsior JET в действииExcelsior JET в действии
Excelsior JET в действии
 
Роман Еникеев - PHP обязан умирать
Роман Еникеев - PHP обязан умиратьРоман Еникеев - PHP обязан умирать
Роман Еникеев - PHP обязан умирать
 
SECON'2016. Сергей Аверин. Javascript-фреймворки:
 должен остаться только один
SECON'2016. Сергей Аверин. Javascript-фреймворки:
 должен остаться только одинSECON'2016. Сергей Аверин. Javascript-фреймворки:
 должен остаться только один
SECON'2016. Сергей Аверин. Javascript-фреймворки:
 должен остаться только один
 
SECON'2016. Аверин Сергей, Javascript-фреймворки:
 должен остаться только один
SECON'2016. Аверин Сергей, Javascript-фреймворки:
 должен остаться только одинSECON'2016. Аверин Сергей, Javascript-фреймворки:
 должен остаться только один
SECON'2016. Аверин Сергей, Javascript-фреймворки:
 должен остаться только один
 
CodeFest 2014. Каплуновский Б. — Использование асинхронного I/O для снижения ...
CodeFest 2014. Каплуновский Б. — Использование асинхронного I/O для снижения ...CodeFest 2014. Каплуновский Б. — Использование асинхронного I/O для снижения ...
CodeFest 2014. Каплуновский Б. — Использование асинхронного I/O для снижения ...
 
20 апреля, DEV {highload}, "Демоны в большом проекте – проблемы и их решения ...
20 апреля, DEV {highload}, "Демоны в большом проекте – проблемы и их решения ...20 апреля, DEV {highload}, "Демоны в большом проекте – проблемы и их решения ...
20 апреля, DEV {highload}, "Демоны в большом проекте – проблемы и их решения ...
 
2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один
2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один
2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один
 
андрей паньгин
андрей паньгинандрей паньгин
андрей паньгин
 
2014.12.23 Александр Андреев, Parallels
2014.12.23 Александр Андреев, Parallels2014.12.23 Александр Андреев, Parallels
2014.12.23 Александр Андреев, Parallels
 
CodeFest 2012. Липский Н. — JIT vs. AOT. Единство и борьба динамического и ст...
CodeFest 2012. Липский Н. — JIT vs. AOT. Единство и борьба динамического и ст...CodeFest 2012. Липский Н. — JIT vs. AOT. Единство и борьба динамического и ст...
CodeFest 2012. Липский Н. — JIT vs. AOT. Единство и борьба динамического и ст...
 
CodeFest 2013. Бурмако Е. — Макросы в Скале
CodeFest 2013. Бурмако Е. — Макросы в СкалеCodeFest 2013. Бурмако Е. — Макросы в Скале
CodeFest 2013. Бурмако Е. — Макросы в Скале
 
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...
 
Lab5
Lab5Lab5
Lab5
 

Multithreading in JS. Myth or reality?

  • 1. Многопоточность в JS :
 Миф или реальность? 1
  • 2. SAFE HARBOR • Контент этого доклада не является единственной истинной в последней инстанции. • Если вы увидели что-то, что считаете неправдой - не бойтесь сказать об этом докладчику. 2
  • 3. Кто я такой • Меня зовут Александр. • Software Engineer в Aeneas Platform. • Студент в КНУ, кибернетика. • Пишу на Scala, Java/Kotlin, C++ и JS. • github.com/Fly-Style 3
  • 4. О чем доклад • Многопоточность
 + производительности
 - сложность кода • JS и многопоточность 4
  • 5. План доклада Memory Model Synchronization Actions Thread Design Allocations Garbage Collection DOM Interaction 5
  • 6. Текущее положение дел • JS-engines – однопоточные. • Неблокирующий I/O в одном потоке. • Web-worker – не панацея. • ChakraCore !-> napa.js. 6
  • 7. Thread support : Pros • Несколько выполняемых задач одновременно на железе. • Скорость выполнения программы увеличивается. 7
  • 8. Пример !// 1
 new Thread(function() { 
 console.log("Hello, threads!"); 
 }).join(); !// 2
 new Thread(() !=> { 
 console.log("Hello, lambdas inside!"); 
 }).join(); 8
  • 9. Thread support : Pros • Специальные структуры данных в языке для пользовательских приложений. • Многопоточность в помощь асинхронному программированию. 9
  • 10. Пример async function task1() = { … }; async function task2() = { … }; const finalResult = task(await task1(), await task2()); 10
  • 11. Пример const threadPool = new ThreadPool(2); const result1 = threadPool.accept(task1); const result2 = threadPool.accept(task2); const finalResult = task(await result1,await result2); 11
  • 12. Thread support : Cons • Усложняется код. • Синхронизация потоков над общими данными. • Сложно для восприятия. 12
  • 13. Давайте пофантазируем… • Что делать инженерам V8 (JSCore, ChakraCore, SpiderMonkey, TeaVM)? • Сначала обратимся к основам CS. 13
  • 14. Архитектура фон Неймана • Память однородна : команды и данные хранятся в одной памяти. • Адресность памяти : память разделена на нумерованные ячейки. • Программное управление памятью : все вычисления должны быть представлены в виде программы, состоящей из последовательности управляющих слов — команд. 14
  • 15. Как устроена память • Процессор (708 байт в x86-64) • Кэши L1-L3 (1 - 16 Mб) • RAM (4 - 64 Гб) – доступна разработчикам. • Внешние накопители 15
  • 16. Но люди не пишут прямые команды процессору! 16
  • 18. Абстрактная машина • Абстрактная машина исполняет код на высокоуровневом языке. • Вас не должно волновать, каким именно образом достигается результат. • А вот инженеров этой самой машины - как раз очень должно волновать. 18
  • 19. Memory Model Synchronization Actions Thread Design Allocations Garbage Collection DOM Interaction 19
  • 20. Memory Model • В последовательных программах все команды исполняются последовательно. • Обращения к памяти тоже происходят последовательно. • В многопоточных же программах все иначе : 
 потоки обращаются к общей памяти, из-за чего ожидаемого результата может и не быть! 20
  • 21. Memory Model • Формализованная модель памяти нужна для того, чтобы специфицировать поведение программы отношениями порядка записи и чтения. • А именно ответить на вопрос : • Какое конкретное значение может увидеть конкретное чтение в программе? 21
  • 22. IRIW atomic var a, b Thread 1 Thread 2 Thread 3 Thread 4 a = 1 b = 1 let r1 = a let r2 = b let r3 = b let r4 = a • Какие допустимые значения кортежа 
 (r1, r2, r3, r4)? 22
  • 23. IRIW atomic var a, b Thread 1 Thread 2 Thread 3 Thread 4 a = 1 b = 1 let r1 = a let r2 = b let r3 = b let r4 = a • Например, (r1, r2, r3, r4) = (0, 1, 0, 1) нежелателен, потому что теряется порядок применения операций load / store. 23
  • 24. IRIW atomic var a, b Thread 1 Thread 2 Thread 3 Thread 4 a = 1 b = 1 let r1 = a let r2 = b let r3 = b let r4 = a • В зрелых моделях памяти это ограничение называется «multiple copy atomicity» – запись видят или все потоки, или никакой из потоков. 24
  • 25. Memory Model • Модель памяти про определение отношений порядков между действиями чтения/записи в программе • … и наложения ограничений на исполнение программы через т.н. «барьеры чтения/записи». 25
  • 26. Без ограничений на исполнение программы в каждом из перечисленных типов порядков, получим С89 в миниатюре. 
 
 Поэтому это нам нужно (глава 27) 26
  • 27. Memory Model Synchronization Actions Thread Design Allocations Garbage Collection DOM Interaction 27
  • 28. Lock • Для блокировки необходимы объекты синхронизации. • Такими объектами являются локи. 28
  • 29. 29
  • 30. Lock • Для блокировки необходимы объекты синхронизации. • Такими объектами являются локи. • Примерами локов являются : mutex, lock_guard, unique_lock из С++. 30
  • 31. Пример Lock let lock = new Mutex();
 
 !//… lock.lock();
 
 doSomeTask();
 
 lock.unlock(); 31
  • 32. Monitors • Условные переменные (conditional variable) или монитор. • Храним информацию о блокировке в метаинформации объекта, например. 32
  • 33. Пример let condVar = new СonditionalVariable(); condVar.wait(lock);
 
 doSomeTask();
 
 condVar.notify(); !// Notify one thread or promise. condVar.notifyAll(); !// Notify all threads and promises. 33
  • 34. Lockless / Atomic • Хитрые хардверщики в своих изыскахЪ подвезли нам возможность за одну инструкцию дешево, безопасно и почти безболезненно сделать запись в память. • Правда есть одно «но» : применимо только для примитивов и ссылок. 34
  • 35. Пример let atomicInt = new AtomicInteger(); atomicInt.compareAndExchange(1, 2); !// !=> true, atomic = 2. atomicInt.compareAndExchange(1, 3); !// !=> false, atomic = 2.
 
 35
  • 36. Lockless / Atomic mov %eax, 0х1
 mov %rbx, 0х2
 mov %rcx, 0х1
 cmpxchg %rcx, %rbx 36
  • 37. Lockless / Atomic : Pros • Лучше масштабируемость. • Применяется в lock-free структурах данных, где важна производительность. 37
  • 38. Transactional Memory • Технология транзакционной памяти упрощает параллельное программирование, выделяя группы инструкций в атомарные транзакции. • В этом случае мы считаем, что потоки работают независимо друг от друга и в редких случаях изменяют одни и те же данные. 38
  • 39. И вот если принести вот это все абстрактному инженеру этой самой виртуальной машины для JS, то … 39
  • 40. 40
  • 41. Lock`и & Atomic`и - необходимая часть языка для того, чтобы работа с многопоточностью не напоминала АДЪ.
 
 Посему, оно нам надо. 41
  • 42. Memory Model Synchronization Actions Thread Design Allocations Garbage Collection DOM Interaction 42
  • 43. Дизайн потоков • Поток – это отдельная единица выполнения кода, связанная с остальными только общей памятью. • Каждый поток должен иметь свои виртуальные регистры, stack pointer и program counter. 43
  • 44. Выбор «бэкэнда» для потока • Есть два варианта : • Kernel thread – полноценная и отдельная нить исполнения. • Fiber a.k.a. Волокна – легкая нить, не выполняется явно параллельно! 44
  • 45. Варианты реализации • Нативная вытесняющая многопоточность 
 (Java, C#) • Кооперативная многопоточность внутри VM
 (Erlang). • Виртуальная многопоточность (Python, Ruby) 45
  • 46. Варианты реализации • Нативная вытесняющая многопоточность 
 (Java, C#) • Кооперативная многопоточность внутри VM
 (Erlang). • Виртуальная многопоточность (Python, Ruby) 46
  • 47. Нативная вытесняющая многопоточность • Каждый поток выполняется поверх назначенному ему нативному потоку ОС. • Переключение и планировка потоков осуществляется планировщиком ОС. • Так как переключения VM не контролирует, часто внутри кода VM нужны критические секции. 47
  • 48. Дизайн класса потока • Если дизайнить Thread как класс, то в прототипе необходимо определить : 1. конструктор с функцией в качестве параметра, в которой будет определён блок с параллельным кодом. 2. метод, который будет исполнять параллельный код. 3. метод, который будет дожидаться конца исполнения и «парковать» освободившийся поток. 48
  • 49. Дизайн класса потока class Thread {
 
 constructor(runner: function) {…}
 join(thread: Thread) {…}
 start() {…}
 
 } 49
  • 50. Пример !// 1
 new Thread(() !=> { 
 console.log("Hello, Thread!"); 
 }).join();
 !// !=> Hello, Thread!
 
 !// 2
 let print = () !=> console.log("Hello");
 let thread = new Thread(print).start();
 thread.join();
 !// !=> Hello! 50
  • 51. Memory Model Synchronization Actions Thread Design Allocations Garbage Collection DOM Interaction 51
  • 52. Выделение памяти : проблемы • Диспетчеры памяти обычно пишутся на языке, отличном от языка таргета (С++ и JS). • Поэтому выделение памяти одному потоку имеет более-менее оправданную скорость, а вот многим - скорее всего нет. 52
  • 53. Выделение памяти : проблемы • Для оптимизации надо позволить потокам выделять целые блоки памяти для своих нужд. • Такие блоки памяти называются Thread-Local Allocation Buffers (a.k.a. TLAB). 53
  • 54. Bump pointer allocation • Аллоцируем по адресу текущего указателя TLAB + размер объекта. • Если мы запрашиваем выделение объекта, который превышает размер TLAB, мы выделяем напрямую. 54
  • 55. TLAB уже реализованы. Осталось только научить V8 отдавать эти TLAB 
 в рантайм, а не только GC. 55
  • 56. Memory Model Synchronization Actions Thread Design Allocations Garbage Collection DOM Interaction 56
  • 57. VM safepoint : Ideas • Иметь безопасный доступ к памяти. • Кооперативно остановить потоки. • Знать, когда нам точно надо уйти на GC паузу. 57
  • 58. VM safepoint : Problems • Остановить потоки не так-то и просто. • Во время критической секции, например. • Или во время т.н. «короткого» цикла. 58
  • 59. GC : Problems • Определение rootset становится еще большей проблемой : надо сканировать стеки всех потоков. • Анализ достижимости объектов и hidden классов. • Достижимость кода из Code Space. 59
  • 60. Reachability Analysis function f() {
 let person = {age: 21, name: "Alex"};
 !// GC safepoint
 register(person);
 }
 
 60
  • 61. Это не полный список изменений. Полный список вызовет у вас желание плакать и плавать в Океане Отчаянья. Инженеров тоже. 61
  • 62. Memory Model Synchronization Actions Thread Design Allocations Garbage Collection DOM Interaction 62
  • 63. DOM Interaction • ConcurrentAccessError при попытке записи из пользовательских потоков. • Также запретить concurrent доступ ко всем глобальным объектам. • Но console, пожалуй, стоит пожалеть :) 63
  • 64. В моде глобальное состояние приложения. Concurrent DOM Interaction не нужен 🙁. 64
  • 66. • Создавать виртуальные машины сложно! • Вносить изменения в VM ещё сложнее! • Мечтать – приятно и очень познавательно! • Многопоточность – сложно! • Бенефит от использования перевешивает минусы! 66
  • 67. Useful books and links 1. Блог WebKit о JS Concurrency. 2. Xiao Feng Li – Advanced Design and Implementation of VM. 3. Richard Jones, Antony Hosking, Eliot Moss – GC Handbook. 67