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

Как эффективно применять среднюю функцию параллельно

Я хочу сопоставить скромно дорогостоящую функцию на большом ленивом seq параллельно. pmap отлично, но я теряю много переключение контекста. Я думаю, мне нужно увеличить размер куска работы, который передается каждому потоку.

Я написал о функции разбить seq на куски и pmap функцию на каждый кусок и рекомбинировать их. это "работает", но результаты не были впечатляющими. Исходный код по существу выглядит следующим образом:

(pmap eval-polynomial (range x) coificients)

Как я могу на самом деле сжать это, сохраняя его ленивым?

4b9b3361

Ответ 2

Я бы посмотрел на функцию ppmap: http://www.braveclojure.com/zombie-metaphysics/. Он позволяет вам pmap при задании размера куска.

Решение этой проблемы заключается в увеличении размера зерна или объем работы, выполняемой каждой параллелизированной задачей. В этом случае задача заключается в применении функции отображения к одному элементу коллекции. Размер зерна не измеряется ни в одной стандартной единице, но вы говорите, что размер зерна pmap по умолчанию равен единице. Увеличение размера зерна до двух будет означать, что вы применяете функцию отображения к двум элементам вместо одного, поэтому поток, на котором выполняется эта задача, делает больше работы. [...] Просто для удовольствия мы можем обобщить эту технику на функцию ppmap, для разбитого pmap. Он может принимать более одного сбор, как карта:

(defn ppmap
  "Partitioned pmap, for grouping map ops together to make parallel
  overhead worthwhile"
  [grain-size f & colls]
  (apply concat
   (apply pmap
          (fn [& pgroups] (doall (apply map f pgroups)))
          (map (partial partition-all grain-size) colls))))
(time (dorun (ppmap 1000 clojure.string/lower-case orc-name-abbrevs)))
; => "Elapsed time: 44.902 msecs"

Ответ 3

Если вы не против чего-то слегка экзотического (в обмен на какое-то действительно заметное ускорение), вы можете также захотеть заглянуть в работу, проделанную автором Penumbra-библиотеки, которая обеспечивает легкий доступ к графическому процессору.

Ответ 4

Я бы посмотрел на библиотеку Fork/Join, которая будет интегрирована в JDK 7. Это легкая модель потоковой передачи, оптимизированная для неблокирования, вычислять деление и побеждать над набором данных, используя пул потоков, планировщик работы и зеленые потоки.

Проделана некоторая работа, чтобы обернуть API Fork/Join в par, но он не был объединен в main (пока).