и посмотреть медиа
Zen of Python - дзен
и посмотреть медиа
Полный гид по философии и практике Python в одном канале.
Полный гид по философии и практике Python в одном канале.
Zen of Python - канал, посвящённый философии и практикам Python. Уроки, скрипты, лучшие практики и материалы для освоения языка в Telegram.
Многопоточный NumPy на сборке без GIL был в 7 раз медленнее процессов, стал в 4 раза быстрее Всё началось с вопроса на Stack Overflow: пользователь пожаловался, что на сборке CPython без GIL расчёт через ThreadPoolExecutor заметно медленнее того же расчёта через ProcessPoolExecutor. Кумар Адитья из Quansight Labs описал 29 июля, как несколько месяцев вычищал причины этого в NumPy и самом CPython. Нагрузка простая и типичная для ufunc: каждый работник берёт свой массив, гоняет по нему np.sin и np.cos в цикле и сворачивает результат. Общего изменяемого состояния между потоками нет, так что масштабироваться оно должно линейно. На деле до 18 потоков росло, а дальше резко деградировало: на 32 работниках 44 секунды против 6 у процессов. Профилирование через samply показало три класса проблем: конкуренция за блокировки, конкуренция за счётчики ссылок общих объектов и конкуренция в аллокаторе. 🔘 tracemalloc выключен по умолчанию, но всё равно брал глобальную блокировку на каждом выделении и освобождении памяти, просто чтобы проверить, включён ли он. Теперь проверка идёт атомарной операцией без блокировки; 🔘 кэш диспетчеризации ufunc, который сопоставляет типам аргументов конкретную реализацию, жил под std::shared_mutex. Записи в нём неизменяемы, поэтому чтение сделали полностью свободным от блокировок, мьютекс остался только на редкие вставки; 🔘 указатель на аллокатор памяти NumPy хранит в глобальном объекте PyCapsule. Без GIL каждое обращение к нему меняет счётчик ссылок атомарно, и кэш-линия со счётчиком начинает метаться между ядрами. Объект сделали бессмертным, то есть вообще без подсчёта ссылок; 🔘 ради этого в CPython появился публичный PyUnstable_SetImmortal: с 3.15 он доступен всем, на 3.14 его можно взять через pythoncapi-compat; 🔘 запись np.sin — это поиск атрибута в модуле, а специализация байткода для таких поисков не работала, если модуль определяет __getattr__. Каждый вызов уходил на медленный путь с захватом импортной блокировки; 🔘 массивы NumPy выделял системным malloc, который плохо переносит параллельные выделения, особенно на macOS. Сырой аллокатор CPython в сборке без GIL перевели на mimalloc, а NumPy переключили на этот сырой аллокатор. После всех правок та же задача на 32 ядрах занимает около 1,5 секунды: примерно в 30 раз быстрее, чем было, и вчетверо быстрее варианта с процессами. Автор оговаривает, что замеры сделаны на одной 32-ядерной машине с Linux и на конкретной ufunc-нагрузке без общего состояния между потоками. Полная статья: Ссылка скрыта @zen_of_python
Открыть канал и посмотреть медиаOnly registered users can share their opinion.
Be the first to share your impression of this resource!
Bot to save posts from closed channels and groups.
A selection of profitable offers, discounts and promotions.
Channel archive on men K-pop group NINE.i: debut, albums, photos and updates in Telegram.