обзор
На протяжении многих лет, благодаря существованию глобального переводчика Замок (GIL), существовало, Python В экосистеме никогда не было настоящей многопоточности, а это означает, что все потоки выполняются на одном ядре, независимо от вашего CPU Он использует только одно из тех ядер, которые у него физически есть. Эта сцена была действительно сложной. 8 Ядерные наблюдатели.
С возвращением отца Python Python уделяет все больше внимания производительности; давняя проблема GIL также оказалась на повестке дня. Из недавних обсуждений мы видим, что GIL станет необязательным после Python-3.12. Подробности см. в официальном предложении PEP 703.
GIL лицо CPU Интенсивные сцены — это действительно ловушки
Я помню, что когда я впервые начал заниматься количественным инвестированием в Python, логика была относительно простой. Я сделал всю модель сам и не использовал никаких сторонних библиотек. В то время я обнаружил проблему, когда только начал. началось. Казалось, что моя программа может использовать только одну вычислительную мощность ядра.
Позже я узнал, что GIL меня обманула, и я был неосторожен! Все в прошлом — лишь пролог, поэтому остановимся на этом. Давайте сначала построим простой сценарий с интенсивным использованием ЦП, чтобы понять, насколько жалок GIL.
#!/usr/bin/env python3
# -*- encoding: utf8 -*-
"""
Тестирование в многопоточности CPU Интенсивные сцены GIL изPerformance
"""
from concurrent.futures import ThreadPoolExecutor
def fun_sum(max_number:int = 0):
"""от 0 Накопить до max_number -1
Parameter:
----------
max_number: int
Return:
-------
int
"""
if max_number <= 0:
return 0
total = 0
for i in range(max_number):
total = total + i
print("total = {0}".format(total))
return total
def main():
threads = 8
max_number = 10000000000
with ThreadPoolExecutor(max_workers=threads) as executor:
for _ in range(threads):
executor.submit(fun_sum, max_number)
if __name__ == "__main__":
main()
1. На двухъядерной машине производительность следующая,То естьЕго может использовать только один основнойиз 100%。
2. существование 8 основнойиз На машине выглядит такиз,То естьЕго также можно использовать только с одним основным из 100% 。
Такая честная программа (сколько бы программ не было, а использует только одну), она точно не наша.
предыдущее решение
После многих лет упорной работы сообщество придумало временное решение этой проблемы. GIL Проблема Замокиз на макроуровне примерно такова: 2 Различные типы программ.
1. использовать C/C+ Напишите логику обработки, которая полностью отсутствует в существующем GIL Никаких ограничений нет, вы можете играть как хотите, это совершенно бесплатно; В конце концов, это может сделать только Python Просто вызовите соответствующую логику обработки. Это требует относительно высоких практических навыков.
2. Второе решение относительно простое: напрямую открыть еще несколько процессов, и разные процессы обрабатывают разные данные. Можно сказать, что это просто, грубо, прямо и эффективно. Давайте продемонстрируем здесь второе решение.
# Открыть два процесса
python3 mult-threads.py &
python3 mult-threads.py &
Неэлегантность – первородный грех
Два обхода, о которых мы упоминали ранее GIL Ни одно из решений не является очень элегантным. Элегантным решением должно быть следующее. GIL Замок Сними его. Не то чтобы ни один большой парень не делал этого раньше.,Просто они все потерпели неудачу。
на этот раз 703 Не так радикально, как раньше, но GIL Сделайте это опцией. При компиляции и установке укажите, хотите ли вы его скомпилировать или нет. GIL из версии. Кроме того этот Разница разизсуществовать в том, что эта оптимизация была PEP , то есть на этот раз имеет официальное одобрение。
Надеюсь, у них получится! Я тестировал его, используя внутреннюю версию,Можно сказать, что производительностьВзлет на месте!!!Python Я больше не тот маленький парень, который не умеет многопоточность.
Python Тестирование новой версии
Неудобство новой версии в том, что она требует перекомпиляции и установки интерпретатора.,И могут возникнуть некоторые проблемы совместимости, которые необходимо адаптировать в некоторых особых сценариях.,Однако в нашем примере выше несовместимости нет.,Можно проверить напрямую.
1. Ключевые параметры при компиляции
./configure --prefix=/usr/local/python-nogil --enable-optimizations
2. Если вы не измените ни одной строчки кода, вам все равно следует использовать пул потоков напрямую.
#!/usr/bin/env python3
# -*- encoding: utf8 -*-
"""
Тестирование в многопоточности CPU Интенсивные сцены GIL изPerformance
"""
from concurrent.futures import ThreadPoolExecutor
def fun_sum(max_number:int = 0):
"""от 0 Накопить до max_number -1
Parameter:
----------
max_number: int
Return:
-------
int
"""
if max_number <= 0:
return 0
total = 0
for i in range(max_number):
total = total + i
print("total = {0}".format(total))
return total
def main():
threads = 8
max_number = 10000000000
with ThreadPoolExecutor(max_workers=threads) as executor:
for _ in range(threads):
executor.submit(fun_sum, max_number)
if __name__ == "__main__":
main()
3. Запустите программу
python3 mult-threads.py &
4. Соблюдать нет GIL из CPU использовать情况
可以смотреть До этого моментаОдин процесс занимает весь процессор,Круто++!
наконец
Ответьте на «disable-gil» в личном сообщении, чтобы получить исходный код! ! !
Все здесь, пришло время встретиться снова! Я относительно real Честно говоря, я хочу увеличить количество подписчиков и помочь мне нажать «Фокусироваться». на! Качество моих технических статей хорошее, обратите внимание на не должно быть потерь.
“существоватьсмотреть” + "делиться" + "Нравиться" + "собирать" Это также мотивация для меня продолжать писать, еще раз спасибо! ! !