Уведомления

Группа в Telegram: @pythonsu

#1 Дек. 4, 2009 18:31:01

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

почему возникают задержки на пустом месте???

Это как раз и называется GIL (Global Interpreter Lock).
Смотрим sys.getcheckinterval(). По умолчанию - 100.
Это значит вот что:
* Питон захватывает lock
* исполняет 100 инструкций байткода
* отпускает lock
* здесь может произойти переключение потока для многопоточной программы. А может и не произойти.
* захватывает опять - и пошли сначала.

Однопоточная программа тоже постоянно захватывает/отпускает lock - это не отключается.

Такое - для каждого потока. Т.е. если один работает - второй ждет. Т.к. одномоментно поток выполняется только на одном проце - то на четырехядерной машине увидим примерно по 25% на ядро.

Я достаточно полно объяснил?



Офлайн

#2 Дек. 5, 2009 10:44:56

o7412369815963
От:
Зарегистрирован: 2009-06-17
Сообщения: 1986
Репутация: +  32  -
Профиль   Отправить e-mail  

почему возникают задержки на пустом месте???

Андрей Светлов
Это как раз и называется GIL (Global Interpreter Lock).
* здесь может произойти переключение потока для многопоточной программы. А может и не произойти.
(в нашем случае тест однопоточный, а переключения есть, и не на 100 инструкций, а на милион (целых 16 мс). )

а где можно скачать python-safe-theard? я где-то вычитал что он без GIL

Офлайн

#3 Дек. 5, 2009 12:33:52

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

почему возникают задержки на пустом месте???

Эээ.
Повторяю. Специально для танкистов.
Каждые 100 инструкций байткода (внимание, не ассемблера, питон исполняет свой байткод интерпретатором!) происходит следующее:
- отпустили GIL
- захватили GIL
и это делается даже в однопоточном приложении.

#ifdef WITH_THREAD
if (interpreter_lock) {
/* Give another thread a chance */

if (PyThreadState_Swap(NULL) != tstate)
Py_FatalError("ceval: tstate mix-up");
PyThread_release_lock(interpreter_lock);

/* Other threads may run now */

PyThread_acquire_lock(interpreter_lock, 1);
if (PyThreadState_Swap(tstate) != NULL)
Py_FatalError("ceval: orphan tstate");

/* Check for thread interrupts */

if (tstate->async_exc != NULL) {
x = tstate->async_exc;
tstate->async_exc = NULL;
PyErr_SetNone(x);
Py_DECREF(x);
why = WHY_EXCEPTION;
goto on_error;
}
}
#endif
PyThreadState_Swap - простая запись в глобальную переменную, а PyThread_release_lock/PyThread_acquire_lock - хуже.
Реализация зависит от платформы.
На Windows это interlocked variable+Event (“тяжелый” объект ядра).
Для Posix - все еще хитрее. Это либо семафор - либо pthread_mutex_t + pthread_cond_t (все они - тоже “ядерные” объекты).
В любом случае получается, что PyThread_release_lock/PyThread_acquire_lock - довольно затратные операции.

И тут можно влететь на затык.
Antoine Pitrou сейчас крутит вариант с более легковесным GIL для py3k. В какой релиз это попадет - непонятно. Скорее всего, только в 3.2 (2.7, вероятно, пролетает).
Из переписки видно, что со старой (она же текущая) реализацией все более или менее нормально на linux, несколько хуже на windows и, как я понял, совсем плохо на mac - там иногда можно попасть на довольно большие задержки.

P.S.
- Питон без GIL - это компиляция без флага WITH_THREAD, который ставится по умолчанию.
- время выполнения одного байткода сильно от этого самого байткода зависит. Диапазон от долей микросекунды до секунд в наиболее злых случаях. Но в любом разе это много-много ассемблерных команд.



Офлайн

#4 Дек. 5, 2009 12:49:17

o7412369815963
От:
Зарегистрирован: 2009-06-17
Сообщения: 1986
Репутация: +  32  -
Профиль   Отправить e-mail  

почему возникают задержки на пустом месте???

Андрей Светлов
- Питон без GIL - это компиляция без флага WITH_THREAD, который ставится по умолчанию.
потоки в нем будут работать? хочу сам разруливать проблему общих ресурсов

Офлайн

#5 Дек. 5, 2009 13:42:52

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

почему возникают задержки на пустом месте???

Нет, не будут. Тут уж что-то одно.

Мы говорим о программировании на “чистом” питоне - без всяких C embedded?
Тогда как вы будете разруливать из Питона его же интерпретатор? Ведь общие ресурсы как раз в нем, в самых что ни на есть недрах.



Офлайн

#6 Дек. 5, 2009 15:29:36

o7412369815963
От:
Зарегистрирован: 2009-06-17
Сообщения: 1986
Репутация: +  32  -
Профиль   Отправить e-mail  

почему возникают задержки на пустом месте???

Андрей Светлов
Нет, не будут. Тут уж что-то одно.

Мы говорим о программировании на “чистом” питоне - без всяких C embedded?
Тогда как вы будете разруливать из Питона его же интерпретатор? Ведь общие ресурсы как раз в нем, в самых что ни на есть недрах.
есть же мютексы, семафоры или что-то типа того…

Офлайн

#7 Дек. 5, 2009 16:00:47

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

почему возникают задержки на пустом месте???

Есть. Но GIL нужен для того, чтобы работал сам Python.
Объекты синхронизации из threading помогут вам в организации мультипоточной работы вашего кода.
И бессильны, если интерпретатор сам по себе не поддерживает многопоточнось.

Так вот, GIL - существенная часть этой поддержки. Выкидываете его - получаете простой однопоточный Питон.



Офлайн

#8 Дек. 6, 2009 14:07:32

o7412369815963
От:
Зарегистрирован: 2009-06-17
Сообщения: 1986
Репутация: +  32  -
Профиль   Отправить e-mail  

почему возникают задержки на пустом месте???

а можно сделать так что-б в определенном куске кода GIL переключения не было, типа: gil-off blabla() gil-on ?

Офлайн

#9 Дек. 6, 2009 15:22:05

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

почему возникают задержки на пустом месте???

:)

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

Создавайте C Extension, в котором внутри BEGIN_THREADS/END_THREADS делайте все, что нужно. Даже это будет проще, чем возиться с GIL напрямую. И гораздо безопасней.



Отредактировано (Дек. 6, 2009 15:50:58)

Офлайн

#10 Дек. 7, 2009 17:45:57

pioner
От:
Зарегистрирован: 2009-10-21
Сообщения: 146
Репутация: +  0  -
Профиль   Отправить e-mail  

почему возникают задержки на пустом месте???

Андрей Светлов
Такое - для каждого потока. Т.е. если один работает - второй ждет.
Второй ждет освобождения ресурсов, а не завершения потока, ведь в этом смысл многопоточности. И если есть свободные ядра у проца, то почему на них не запускается новый поток?

Андрей Светлов
Т.к. одномоментно поток выполняется только на одном проце - то на четырехядерной машине увидим примерно по 25% на ядро.
Т.е. поток на 100% одно ядро не может загрузить?
Андрей Светлов
Я достаточно полно объяснил?
Получается, что сам интерпретатор однопоточен? если прерывается для проверки потоков на исполнение?



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version