From: John Cowan <>
Subject: Re: [Chicken-users] Other Cheney-MTA systems?
Date: Sat, 13 Nov 2010 13:53:21 -0500

> Peter Bex scripsit:
>> What is used instead of CPS nowadays?
> The typical view is that it's more important to optimize normal calls
> and returns than calls to escape procedures, so a stack is used and then
> copied when call/cc is invoked.  Chicken allocates stack frames on a
> first-generation heap, which means that you are paying to GC that heap,
> as well as the (nowadays small) space cost of retaining the C return
> addresses on the stack that are never used.

That's right. But the really important point is TCO which is
crucial. Without generating one big function, and/or using trampolines
it is not possibly to portably generate C without losing full tail
calls. One bug function is in practice not possible. Trampolines pay
for cross-module calls and are expensive by requiring to maintain a
"shadow" stack (this may be improved by generating big C functions but
that doesn't scale too well in terms of gcc compile
times). Cheney-on-the-MTA handles call/cc, TCO and first-level GC
using a single technique, generates small functions that compile fast
and keeps the C function calling conventions.

>> Does it give you "free" call/cc?
> In effect, Chicken call/cc is not free; its cost is amortized over
> all calls.  However, that cost is paid even by programs that never
> use call/cc.

Also correct. Note that cheap continuations become important when
they are used to implement threading.


;;;; thread-list.scm
; usage: csi -s thread-list.scm [COUNT]

(use srfi-18)

(define count #f)

(define (run n)
  (set! count n)
  (print "creating " n " threads ...")
  (let loop ((n n) (prev #f))
    (cond ((negative? n)
           (print "starting ...")
           (thread-start! prev))
            (sub1 n)
             (lambda ()
               (thread-start! prev)
               (bump n))))))))

(define (bump n)
  (set! count (sub1 count))
  (cond ((zero? count) 
        ((zero? (modulo n 1000))
         (print* "."))))

(run (string->number (optional (command-line-arguments) "250000")))
(thread-sleep! 604800)

; time csi -s thread-list.scm 1000000 -:h1g -:d
;   11 secs
; csc thread-list.scm -o a.out -v -O4 -f -d0
; time a.out 1000000 -:h1g -:d
;   4 secs
; (x86, Core2 Duo, 2.4Ghz, 2GB RAM)
Chicken-users mailing list

Reply via email to