Подтвердить что ты не робот

Моя сборка numpy не использует несколько ядер процессора

Примечание: Внимательно прочитайте этот вопрос. Я понимаю, что CPython имеет GIL. Как правило, для большинства функций функция "Нейпинг" не ограничена GIL.

Обновление: Оказывается, это проблема, описанная в этом вопросе. Если вы свяжете numpy с OpenBLAS, он установит близость процессора всего процесса, как только вы импортируете numpy. Это можно зафиксировать с помощью флага сборки OpenBLAS.

В моем приложении используется numpy, который я строю из источника (т.е. без easy_install и т.д.). Обычно моя пользовательская сборка работает отлично. Недавно, хотя я сделал что-то (для моей сборки? В моей ОС?), Что предотвращает использование numpy от нескольких ядер процессора.

Рассмотрим эту простую программу, которая делает следующее:

  • Запустите глупую рабочую нагрузку в рабочем потоке.
  • Повторите ту же самую рабочую нагрузку дважды в двух параллельных потоках.

При правильно работающей установке numpy второй (параллельный) шаг выполняется почти так же быстро, как и первый шаг. Но в моей специальной сборке второй шаг занимает вдвое больше! Используется только 1 процессор. Он действует так, как будто numpy.sqrt не выпускает GIL, но я знаю, что он должен.

Человек, я не знаю, как сломать такую ​​же сумму, как если бы я захотел. Он отказывается использовать более одного ядра процессора! Как я это сделал? Как это исправить?

Изменить: Подробнее: numpy-1.7.0, gcc, Linux (Fedora 16), но я не думаю, что эти особенности слишком важны. Я уже построил эту конфигурацию, не сталкиваясь с этой проблемой. Наверное, мне интересно, есть ли какая-то ОС или настройка python, которые могут вызвать подобное поведение.

import numpy, threading, time

a1 = numpy.random.random((500,500,200)).astype(numpy.float32)
a2 = numpy.random.random((500,500,200)).astype(numpy.float32)
a3 = numpy.random.random((500,500,200)).astype(numpy.float32)

def numpy_workload(name, a):
    print "starting numpy_workload " + name
    for _ in range(10):
        numpy.sqrt(a)
    print "finished numpy_workload " + name

t1 = threading.Thread(target=lambda: numpy_workload("1", a1))
t2 = threading.Thread(target=lambda: numpy_workload("2", a2))
t3 = threading.Thread(target=lambda: numpy_workload("3", a3))

start = time.time()
t1.start()
t1.join()
stop = time.time()
print "Single thread done after {} seconds\n".format( stop - start )

start = time.time()
t2.start()
t3.start()
t2.join()
t3.join()
stop = time.time()
print "Two threads done after {} seconds\n".format( stop - start )
4b9b3361