如何使clisp或sbcl使用所有cpu核心可用?

时间:2016-07-25 19:52:39

标签: common-lisp cross-compiling cpu-usage sbcl clisp

通过远程ssh连接,我正在尝试使用clisp交叉编译sbcl。到目前为止,我所遵循的步骤是这样的:

我下载了最新的sbcl源代码(此时为sbcl-1.3.7),未压缩它,并进入其源目录。

然后建立它:

root@remotehost:/sbcl-1.3.7# screen 
root@remotehost:/sbcl-1.3.7# sh make.sh --prefix=/usr --dynamic-space-size=2Gb --xc-host='clisp -q'
root@remotehost:/sbcl-1.3.7# Ctrl-A Ctrl-D
[detached from 4486.pts-1.remotehost]r/fun-info-funs.fas
root@remotehost:/sbcl-1.3.7# 

通过同一个盒子的第二个远程ssh连接,top报告cpu使用率为6%

nproc说我有16个核心(这是谷歌计算引擎 - 我无法承受16核心的东西:)

MAKEFLAGS在我的环境中设置为-j16,但我猜clisp并不知道这一点。如何使用这个版本来使用所有16​​个内核?

2 个答案:

答案 0 :(得分:1)

我建议您使用并行库,我非常喜欢lparallel library

它有很多实用程序可以在您的计算机中的所有处理器上并行化代码。这是我使用SBCL的macbook pro(4核)的一个例子。有一系列常见的lisp并发和并行here

但是让我们创建一个使用lparallel cognates的示例示例,请注意,这个示例并不是一个很好的并行练习,只是为了展示leparallel的强大功能以及使用它的简单性。

让我们考虑来自cliki:

的斐波那契尾递归函数
  

(defun fib(n)“尾部递归计算的第n个元素   Fibonacci序列“(校验类型n(整数0 *))(标签((fib-aux   (n f1 f2)                       (if(zerop n)f1                         (fib-aux(1-n)f2(+ f1 f2)))))             (fib-aux n 0 1)))

这将是高计算成本算法的示例。让我们用它:

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

这是我计算机上斐波纳契系列第10000个术语的计算。

让我们举例说明使用mapcar计算一个fibonnaci数列表:

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有同源词:

  

除了案例外,他们返回的结果与CL对应的结果相同   并行主义必须发挥作用。例如,preove表现   基本上就像它的CL版本,但por略有不同。要么   返回计算结果的第一个表单的结果   非零,而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有很多你可以探索的资源:

我还在Mac上添加了第一个mapcar和pmapcar的cpu使用情况:

the first load is mapcar and the second from lparallel

答案 1 :(得分:0)

SBCL交叉编译(又称自举)是在100%vanilla CL中完成的,标准中没有任何关于线程或多个进程的内容。

使用机器supplied SBCL binary可能不会使用线程,即使我知道SBCL确实有该语言的线程支持。

如果您更改了SBCL的来源,则只需执行此操作,因为最新支持的版本已经过预编译。我自己还没有自己编译SBCL,但我怀疑它需要的时间比90年代我的Linux编译时间长,而且比我每晚的睡眠时间少。

相关问题