Upgrade to Pro — share decks privately, control downloads, hide ads and more …

GIL Demystified

GIL Demystified

Brief presentation on Python GIL and how to live with it.

Sergey Arkhipov

November 09, 2014
Tweet

More Decks by Sergey Arkhipov

Other Decks in Programming

Transcript

  1. Мифы GIL Demystified ← Что мы знаем о Gil: ―

    Работает только 1 поток! ― Многопоточности в Python нет! ― Пользуемся multiprocessing'ом! ― Или gevent'ом! ― Или tornado! ― Или Jython! ― Или Stackless!
  2. Что такое GIL GIL Demystified ← In CPython, the global

    interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython's memory management is not thread- safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.) — https://wiki.python.org/moin/GlobalInterpreterLock
  3. Что такое GIL GIL Demystified ← In CPython, the global

    interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython's memory management is not thread- safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.) — https://wiki.python.org/moin/GlobalInterpreterLock
  4. Как работает GIL GIL Demystified ← Захватил Gil Освободил Gil

    добровольно Освободил Gil принудительно Ждет Gil 100 тиков I/O I/O 100 тиков I/O
  5. Как работает GIL GIL Demystified ← Упрощенно, Gil переключается в

    2 случаях: ― Когда происходят операции I/O; ― Когда выполняются несколько виртуальных операций; ― Когда Gil переключают явно.
  6. Как работает GIL GIL Demystified ← В Python 3.2 несколько

    иной механизм: ― Когда поток не получает Gil в течение 5 мс, он не ждет пассивно, а начинает его требовать; ― После каждого тика интерпретатор проверяет, не требует ли кто-то Gil; ― Если требует — отдаем.
  7. Как работает GIL GIL Demystified ← sys.setcheckinterval(interval) Set the interpreter’s

    “check interval”. This integer value determines how often the interpreter checks for periodic things such as thread switches and signal handlers. The default is 100, meaning the check is performed every 100 Python virtual instructions. Setting it to a larger value may increase performance for programs using threads. Setting it to a value <= 0 checks every virtual instruction, maximizing responsiveness as well as overhead. — https://docs.python.org/2/library/sys.html#sys.setcheckinterval
  8. GIL Demystified In CPython, the global interpreter lock, or GIL,

    is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython's memory management is not thread- safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.) — https://wiki.python.org/moin/GlobalInterpreterLock
  9. Байткод GIL Demystified ← def bad_function(): return -1 in xrange(100000000000)

    import dis dis.dis(bad_function) 5 0 LOAD_CONST 1 (-1) 3 LOAD_GLOBAL 0 (xrange) 6 LOAD_CONST 2 (10000000000) 9 CALL_FUNCTION 1 12 COMPARE_OP 6 (in) 15 RETURN_VALUE
  10. Байткод GIL Demystified ← 5 0 LOAD_CONST 1 (-1) 3

    LOAD_GLOBAL 0 (xrange) 6 LOAD_CONST 2 (10000000000) 9 CALL_FUNCTION 1 12 COMPARE_OP 6 (in) 15 RETURN_VALUE
  11. Байткод GIL Demystified ← 5 0 LOAD_CONST 1 (-1) 3

    LOAD_GLOBAL 0 (xrange) 6 LOAD_CONST 2 (10000000000) 9 CALL_FUNCTION 1 12 COMPARE_OP 6 (in) 15 RETURN_VALUE
  12. Байткод GIL Demystified ← 5 0 LOAD_CONST 1 (-1) 3

    LOAD_GLOBAL 0 (xrange) 6 LOAD_CONST 2 (10000000000) 9 CALL_FUNCTION 1 12 COMPARE_OP 6 (in) 15 RETURN_VALUE Вызов нативного кода занимает 1 инструкцию байткода! Тик равен нескольким инструкциям байткода, гарантирующих атомарность изменения структур данных интерпретатора.
  13. GIL Demystified In CPython, the global interpreter lock, or GIL,

    is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython's memory management is not thread- safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.) — https://wiki.python.org/moin/GlobalInterpreterLock
  14. Зачем нужен GIL GIL Demystified ← ― Процессоры не могут

    исполнять несколько задач параллельно, они играют в пошаговую стратегию; ― Многоядерные процессоры играют в несколько пошаговых стратегий; ― Поток не может переключиться в процессе выполнения инструкции на процессоре; ― Потоки засыпают и просыпаются в неожиданное время.
  15. Зачем нужен GIL GIL Demystified ← ― Процессоры не могут

    исполнять несколько задач параллельно, они играют в пошаговую стратегию; ― Многоядерные процессоры играют в несколько пошаговых стратегий; ― Поток не может переключиться в процессе выполнения инструкции на процессоре; ― Потоки засыпают и просыпаются в неожиданное время. Gil защищает интерпретатор от того, что один поток проснется неожиданно для второго, и поменяет структуры в памяти интерпретатора.
  16. Зачем нужен GIL GIL Demystified ← Gil нужен всего лишь

    для 3 задач: ― Безопасно усыпить поток, чтобы он закончил работу над структурами данных интерпретатора; ― Усыпить поток в ожидаемое время, не полагаясь на планировщик ОС; ― Не дать другому потоку подняться неожиданно.
  17. Когда GIL не помеха GIL Demystified ← Когда Gil не

    помеха: ― NumPy / SciPy; ― Код без C Extensions; ― C Extensions (+Cython), работающие без Gil; ― I/O < 10K; ― PyPy-STM.