SlideShare a Scribd company logo
1 of 33
Download to read offline
Введение в потоки
GIL и новый GIL

Андрей Нехайчик
Wargaming.net
Из чего сделана эта презентация
3 доклада David Beazley:
● Inside the Python GIL, июнь 2009
● Inside the New GIL, январь 2010
● Understanding the Python GIL,
февраль 2010
http://www.dabeaz.com/GIL/

- Специфический внутряк для
разработчиков ядра питона
+ Свежие тесты
Немного о потоках
● для распараллеливания однотипных
задач
● используется pthread

Отличия от процессов
● поток – наименьшая единица обработки
● поток – составной элемент процесса
● потоки работают в едином адресном
пространстве
● потоки “дешевле” и, обычно, ОС проще
ими манипулировать
Как работают потоки в идеале
1 ядро
Как работают потоки в идеале
3 ядра
Пример
def count(n):
while n > 0:
n -= 1
t1 = Thread(target=count, args=(100000000, ))
t2 = Thread(target=count, args=(100000000, ))
t1.start()
t2.start()
t1.join()
t2.join()
Пример
def count(n):
while n > 0:
n -= 1
t1 = Thread(target=count, args=(100000000, ))
t2 = Thread(target=count, args=(100000000, ))
t1.start()
t2.start()
t1.join()
t2.join()

прекратите
тиражировать
бесполезный пример
Пример: поиск простых чисел
def is_odd_prime(num):
for multiplier in range(3, num, 2):
if num % multiplier == 0:
return False
return True
def store_odd_primes(storage, max_number, start_number=3):
for num in range(start_number, max_number + 1, 2):
if is_odd_prime(num):
storage.append(num)
numbers = [2]
store_odd_primes(numbers, 20000)
store_odd_primes(numbers, 40000, start_number=20001)
print len(numbers)
Пример: поиск простых чисел
from threading import Thread
...
numbers = [2]
thread1=Thread(target=store_odd_primes, args=(numbers, 20000, ))
thread1.start()
thread2=Thread(target=store_odd_primes, args=(numbers, 40000, ),
kwargs={'start_number': 20001})
thread2.start()
thread1.join()
thread2.join()
print len(numbers)
Результаты
Поиск простых чисел до 40000
неоптимальным алгоритмом
Окружение

Последовательное
выполнение

2 потока
(1 ядро)

2 потока
(2 ядра)

python 2.7.5
(2GHz, Gentoo)

5.40

5.41

5.92 (+10%)

python 3.2.5

8.80

9.02

12.11 (+40%)

python 3.3.3

8.90

8.90

12.20 (+40%)

python 2.7.3
(1GHz, iOS 7, iPad 3)

23.90

-

25.30 (+5%)

python 2.7.2
(2.5GHz, OS X 10.8)

3.56

-

3.90 (+10%)
Потоки в Python
● Существует GIL и гарантирует
последовательное выполнение байткода
● Каждые 100 тиков: освобождение и захват
GIL
● 1 тик – одна или более инструкций
байткода
● IO освобождает GIL
● Си-модули могут освобождать GIL
● Освобождение и захват GIL –
дополнительные накладные расходы
Потоки в Python
Обработка сигналов
Профилирование однопоточной
программы
python -m cProfile prime_seq.py
ncalls
1
1

tottime
0.001
0.015

9999
1229

0.797
0.001

1

0.000

# 10000

filename:lineno(function)
prime_seq.py:1(<module>)
prime_seq.py:3
(get_prime_list)
prime_seq.py:5(is_prime)
{method 'append' of
'list' objects}
{method 'disable' of
'_lsprof.Profiler' objects}
Профилирование многопоточной
программы
ncalls tottime percall cumtime percall filename:lineno(function)
………
2

0.000

0.000

0.886

0.443 threading.py:909(join)

25

0.886

0.035

0.886

0.035 {method 'acquire' of 'thread.lock'}

97

0.000

0.000

0.000

0.000 {method 'append' of 'list'}

1

0.000

0.000

0.000

0.000 {method 'disable' of

………

'_lsprof.Profiler'}
2

0.000

0.000

0.000

0.000 {method 'extend' of 'list'}

2

0.000

0.000

0.000

0.000 {method 'get' of 'dict'}

1

0.000

0.000

0.000

0.000 {method 'insert' of 'list'}

2

0.000

0.000

0.000

0.000 {method 'items' of 'dict'}

1

0.000

0.000

0.000

0.000 {method 'lower' of 'str'}

12

0.000

0.000

0.000

0.000 {method 'release' of 'thread.lock'}

1

0.000

0.000

0.000

0.000 {method 'rfind' of 'str'}

2

0.000

0.000

0.000

0.000 {method 'setter' of 'property'}

6

0.000

0.000

0.000

0.000 {method 'write' of 'file'}
Вернёмся к начальному примеру
def count(n):
while n > 0:
n -= 1
Последовательное

2 потока
(2 ядра)

Разница

python 2.7.5,
Gentoo, 2Ghz

20.0

27.7

x1.4

python 3.2.5

19.7

34.5

x1.8

David Beazley
OS X, 2GHz

24.6

45.5

x1.8

python 2.7.2
OS X 10.8, 2.5 Ghz i5

15.2

23.7

x1.6
Почему такие большие накладные
расходы (1 ядро)?
Почему такие большие накладные
расходы (2 ядра)?
Визуализация попыток захвата
Промежуточные итоги
● Код параллельно не выполняется
● Но IO (всегда) и CPython расширения
(некоторые) освобождают GIL
● Нет планировщика потоков
● Сигналы обрабатываются в главном
потоке
● Потоки с интенсивным использованием
CPU передерживают GIL
● Провальные попытки захвата GIL
Зачем нужен GIL?
● Защита операций работы с памятью в
ядре
● Упрощение кода
● Скорость выше, если код проще
GIL в python 3.2
● Первое серьёзное изменение со времён
1992 года
● Вместо счётчика тиков - gil_drop_request
● Также добавлен таймаут в 5мс
Как это работает?
Проблемы с таймаутом
Проблемы из-за отсутствия
планировщика
Замедление IO
Какие планы по GIL
Его заменят, если новый подход будет:
● простым
● увеличит скорость для многопоточных
программ
● не изменит скорость для однопоточных
● будет совместим с текущим API ядра
● оставит такое же поведение GC
Как обойти GIL
● Для IO этого делать не надо
● Использовать специализированные
библиотеки:
https://wiki.python.org/moin/ParallelProcessing

(например scipy)
● Использовать другие интерпретаторы
● Использовать multiprocessing
Использовать другие
интерпретаторы
Последовательное

2 потока
(2 ядра)

4 потока
(4 ядра)

jython 2.5.3
(Gentoo, i3 3Ghz)

10.70

8.65 (x1.24)

6.85 (x1.56)

pypy 2.0.2
(Gentoo, i3 3Ghz)

2.75

2.85

2.90
Multiprocessing
from multiprocessing import Process, Pipe
…
def store_odd_primes(pipe_conn, max_number, start_number=3):
storage = []
for num in range(start_number, max_number + 1, 2):
if is_odd_prime(num):
storage.append(num)
pipe_conn.send(storage)
numbers = [2]
parent_conn, child_conn = Pipe()
proc1 = Process(target=store_odd_primes, args=(child_conn, 20000, ))
proc2 = Process(target=store_odd_primes, args=(child_conn, 40000, ),
kwargs={'start_number': 20001})
proc1.start();proc2.start();proc1.join();proc2.join()
numbers += parent_conn.recv()
numbers += parent_conn.recv()
print len(numbers)
Multiprocessing
Последовательное

2 процесса
(2 ядра)

4 потока
(4 ядра)

python 2.6.8
(Gentoo, i3 3Ghz)

3.80

2.80 (x1.35)

2.08 (x1.83)

python 3.2.5
(Gentoo, i3 3Ghz)

5.05

3.68 (x1.37)

3.10 (x1.63)

pypy 2.0.2
(Gentoo, i3 3Ghz)

0.50

0.42 (x1.20)

0.33 (x1.55)
Выводы
● Параллельной многопоточности в Python
по умолчанию нет
● Она частично существует для
специализированных расширений и
операций IO
● GIL почти никогда не мешает
● А когда мешает мы знаем как с этим
бороться
Спасибо.

More Related Content

What's hot

Dynamic Language Runtime
Dynamic Language RuntimeDynamic Language Runtime
Dynamic Language RuntimeSQALab
 
Разработка real-time приложений с RethinkDB / Илья Вербицкий (Независимый кон...
Разработка real-time приложений с RethinkDB / Илья Вербицкий (Независимый кон...Разработка real-time приложений с RethinkDB / Илья Вербицкий (Независимый кон...
Разработка real-time приложений с RethinkDB / Илья Вербицкий (Независимый кон...Ontico
 
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...Ontico
 
Гареев Роман, Создание генератора промежуточного представления Ssa из полиэдр...
Гареев Роман, Создание генератора промежуточного представления Ssa из полиэдр...Гареев Роман, Создание генератора промежуточного представления Ssa из полиэдр...
Гареев Роман, Создание генератора промежуточного представления Ssa из полиэдр...Darya Zubova
 
Автоматическая оптимизация алгоритмов с помощью быстрого возведения матриц в ...
Автоматическая оптимизация алгоритмов с помощью быстрого возведения матриц в ...Автоматическая оптимизация алгоритмов с помощью быстрого возведения матриц в ...
Автоматическая оптимизация алгоритмов с помощью быстрого возведения матриц в ...Alexander Borzunov
 
разработка серверов и серверных приложений лекция №2
разработка серверов и серверных приложений лекция №2разработка серверов и серверных приложений лекция №2
разработка серверов и серверных приложений лекция №2Eugeniy Tyumentcev
 
ПВТ - осень 2014 - лекция 1 - Введение в параллельные вычисления
ПВТ - осень 2014 - лекция 1 - Введение в параллельные вычисленияПВТ - осень 2014 - лекция 1 - Введение в параллельные вычисления
ПВТ - осень 2014 - лекция 1 - Введение в параллельные вычисленияAlexey Paznikov
 
PostgreSQL: практические примеры оптимизации SQL-запросов / Иван Фролков (Po...
PostgreSQL: практические примеры оптимизации SQL-запросов /  Иван Фролков (Po...PostgreSQL: практические примеры оптимизации SQL-запросов /  Иван Фролков (Po...
PostgreSQL: практические примеры оптимизации SQL-запросов / Иван Фролков (Po...Ontico
 
ПВТ - осень 2014 - Лекция 2 - Архитектура вычислительных систем с общей памятью
ПВТ - осень 2014 - Лекция 2 - Архитектура вычислительных систем с общей памятьюПВТ - осень 2014 - Лекция 2 - Архитектура вычислительных систем с общей памятью
ПВТ - осень 2014 - Лекция 2 - Архитектура вычислительных систем с общей памятьюAlexey Paznikov
 
Доклад Антона Поварова на Tarantool Meetup. "Tarantool в Badoo: хранение исто...
Доклад Антона Поварова на Tarantool Meetup. "Tarantool в Badoo: хранение исто...Доклад Антона Поварова на Tarantool Meetup. "Tarantool в Badoo: хранение исто...
Доклад Антона Поварова на Tarantool Meetup. "Tarantool в Badoo: хранение исто...Badoo Development
 
SECON'2016. Сигаев Федор, Pg в кластере. Скандалы, интриги, расследования
SECON'2016. Сигаев Федор, Pg в кластере. Скандалы, интриги, расследованияSECON'2016. Сигаев Федор, Pg в кластере. Скандалы, интриги, расследования
SECON'2016. Сигаев Федор, Pg в кластере. Скандалы, интриги, расследованияSECON
 
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Yandex
 
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...Alexey Paznikov
 
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...Ontico
 
Семинар 11. Параллельное программирование на MPI (часть 4)
Семинар 11. Параллельное программирование на MPI (часть 4)Семинар 11. Параллельное программирование на MPI (часть 4)
Семинар 11. Параллельное программирование на MPI (часть 4)Mikhail Kurnosov
 
Введение в Python и Django
Введение в Python и DjangoВведение в Python и Django
Введение в Python и DjangoTaras Lyapun
 

What's hot (16)

Dynamic Language Runtime
Dynamic Language RuntimeDynamic Language Runtime
Dynamic Language Runtime
 
Разработка real-time приложений с RethinkDB / Илья Вербицкий (Независимый кон...
Разработка real-time приложений с RethinkDB / Илья Вербицкий (Независимый кон...Разработка real-time приложений с RethinkDB / Илья Вербицкий (Независимый кон...
Разработка real-time приложений с RethinkDB / Илья Вербицкий (Независимый кон...
 
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
 
Гареев Роман, Создание генератора промежуточного представления Ssa из полиэдр...
Гареев Роман, Создание генератора промежуточного представления Ssa из полиэдр...Гареев Роман, Создание генератора промежуточного представления Ssa из полиэдр...
Гареев Роман, Создание генератора промежуточного представления Ssa из полиэдр...
 
Автоматическая оптимизация алгоритмов с помощью быстрого возведения матриц в ...
Автоматическая оптимизация алгоритмов с помощью быстрого возведения матриц в ...Автоматическая оптимизация алгоритмов с помощью быстрого возведения матриц в ...
Автоматическая оптимизация алгоритмов с помощью быстрого возведения матриц в ...
 
разработка серверов и серверных приложений лекция №2
разработка серверов и серверных приложений лекция №2разработка серверов и серверных приложений лекция №2
разработка серверов и серверных приложений лекция №2
 
ПВТ - осень 2014 - лекция 1 - Введение в параллельные вычисления
ПВТ - осень 2014 - лекция 1 - Введение в параллельные вычисленияПВТ - осень 2014 - лекция 1 - Введение в параллельные вычисления
ПВТ - осень 2014 - лекция 1 - Введение в параллельные вычисления
 
PostgreSQL: практические примеры оптимизации SQL-запросов / Иван Фролков (Po...
PostgreSQL: практические примеры оптимизации SQL-запросов /  Иван Фролков (Po...PostgreSQL: практические примеры оптимизации SQL-запросов /  Иван Фролков (Po...
PostgreSQL: практические примеры оптимизации SQL-запросов / Иван Фролков (Po...
 
ПВТ - осень 2014 - Лекция 2 - Архитектура вычислительных систем с общей памятью
ПВТ - осень 2014 - Лекция 2 - Архитектура вычислительных систем с общей памятьюПВТ - осень 2014 - Лекция 2 - Архитектура вычислительных систем с общей памятью
ПВТ - осень 2014 - Лекция 2 - Архитектура вычислительных систем с общей памятью
 
Доклад Антона Поварова на Tarantool Meetup. "Tarantool в Badoo: хранение исто...
Доклад Антона Поварова на Tarantool Meetup. "Tarantool в Badoo: хранение исто...Доклад Антона Поварова на Tarantool Meetup. "Tarantool в Badoo: хранение исто...
Доклад Антона Поварова на Tarantool Meetup. "Tarantool в Badoo: хранение исто...
 
SECON'2016. Сигаев Федор, Pg в кластере. Скандалы, интриги, расследования
SECON'2016. Сигаев Федор, Pg в кластере. Скандалы, интриги, расследованияSECON'2016. Сигаев Федор, Pg в кластере. Скандалы, интриги, расследования
SECON'2016. Сигаев Федор, Pg в кластере. Скандалы, интриги, расследования
 
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
 
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
 
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
 
Семинар 11. Параллельное программирование на MPI (часть 4)
Семинар 11. Параллельное программирование на MPI (часть 4)Семинар 11. Параллельное программирование на MPI (часть 4)
Семинар 11. Параллельное программирование на MPI (часть 4)
 
Введение в Python и Django
Введение в Python и DjangoВведение в Python и Django
Введение в Python и Django
 

Similar to Введение в потоки питона

Михаил Коробов: Как перейти на Python 3
Михаил Коробов: Как перейти на Python 3Михаил Коробов: Как перейти на Python 3
Михаил Коробов: Как перейти на Python 3it-people
 
Разработка декстопных приложений для linux (Владимир Яковлев)
Разработка декстопных приложений для linux (Владимир Яковлев)Разработка декстопных приложений для linux (Владимир Яковлев)
Разработка декстопных приложений для linux (Владимир Яковлев)IT-Доминанта
 
Плюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав БахмутовПлюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав БахмутовYandex
 
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотекSWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотекPython Meetup
 
BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...
BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...
BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...Ontico
 
Плюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав БахмутовПлюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав БахмутовYandex
 
Владислав Грязнов "Многозадачность в PHP"
Владислав Грязнов "Многозадачность в PHP"Владислав Грязнов "Многозадачность в PHP"
Владислав Грязнов "Многозадачность в PHP"Fwdays
 
Сетевой инженер 2.0. Что нужно знать о программируемости в корпоративной сети?
Сетевой инженер 2.0. Что нужно знать о программируемости в корпоративной сети?Сетевой инженер 2.0. Что нужно знать о программируемости в корпоративной сети?
Сетевой инженер 2.0. Что нужно знать о программируемости в корпоративной сети?Cisco Russia
 
Практические приёмы оптимизации .NET-приложений
Практические приёмы оптимизации .NET-приложенийПрактические приёмы оптимизации .NET-приложений
Практические приёмы оптимизации .NET-приложенийAndrey Akinshin
 
Evgeny Rybak Presentation
Evgeny Rybak PresentationEvgeny Rybak Presentation
Evgeny Rybak Presentationsef2009
 
По ту сторону ООП: PEAK-Rules и PyProtocols
По ту сторону ООП: PEAK-Rules и PyProtocolsПо ту сторону ООП: PEAK-Rules и PyProtocols
По ту сторону ООП: PEAK-Rules и PyProtocolsSergey Schetinin
 
Построение мультисервисного стартапа в реалиях full-stack javascript
Построение мультисервисного стартапа в реалиях full-stack javascriptПостроение мультисервисного стартапа в реалиях full-stack javascript
Построение мультисервисного стартапа в реалиях full-stack javascriptFDConf
 
Параллельное программирование на современных видеокартах
Параллельное программирование на современных видеокартахПараллельное программирование на современных видеокартах
Параллельное программирование на современных видеокартахAlex Tutubalin
 
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияДракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияPlatonov Sergey
 
Евгений Лазин. Неизменяемая структура данных HAMT для создания БД в памяти
Евгений Лазин. Неизменяемая структура данных HAMT для создания БД в памятиЕвгений Лазин. Неизменяемая структура данных HAMT для создания БД в памяти
Евгений Лазин. Неизменяемая структура данных HAMT для создания БД в памятиFProg
 
Flame graph: новый взгляд на старое профилирование
Flame graph: новый взгляд на старое профилированиеFlame graph: новый взгляд на старое профилирование
Flame graph: новый взгляд на старое профилированиеКирилл Борисов
 
Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва...
 Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва... Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва...
Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва...Nikolay Samokhvalov
 
CodeFest 2013. Лузин А. — Бэкенд-винегрет: как подружить разные ЯП на ваших с...
CodeFest 2013. Лузин А. — Бэкенд-винегрет: как подружить разные ЯП на ваших с...CodeFest 2013. Лузин А. — Бэкенд-винегрет: как подружить разные ЯП на ваших с...
CodeFest 2013. Лузин А. — Бэкенд-винегрет: как подружить разные ЯП на ваших с...CodeFest
 

Similar to Введение в потоки питона (20)

Михаил Коробов: Как перейти на Python 3
Михаил Коробов: Как перейти на Python 3Михаил Коробов: Как перейти на Python 3
Михаил Коробов: Как перейти на Python 3
 
Разработка декстопных приложений для linux (Владимир Яковлев)
Разработка декстопных приложений для linux (Владимир Яковлев)Разработка декстопных приложений для linux (Владимир Яковлев)
Разработка декстопных приложений для linux (Владимир Яковлев)
 
Плюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав БахмутовПлюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
 
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотекSWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
 
BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...
BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...
BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...
 
Плюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав БахмутовПлюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
 
Владислав Грязнов "Многозадачность в PHP"
Владислав Грязнов "Многозадачность в PHP"Владислав Грязнов "Многозадачность в PHP"
Владислав Грязнов "Многозадачность в PHP"
 
Сетевой инженер 2.0. Что нужно знать о программируемости в корпоративной сети?
Сетевой инженер 2.0. Что нужно знать о программируемости в корпоративной сети?Сетевой инженер 2.0. Что нужно знать о программируемости в корпоративной сети?
Сетевой инженер 2.0. Что нужно знать о программируемости в корпоративной сети?
 
Git for you
Git for youGit for you
Git for you
 
Практические приёмы оптимизации .NET-приложений
Практические приёмы оптимизации .NET-приложенийПрактические приёмы оптимизации .NET-приложений
Практические приёмы оптимизации .NET-приложений
 
Evgeny Rybak Presentation
Evgeny Rybak PresentationEvgeny Rybak Presentation
Evgeny Rybak Presentation
 
По ту сторону ООП: PEAK-Rules и PyProtocols
По ту сторону ООП: PEAK-Rules и PyProtocolsПо ту сторону ООП: PEAK-Rules и PyProtocols
По ту сторону ООП: PEAK-Rules и PyProtocols
 
Построение мультисервисного стартапа в реалиях full-stack javascript
Построение мультисервисного стартапа в реалиях full-stack javascriptПостроение мультисервисного стартапа в реалиях full-stack javascript
Построение мультисервисного стартапа в реалиях full-stack javascript
 
Параллельное программирование на современных видеокартах
Параллельное программирование на современных видеокартахПараллельное программирование на современных видеокартах
Параллельное программирование на современных видеокартах
 
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияДракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
 
Евгений Лазин. Неизменяемая структура данных HAMT для создания БД в памяти
Евгений Лазин. Неизменяемая структура данных HAMT для создания БД в памятиЕвгений Лазин. Неизменяемая структура данных HAMT для создания БД в памяти
Евгений Лазин. Неизменяемая структура данных HAMT для создания БД в памяти
 
Purely practical data structures
Purely practical data structuresPurely practical data structures
Purely practical data structures
 
Flame graph: новый взгляд на старое профилирование
Flame graph: новый взгляд на старое профилированиеFlame graph: новый взгляд на старое профилирование
Flame graph: новый взгляд на старое профилирование
 
Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва...
 Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва... Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва...
Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва...
 
CodeFest 2013. Лузин А. — Бэкенд-винегрет: как подружить разные ЯП на ваших с...
CodeFest 2013. Лузин А. — Бэкенд-винегрет: как подружить разные ЯП на ваших с...CodeFest 2013. Лузин А. — Бэкенд-винегрет: как подружить разные ЯП на ваших с...
CodeFest 2013. Лузин А. — Бэкенд-винегрет: как подружить разные ЯП на ваших с...
 

Введение в потоки питона

  • 1. Введение в потоки GIL и новый GIL Андрей Нехайчик Wargaming.net
  • 2. Из чего сделана эта презентация 3 доклада David Beazley: ● Inside the Python GIL, июнь 2009 ● Inside the New GIL, январь 2010 ● Understanding the Python GIL, февраль 2010 http://www.dabeaz.com/GIL/ - Специфический внутряк для разработчиков ядра питона + Свежие тесты
  • 3. Немного о потоках ● для распараллеливания однотипных задач ● используется pthread Отличия от процессов ● поток – наименьшая единица обработки ● поток – составной элемент процесса ● потоки работают в едином адресном пространстве ● потоки “дешевле” и, обычно, ОС проще ими манипулировать
  • 4. Как работают потоки в идеале 1 ядро
  • 5. Как работают потоки в идеале 3 ядра
  • 6. Пример def count(n): while n > 0: n -= 1 t1 = Thread(target=count, args=(100000000, )) t2 = Thread(target=count, args=(100000000, )) t1.start() t2.start() t1.join() t2.join()
  • 7. Пример def count(n): while n > 0: n -= 1 t1 = Thread(target=count, args=(100000000, )) t2 = Thread(target=count, args=(100000000, )) t1.start() t2.start() t1.join() t2.join() прекратите тиражировать бесполезный пример
  • 8. Пример: поиск простых чисел def is_odd_prime(num): for multiplier in range(3, num, 2): if num % multiplier == 0: return False return True def store_odd_primes(storage, max_number, start_number=3): for num in range(start_number, max_number + 1, 2): if is_odd_prime(num): storage.append(num) numbers = [2] store_odd_primes(numbers, 20000) store_odd_primes(numbers, 40000, start_number=20001) print len(numbers)
  • 9. Пример: поиск простых чисел from threading import Thread ... numbers = [2] thread1=Thread(target=store_odd_primes, args=(numbers, 20000, )) thread1.start() thread2=Thread(target=store_odd_primes, args=(numbers, 40000, ), kwargs={'start_number': 20001}) thread2.start() thread1.join() thread2.join() print len(numbers)
  • 10. Результаты Поиск простых чисел до 40000 неоптимальным алгоритмом Окружение Последовательное выполнение 2 потока (1 ядро) 2 потока (2 ядра) python 2.7.5 (2GHz, Gentoo) 5.40 5.41 5.92 (+10%) python 3.2.5 8.80 9.02 12.11 (+40%) python 3.3.3 8.90 8.90 12.20 (+40%) python 2.7.3 (1GHz, iOS 7, iPad 3) 23.90 - 25.30 (+5%) python 2.7.2 (2.5GHz, OS X 10.8) 3.56 - 3.90 (+10%)
  • 11. Потоки в Python ● Существует GIL и гарантирует последовательное выполнение байткода ● Каждые 100 тиков: освобождение и захват GIL ● 1 тик – одна или более инструкций байткода ● IO освобождает GIL ● Си-модули могут освобождать GIL ● Освобождение и захват GIL – дополнительные накладные расходы
  • 14. Профилирование однопоточной программы python -m cProfile prime_seq.py ncalls 1 1 tottime 0.001 0.015 9999 1229 0.797 0.001 1 0.000 # 10000 filename:lineno(function) prime_seq.py:1(<module>) prime_seq.py:3 (get_prime_list) prime_seq.py:5(is_prime) {method 'append' of 'list' objects} {method 'disable' of '_lsprof.Profiler' objects}
  • 15. Профилирование многопоточной программы ncalls tottime percall cumtime percall filename:lineno(function) ……… 2 0.000 0.000 0.886 0.443 threading.py:909(join) 25 0.886 0.035 0.886 0.035 {method 'acquire' of 'thread.lock'} 97 0.000 0.000 0.000 0.000 {method 'append' of 'list'} 1 0.000 0.000 0.000 0.000 {method 'disable' of ……… '_lsprof.Profiler'} 2 0.000 0.000 0.000 0.000 {method 'extend' of 'list'} 2 0.000 0.000 0.000 0.000 {method 'get' of 'dict'} 1 0.000 0.000 0.000 0.000 {method 'insert' of 'list'} 2 0.000 0.000 0.000 0.000 {method 'items' of 'dict'} 1 0.000 0.000 0.000 0.000 {method 'lower' of 'str'} 12 0.000 0.000 0.000 0.000 {method 'release' of 'thread.lock'} 1 0.000 0.000 0.000 0.000 {method 'rfind' of 'str'} 2 0.000 0.000 0.000 0.000 {method 'setter' of 'property'} 6 0.000 0.000 0.000 0.000 {method 'write' of 'file'}
  • 16. Вернёмся к начальному примеру def count(n): while n > 0: n -= 1 Последовательное 2 потока (2 ядра) Разница python 2.7.5, Gentoo, 2Ghz 20.0 27.7 x1.4 python 3.2.5 19.7 34.5 x1.8 David Beazley OS X, 2GHz 24.6 45.5 x1.8 python 2.7.2 OS X 10.8, 2.5 Ghz i5 15.2 23.7 x1.6
  • 17. Почему такие большие накладные расходы (1 ядро)?
  • 18. Почему такие большие накладные расходы (2 ядра)?
  • 20. Промежуточные итоги ● Код параллельно не выполняется ● Но IO (всегда) и CPython расширения (некоторые) освобождают GIL ● Нет планировщика потоков ● Сигналы обрабатываются в главном потоке ● Потоки с интенсивным использованием CPU передерживают GIL ● Провальные попытки захвата GIL
  • 21. Зачем нужен GIL? ● Защита операций работы с памятью в ядре ● Упрощение кода ● Скорость выше, если код проще
  • 22. GIL в python 3.2 ● Первое серьёзное изменение со времён 1992 года ● Вместо счётчика тиков - gil_drop_request ● Также добавлен таймаут в 5мс
  • 27. Какие планы по GIL Его заменят, если новый подход будет: ● простым ● увеличит скорость для многопоточных программ ● не изменит скорость для однопоточных ● будет совместим с текущим API ядра ● оставит такое же поведение GC
  • 28. Как обойти GIL ● Для IO этого делать не надо ● Использовать специализированные библиотеки: https://wiki.python.org/moin/ParallelProcessing (например scipy) ● Использовать другие интерпретаторы ● Использовать multiprocessing
  • 29. Использовать другие интерпретаторы Последовательное 2 потока (2 ядра) 4 потока (4 ядра) jython 2.5.3 (Gentoo, i3 3Ghz) 10.70 8.65 (x1.24) 6.85 (x1.56) pypy 2.0.2 (Gentoo, i3 3Ghz) 2.75 2.85 2.90
  • 30. Multiprocessing from multiprocessing import Process, Pipe … def store_odd_primes(pipe_conn, max_number, start_number=3): storage = [] for num in range(start_number, max_number + 1, 2): if is_odd_prime(num): storage.append(num) pipe_conn.send(storage) numbers = [2] parent_conn, child_conn = Pipe() proc1 = Process(target=store_odd_primes, args=(child_conn, 20000, )) proc2 = Process(target=store_odd_primes, args=(child_conn, 40000, ), kwargs={'start_number': 20001}) proc1.start();proc2.start();proc1.join();proc2.join() numbers += parent_conn.recv() numbers += parent_conn.recv() print len(numbers)
  • 31. Multiprocessing Последовательное 2 процесса (2 ядра) 4 потока (4 ядра) python 2.6.8 (Gentoo, i3 3Ghz) 3.80 2.80 (x1.35) 2.08 (x1.83) python 3.2.5 (Gentoo, i3 3Ghz) 5.05 3.68 (x1.37) 3.10 (x1.63) pypy 2.0.2 (Gentoo, i3 3Ghz) 0.50 0.42 (x1.20) 0.33 (x1.55)
  • 32. Выводы ● Параллельной многопоточности в Python по умолчанию нет ● Она частично существует для специализированных расширений и операций IO ● GIL почти никогда не мешает ● А когда мешает мы знаем как с этим бороться