2010-01-20 1 views
28

Использование clojure У меня есть очень большой объем данных в последовательности, и я хочу обрабатывать его параллельно, с относительно небольшим количеством ядер (от 4 до 8).Лучшая альтернатива pmap в Clojure для параллелизации недорогостоящих функций над большими данными?

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

Я думаю, причина в том, что pmap предполагает, что функция, отображаемая по данным, очень дорога. Глядя на исходный код pmap, он, по-видимому, создает 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 будут работать?

+0

не забудьте воспользоваться мемонией, если это применимо. http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/memoize –

ответ

19

Этим вопросом: how-to-efficiently-apply-a-medium-weight-function-in-parallel также решает эту проблему в очень похожем контексте.

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

+0

Я действительно хотел бы использовать 'pmap' на каждом куске? Я думаю, что это все равно создаст будущее на каждый пункт. Мне было бы разумнее просто «нарисовать» «будущее» на каждом патроне. –

+3

Идея состоит в том, чтобы увеличить размер куска, так что он бьет накладные расходы на координацию, все еще заполняя все ядра. Не у всех наборов данных есть такое сладкое пятно. –

+1

Ах-ха. Мне нужно было думать на уровне еще одной абстракции. Я 'pmap' функцию над кусками, и эта функция будет« отображать »мою функцию обработки над каждым членом блока. Это то, что вы имели ввиду? –

0

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

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

+1

swarmiji, если библиотека для распределенных вычислений в Clojure. У меня сложилось впечатление, что это quiestion больше фокусировалось на односистемной параллелизации. –

5

К сожалению, еще не верный ответ, но что-то, что нужно посмотреть в будущем, - это работа Рича с библиотекой fork/join, приходящая на Java 7. Если вы посмотрите на свою ветку Par в github, он проделал некоторую работу с ней и В последний раз я видел, как ранние возвращения были потрясающими.

Пример использования Rich.

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

+2

На самом деле я обнаружил, что теперь это можно попробовать с помощью Java6, ветви «par» Clojure от github и файла jsr166y.jar, которые Rich Hickey предоставил по адресу: http://cloud.github.com/downloads/richhickey/clojure/ jsr166y.jar –

+0

Ой, правда? Возможно, придется это взглянуть, так как Par выглядит потрясающе. Спасибо за подсказку, поскольку я пропустил это. – Runevault

+3

паста мертва –

2

Вилка/присоединиться к работе, упомянутые в предыдущих ответах на этом и аналогичных нитей в конечном итоге принесло свои плоды, как reducers библиотека, которая, вероятно, стоит посмотреть.

 Смежные вопросы

  • Нет связанных вопросов^_^