*evaluator-mode* :interpret and slow loop in SBCL

2 views
Skip to first unread message

Qian Yun

unread,
Oct 15, 2023, 10:38:31 AM10/15/23
to fricas-devel
While testing my memory usage report patch, I found that loop in SBCL
is much slower than other Lisps and takes much more (20x) RAM!

[x for x in 1..5*10^5];

For SBCL, it takes 1.75s and 668MB;
For ECL, it takes 0.34s and 36MB;
For CCL, it takes 0.11s and 20MB;
For CLISP,it takes 4.87s and 340MB.

Not only that,
")lisp (progn (loop for x from 1 to 5000000 collect x) 1)"
is also slow in FriCAS, but fast in SBCL.

After some debugging, I found that
(setf sb-ext:*evaluator-mode* :interpret)
in src/lisp/fricas-lisp.lisp is responsible.

Quoting Waldek from "Re: sbcl: 971 Segmentation Fault" in 2007:

````
You may delete this line -- this line just tries to optimize build
speed. Namely, Axiom during Spad compilation makes heavy use of eval.
Profiling indicated that more than 10% of time is spent compiling
Lisp forms passed to eval. The line above switches sbcl
evaluator to use true interpretation, which significantly
reduced time used by eval. However, sbcl got interpreted evaluation
somwhere late within 0.9 series.
````

So it was an optimization for building. I did following test (make -j8):

Build FriCAS by default : 3m26.863s, test (-j1) takes 1m1.040s
Build FriCAS without :interpret: 3m23.284s, test (-j1) takes 1m14.889s
Build FriCAS with sb-fasteval: 3m19.433s, test (-j1) takes 1m1.311s

So nowadays this option does not affect build time at all. (It does
affect test running a bit though. Not look into it yet.)

After removing this setting, the loop is fast now: 0.11s and 21MB.

So shall we do this change?

- Qian

Waldek Hebisch

unread,
Oct 15, 2023, 11:19:16 AM10/15/23
to fricas...@googlegroups.com
Well, I noticed the issue tooking at build time, but this is really
general problem:
- sbcl compiler is slow (takes a lot of time to generate code)
- default sbcl interpreter is slow too

Most things that we pass to sbcl eval is trivial, so slow interpreter
is still significantly faster than compilation+compiled runtime.
Note that if you put your loop in a function, it will be compiled
and run at compiled speed. I feel that such loops on command
line are rare enough that our current setting is better than sbcl
default.

Concerning build time: using interpreted eval gave us significant
speedup, but not using eval is faster, so a lot of evals in compiler
are removed (replaced by different code). But for handling
code generated by FriCAS interpreter use of eval is currently
unavoidable...

--
Waldek Hebisch

Qian Yun

unread,
Oct 15, 2023, 8:24:14 PM10/15/23
to fricas...@googlegroups.com


On 10/15/23 23:19, Waldek Hebisch wrote:
>
> Well, I noticed the issue tooking at build time, but this is really
> general problem:
> - sbcl compiler is slow (takes a lot of time to generate code)
> - default sbcl interpreter is slow too
>
> Most things that we pass to sbcl eval is trivial, so slow interpreter
> is still significantly faster than compilation+compiled runtime.

I would argue that compiling such trivial things passed to eval
is fast enough that is undetectable by human.

SBCL is designed to compile everything (including in REPL) by default.

> Note that if you put your loop in a function, it will be compiled
> and run at compiled speed. I feel that such loops on command
> line are rare enough that our current setting is better than sbcl
> default.

Running loops in interpreter is a common use pattern, and running
loops with millions of items (and filter them) is not uncommon.

- Qian
Reply all
Reply to author
Forward
0 new messages