Существует ли реализация Схемы, которая параллелизирует?

Существует ли реализация Схемы R5RS-higher, которая делает распараллеливание? Например, если я говорю, чтобы сделать:

(map (lambda (x) 
        (pure-functional-stuff x))
     '(1 3 5 7 11 13))

это обработает 1, 3, 5, и 7 одновременно, если машина может сделать это? Это, как предполагается, является одним из больших преимуществ функционального программирования, но я не могу найти сохраняемую, актуальную Схему, которая делает это. Я согласился бы с тем, который не параллелизирует его, если я не буду утверждать, что функция не имеет побочных эффектов.

13
задан JasonFruit 18 July 2010 в 21:35
поделиться

4 ответа

Я разработчик Schemik и думаю, что это именно та схема, которую вы ищете. Проект все еще развивается и поддерживается. В начале этого года я выпустил версию, улучшающую совместимость с R5RS. К сожалению, Schemik - это исследовательский проект, сфокусированный на процессе оценки выражений, поэтому его стандартная библиотека все еще относительно мала. Есть ли в Schemik какие-то функции, которые вам не хватает?

5
ответ дан 2 December 2019 в 00:45
поделиться

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

3
ответ дан 2 December 2019 в 00:45
поделиться

Я только что нашел Schemik

http://schemik.sourceforge.net/

который, похоже, поддерживается по крайней мере до 2009 года, хотя я не знаю, является ли он R5RS.

2
ответ дан 2 December 2019 в 00:45
поделиться

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

(map add1 '(1 2 3))

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

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

Такая простая вещь, как

(define (pmap f xs)
  (map touch (map (λ(x) (future (λ() (f x)))) xs)))

, может уйти довольно далеко при разумном использовании, но вам следует поэкспериментировать с разбиением данных на части для передачи в параллельные потоки.

3
ответ дан 2 December 2019 в 00:45
поделиться