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

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

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

(pmap eval-polynomial (range x) coificients)

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


person Arthur Ulfeldt    schedule 09.11.2009    source источник


Ответы (4)


Как насчет использования функции partition для разбиения вашей последовательности range? На http://www.fatvat.co.uk/2009/05/jvisualvm-and-clojure.html

person clartaq    schedule 11.11.2009

Я бы посмотрел на функцию ppmap с: . Это позволяет вам pmap указать размер фрагмента.

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

(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"
person Didier A.    schedule 19.01.2016
comment
Ссылки приходят и уходят, stackoverflow — это навсегда... Не могли бы вы включить соответствующую цитату из Braveclojure, чтобы убедиться, что этот ответ останется в контексте в долгосрочной перспективе. (также этому вопросу почти 7 лет) - person Arthur Ulfeldt; 20.01.2016

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

person pmf    schedule 10.11.2009

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

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

person Mike Douglas    schedule 09.11.2009
comment
Да, если бы вы могли дождаться ветки номинала, которую я бы дождался, маленькие кусочки, которые я видел, просто сногсшибательны. - person Runevault; 10.11.2009
comment
@Runevault, как это сногсшибательно. Похоже на обертку на fork join - person Surya; 21.09.2010