Почему многопроцессорная обработка использует только одно ядро после импорта numpy?
Я не уверен, что это больше относится к проблеме ОС, но я подумал, что спрошу здесь, Если у кого-то есть некоторое представление о конце Python.
Я пытался распараллелить CPU-heavy for
цикл с помощью joblib
, но я обнаружил, что вместо того, чтобы каждый рабочий процесс был назначен другому ядру, я в конечном итоге все они назначаются одному ядру и не повышают производительность.
вот очень тривиальный образец...
from joblib import Parallel,delayed
import numpy as np
def testfunc(data):
# some very boneheaded CPU work
for nn in xrange(1000):
for ii in data[0,:]:
for jj in data[1,:]:
ii*jj
def run(niter=10):
data = (np.random.randn(2,100) for ii in xrange(niter))
pool = Parallel(n_jobs=-1,verbose=1,pre_dispatch='all')
results = pool(delayed(testfunc)(dd) for dd in data)
if __name__ == '__main__':
run()
...и вот что я вижу в htop
пока этот скрипт работает:
Я с Ubuntu 12.10 (3.5.0-26) на ноутбуке с 4-мя ядрами. Ясно joblib.Parallel
порождает отдельные процессы для разных работников, но есть ли способ, которым я могу заставить эти процессы выполняться на разных ядрах?
3 ответа:
после некоторых погуглив я нашел ответ!--13-->здесь.
оказывается, что некоторые модули Python (
numpy
,scipy
,tables
,pandas
,skimage
...) беспорядок с основным сродством при импорте. Насколько я могу судить, эта проблема, похоже, специально вызвана их связыванием с многопоточными библиотеками OpenBLAS.обходной путь заключается в сбросе сходства задач с помощью
os.system("taskset -p 0xff %d" % os.getpid())
С этой строкой вставить в модуль импорт, мой пример теперь работает на всех ядрах:
мой опыт до сих пор было то, что это, кажется, не имеет никакого негативного влияния на
numpy
производительность, хотя это, вероятно, зависит от машины и задачи.обновление:
есть также два способа отключить сродство процессора-сброс поведения самого OpenBLAS. Во время выполнения можно использовать переменную окружения
OPENBLAS_MAIN_FREE
(илиGOTOBLAS_MAIN_FREE
), для примерOPENBLAS_MAIN_FREE=1 python myscript.py
или альтернативно, если вы компилируете OpenBLAS из исходного кода, Вы можете навсегда отключить его во время сборки, отредактировав
Makefile.rule
содержит строкуNO_AFFINITY=1
Python 3 теперь предоставляет методы установить сродство
>>> import os >>> os.sched_getaffinity(0) {0, 1, 2, 3} >>> os.sched_setaffinity(0, {1, 3}) >>> os.sched_getaffinity(0) {1, 3} >>> x = {i for i in range(10)} >>> x {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} >>> os.sched_setaffinity(0, x) >>> os.sched_getaffinity(0) {0, 1, 2, 3}
Это, кажется, общая проблема с Python на Ubuntu и не относится к
joblib
:
- как многопроцессорность.карта и joblib используют только 1 Процессор после обновления с Ubuntu 10.10 до 12.04
- многопроцессорная обработка Python использует только одно ядро
- многопроцессорная обработка.Процессы пула заблокированы на одном ядре
Я бы предложил поэкспериментировать с сродством процессора (
taskset
).