Какова стоимость выпуска GIL? - PullRequest
7 голосов
/ 22 октября 2011

Предположим, у меня есть функция расширения C, которая делает что-то полностью независимое от интерпретатора Python. Есть ли причина , а не , чтобы освободить GIL?

Например, есть ли причина не писать такой код (кроме таких вопросов, как читаемость и избегание микрооптимизации - вещи, которые важны, но не имеют отношения к моему вопросу)?

Py_BEGIN_ALLOW_THREADS
    a = 1 + 1;
Py_END_ALLOW_THREADS

Очевидно, что это тривиальный код, производительность которого, вероятно, не будет иметь большого значения. Но есть ли причина производительности , а не для выпуска GIL здесь? Или GIL должен быть выпущен только для более ресурсоемкого кода?

Ответы [ 4 ]

7 голосов
/ 22 октября 2011

GIL - это обычный мьютекс. Стоимость блокировки или разблокирования мьютекса неоспоримый чрезвычайно низка, не намного больше, чем стоимость изменения глобальной переменной. Однако, если вы блокируете и разблокируете оспариваемый мьютекс очень часто, стоимость мьютекса может стать значительной.

Итак, обычно это не очень хорошая идея:

Py_BEGIN_ALLOW_THREADS
    a = 1 + 1;
Py_END_ALLOW_THREADS

То, что здесь происходит, - вы открываете мьютекс, который сразу после этого пытаетесь снова заблокировать. Если это разрыв между двумя большими частями кода, то это дает возможность другому потоку работать. Но если у вас нет проблем с гранулярностью потоков, просто сохраните блокировку.

Так что это хорошая идея в этом контексте:

very_long_computation_requires_gil();
Py_BEGIN_ALLOW_THREADS;
a = a + i;
Py_END_ALLOW_THREADS;
very_long_computation_also_requires_gil();

На самом деле невозможно сделать обоснованное предположение, не зная контекста, и зачастую все еще сложно без проведения тестов.

2 голосов
/ 20 ноября 2011

Эксперты все еще настраивают и тестируют GIL.

Это новые идеи о старой проблеме: inside-look-at-gil-removal-patch

Вы также можете попробовать использовать Stackless Python (без GIL) или PyPy (Python с компилятором Just-In-Time).

0 голосов
/ 31 октября 2011

Есть ли причина не выпускать GIL?

Если расширение C вызывает не повторяющийся код, то могут возникнуть проблемы, если несколько потоков Python вызывают это расширение.в то же время.Поэтому вы можете избежать выпуска GIL в таких расширениях для защиты от этого (конечно, вы можете создать свой собственный мьютекс на уровне Python или C, чтобы достичь этого, не затрагивая другие потоки).

Или GIL должен высвобождаться только для более интенсивно загружающего ЦП кода?

Другой основной причиной освобождения GIL является вызов C-расширения, которое блокирует (например, блокирующее чтение в сокете)разрешить запуск других потоков.Это именно то, что происходит, когда интерпретатор Python сам выполняет блокирующую операцию в потоке.

0 голосов
/ 22 октября 2011

Если у вас есть функция расширения C, которая делает что-то полностью независимое от интерпретатора Python, то выпуск GIL обычно является хорошей идеей. Единственным недостатком является ожидание, чтобы вернуть GIL. В Python 3.2 вам нужно подождать как минимум 1/20 секунды.

...