Лучшая альтернатива pmap в Clojure для параллелизации умеренно недорогих функций по большим данным?

Используя clojure у меня есть очень большой объем данных в последовательности, и я хочу обработать его параллельно, с относительно небольшое количество ядер (4 - 8).

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

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

Вот соответствующая часть источника pmap:

(defn pmap
  "Like map, except f is applied in parallel. Semi-lazy in that the
  parallel computation stays ahead of the consumption, but doesn't
  realize the entire result unless required. Only useful for
  computationally intensive functions where the time of f dominates
  the coordination overhead."
  ([f coll]
   (let [n (+ 2 (.. Runtime getRuntime availableProcessors))
         rets (map #(future (f %)) coll)
         step (fn step [[x & xs :as vs] fs]
                (lazy-seq
                 (if-let [s (seq fs)]
                   (cons (deref x) (step xs (rest s)))
                   (map deref vs))))]
     (step rets (drop n rets))))
  ;; multi-collection form of pmap elided

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

Мое понимание pmap корректный?

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

29
задан Alex Stoddard 31 August 2011 в 03:35
поделиться

3 ответа

Этот вопрос: , как-эффективно - Apply-A-Medive-Weight-Function-Parallel также рассматривает эту проблему в очень аналогичном контексте.

Текущий лучший ответ - использовать раздел , чтобы сломать его в куски. Затем PMAP функция карты на каждый кусок. Затем верните результаты. Стиль карты-уменьшения.

20
ответ дан 28 November 2019 в 02:03
поделиться

Вы можете использовать некоторые карты/сокращения, реализованные вручную. Также взгляните на структуру swarmiji .

«Распределенная вычислительная система, которая помогает писать и запускать код Clojure параллельно - между ядрами и процессорами»

0
ответ дан 28 November 2019 в 02:03
поделиться

К сожалению, не допустимый ответ, но что-то посмотреть в будущем, - это работа богатых с библиотекой Fork / Join, приходящая в Java 7. Если вы посмотрите на его филиал на Github, он сделал с ней работу и последним Я видел ранние доходы были потрясающими.

Пример богатых пробуя.

http://paste.lisp.org/display/84027

5
ответ дан 28 November 2019 в 02:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: