Я рекомендую использовать библиотеку parallism, мне очень нравится lparallel library
Он имеет довольно утилиты для распараллеливания кода ammong всех процессоров в вашей машине. Это пример моего macbook pro (4 ядра) с использованием SBCL. Существует большая серия общих совпадений и параллелизма. here
Но давайте создадим пример с использованием lparallel cognates, обратите внимание, что этот пример не является хорошим упражнением параллелизма, это только показать силу лепараллельной и насколько легко использовать.
Рассмотрим Фибоначи хвост рекурсивная функция от cliki:
(Defun Фибо (п) "Tail-рекурсивном вычислении п-го элемента последовательности Фибоначчи" (проверка типа п (целое число 0 *)) (метки ((fib-aux (n f1 f2) (если (zerop n) f1 (fib-aux (1- n) f2 (+ f1 f2))))) (fib-aux n 0 1)))
Это будет пример высокой стоимости вычислений a lgorithm. давайте использовать его:
CL-USER> (time (progn (fib 1000000) nil))
Evaluation took:
17.833 seconds of real time
18.261164 seconds of total run time (16.154088 user, 2.107076 system)
[ Run times consist of 3.827 seconds GC time, and 14.435 seconds non-GC time. ]
102.40% CPU
53,379,077,025 processor cycles
43,367,543,984 bytes consed
NIL
это расчет на 1000000-й срок действия ряда фибоначчи на моем компьютере.
Давайте, например, вычислить список fibonnaci чисел с помощью MAPCAR:
CL-USER> (time (progn (mapcar #'fib '(1000000 1000001 1000002 1000003)) nil))
Evaluation took:
71.455 seconds of real time
73.196391 seconds of total run time (64.662685 user, 8.533706 system)
[ Run times consist of 15.573 seconds GC time, and 57.624 seconds non-GC time. ]
102.44% CPU
213,883,959,679 processor cycles
173,470,577,888 bytes consed
NIL
Lparallell имеет родственные слова:
Они возвращают те же результаты, что и их коллеги ХЛ за исключением случаев , где параллелизм должен играть роль. Например, preove ведет себя как , по существу, как версия CL, но por немного отличается. или возвращает результат первой формы, которая оценивается чем-то non-nil, тогда как por может возвращать результат любой такой не ноль-оценивающей формы.
первая lparallel нагрузка:
CL-USER> (ql:quickload :lparallel)
To load "lparallel":
Load 1 ASDF system:
lparallel
; Loading "lparallel"
(:LPARALLEL)
Таким образом, в нашем случае, единственное, что вам нужно сделать, это изначально ядро с числом ядер у вас есть в наличии:
CL-USER> (setf lparallel:*kernel* (lparallel:make-kernel 4 :name "fibonacci-kernel"))
#<LPARALLEL.KERNEL:KERNEL :NAME "fibonacci-kernel" :WORKER-COUNT 4 :USE-CALLER NIL :ALIVE T :SPIN-COUNT 2000 {1004E1E693}>
а затем запустить родственников из семейства pmap:
CL-USER> (time (progn (lparallel:pmapcar #'fib '(1000000 1000001 1000002 1000003)) nil))
Evaluation took:
58.016 seconds of real time
141.968723 seconds of total run time (107.336060 user, 34.632663 system)
[ Run times consist of 14.880 seconds GC time, and 127.089 seconds non-GC time. ]
244.71% CPU
173,655,268,162 processor cycles
172,916,698,640 bytes consed
NIL
Вы можете увидеть, как легко распараллелить эту задачу, lparallel имеет много ресурсов, которые вы можете изучить:
Я также добавить захват использования процессора с первого MAPCAR и pmapcar в моем Mac:
Нечеткая память от 2002 года или около того, когда я работал над тем, что в конечном итоге превратилось в текущую диагностику-заглушку SBCL, заключается в том, что сборка SBCL с нуля была потрачена ~ 30-40 минут на ноутбук, который у меня был в то время (который был 3-4-летним ноутбуком Dell с ~ 1 ГБ оперативной памяти, если память мне правильна). – Vatine
Спасибо, что сообщили мне, что это невозможно! Правда, sbcl не так долго компилируется на моем ThinkPad (около часа), но двигатель Google вычисляет часы в минутах, на стандартных компиляторах gcc, которые распознают makeflags: я надеялся узнать что-то подобное для lisp. –