Q : (Почему) ... работает медленнее , чем обычный цикл for (?)
>>> import numpy as np; _ = np.random.rand( 50, 50, 50)
>>> from zmq import Stopwatch; aClk = Stopwatch()
>>>
>>> aClk.start(); r = denoise_tv_chambolle( _, weight = 0.1, multichannel = True ); b = aClk.stop(); print( "The code took {0: > 9d}[us]".format( b ) )
The code took 679749[us]
The code took 683137[us]
The code took 678925[us]
The code took 688936[us]
Учитывая миниатюрную форму данных (50,50,50)
-of- float64
, вычисления в кеше являются ключом к производительности. Использование joblib.Parallel
с бэкэндом 'threading
' является довольно анти-паттерном (python использует GIL
-блок для повторного вычисления [SERIAL]
один за другим , поскольку это позволяет избежать любого общего, связанного с параллелизмом столкновения). Такой последовательный поток вычислений здесь еще хуже, потому что «переключение» один за другим идет за дополнительную плату (не улучшая оригинал чисто - [SERIAL]
выполнение кода - так вы платите больше, чтобы получить то же самое (но через некоторое время))
Q : увеличение n_jobs
также увеличьте время обработки
Конечно, это увеличивает количество потерянного времени на накладные расходы на повторное использование GIL-блокировки, так как их больше one-step-after-another
GIL-направленное предотвращение столкновений " переключение " - переходы.
Последнее, но не менее важное
Даже если идти вПолноценный параллелизм, использующий параллелизм, основанный на процессах (избегает затрат на GIL-блокировку), он приходит (опять же за счет затрат - затрат на создание экземпляров процессов (полная копия памяти в 1: 1 процесса интерпретатора python n_jobs
- в Win O / S, аналогично в Linux O / S - как описано в joblib
модуль, вкл. рекомендации, чтобы избежать некоторых других форм порождения параллельных процессов), параметр data-Transfer-Cost, result-Transfer-Cost).
Если добавить все эти дополнительные расходы для n_jobs = 6
и если эти затраты были начислены во имя только миниатюрной вычислительной задачи (всего лишь ~ 680 [ms]
по продолжительности), то вскоре вы получите оплату намного больше настроить параллельную обработку , которую когда-либо получит обратно (поскольку другой эффект - как худшее, чем оригинальное повторное использование кэша - не "увеличит" скорость вычислений).
реальных затрат (и должный учет затрат каждого класса (всех таких)) вычислительных нагрузок - причина (почему) ... работает медленнее