Я играю с multiprocessing
в Python 3, чтобы попытаться понять, как это работает и когда это полезно.
Я основываю свои примеры на этот вопрос , который действительно старый (2012).
Мой компьютер представляет собой Windows, 4 физических ядра, 8 логических ядер.
Первый: несегментированные данные
Сначала я пытаюсь грубо вычислить numpy.sin
для миллиона значений. Миллион значений - это один фрагмент, не сегментированный.
import time
import numpy
from multiprocessing import Pool
# so that iPython works
__spec__ = "ModuleSpec(name='builtins', loader=<class '_frozen_importlib.BuiltinImporter'>)"
def numpy_sin(value):
return numpy.sin(value)
a = numpy.arange(1000000)
if __name__ == '__main__':
pool = Pool(processes = 8)
start = time.time()
result = numpy.sin(a)
end = time.time()
print('Singled threaded {}'.format(end - start))
start = time.time()
result = pool.map(numpy_sin, a)
pool.close()
pool.join()
end = time.time()
print('Multithreaded {}'.format(end - start))
И я понимаю, что независимо от количества процессов «multi_threading» всегда занимает примерно в 10 раз больше, чем «однопоточность» , В диспетчере задач я вижу, что не все процессоры работают с максимальной нагрузкой, а общее использование процессора составляет от 18% до 31%.
Так что я пробую что-то еще.
Второе: сегментированные данные
Я пытаюсь разделить исходный 1 миллион вычислений на 10 пакетов по 100 000 каждый.
Затем я снова пытаюсь выполнить 10 миллионов вычислений в 10 пакетах по 1 миллиону каждый.
import time
import numpy
from multiprocessing import Pool
# so that iPython works
__spec__ = "ModuleSpec(name='builtins', loader=<class '_frozen_importlib.BuiltinImporter'>)"
def numpy_sin(value):
return numpy.sin(value)
p = 3
s = 1000000
a = [numpy.arange(s) for _ in range(10)]
if __name__ == '__main__':
print('processes = {}'.format(p))
print('size = {}'.format(s))
start = time.time()
result = numpy.sin(a)
end = time.time()
print('Singled threaded {}'.format(end - start))
pool = Pool(processes = p)
start = time.time()
result = pool.map(numpy_sin, a)
pool.close()
pool.join()
end = time.time()
print('Multithreaded {}'.format(end - start))
Я запустил этот последний фрагмент кода для разных процессов p
и различной длины списка s
, 100000
и 1000000
.
По крайней мере теперь диспетчер задач выдает максимальную нагрузку на ЦП при 100% загрузке.
Я получаю следующие результаты за прошедшее время (ОРАНЖЕВЫЙ: многопроцессный, СИНИЙ : single):
![enter image description here](https://i.stack.imgur.com/KBRk7.png)
![enter image description here](https://i.stack.imgur.com/PIeix.png)
То есть multiprocessing
никогда выигрывает за один процесс.
Почему ??