Я искал способы легко многопоточить некоторые из моего простого кода анализа, так как я заметил numpy, что он использовал только одно ядро, несмотря на то, что он должен быть многопоточным.
Кто сказал, что он должен быть многопоточным?
numpy
в первую очередь предназначен для того, чтобы быть как можно быстрее на одном ядре и быть как можно более параллельным, если вам нужно сделать так. Но вам все равно придется распараллелить его.В частности, вы можете одновременно работать с независимыми предметами, а медленные операции освобождают GIL, если это возможно, хотя «когда возможно» может быть недостаточно , Кроме того, объекты
numpy
предназначены для совместного использования или передачи между процессами как можно проще, чтобы облегчить использованиеmultiprocessing
.Существуют некоторые специализированные методы, которые автоматически распараллеливаются, но большинство основных методов не. В частности,
dot
реализуется поверх BLAS, когда это возможно, и BLAS автоматически распараллеливается на большинстве платформ, ноmean
реализован в виде простого кода C.См. Параллельное программирование с numpy и scipy для деталей.
Итак, как вы знаете, какие методы распараллелены, а какие нет? И, из тех, которые не являются, как вы знаете, какие из них могут быть хорошо обработаны вручную и которые нуждаются в многопроцессорности?
На это нет хорошего ответа. Вы можете сделать обоснованные догадки (X кажется, что он, вероятно, реализован поверх ATLAS, и моя копия ATLAS неявно переименована), или вы можете прочитать источник.
Но обычно лучше всего сделать попробуйте и проверьте. Если код использует 100% одного ядра и 0% других, добавьте ручную резьбу. Если теперь он использует 100% одного ядра и 10% других и работает не быстрее, измените многопоточность на многопроцессорность. (К счастью, Python делает это довольно легко, особенно если вы используете классы Executor из
concurrent.futures
или классов пула изmultiprocessing
. Но вам все равно часто нужно вникать в это и проверить относительные затраты на совместное использование vs. если у вас большие массивы.)Кроме того, как указывает kwatford, просто потому, что какой-то метод не кажется неявно параллельным, не означает, что он не будет параллелен в следующей версии numpy , или следующей версии BLAS, или на другой платформе, или даже на машине с немного отличающимися на ней материалами. Поэтому будьте готовы к повторной проверке. И сделайте что-нибудь вроде
my_mean = numpy.mean
, а затем используйтеmy_mean
всюду, поэтому вы можете просто изменить одну строку наmy_mean = pool_threaded_mean
.