[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Chicken-users] Other Cheney-MTA systems?
From: |
Felix |
Subject: |
Re: [Chicken-users] Other Cheney-MTA systems? |
Date: |
Sun, 14 Nov 2010 15:55:31 +0100 (CET) |
From: John Cowan <address@hidden>
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.
cheers,
felix
;;;; 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))
(else
(loop
(sub1 n)
(make-thread
(lambda ()
(thread-start! prev)
(bump n))))))))
(define (bump n)
(set! count (sub1 count))
(cond ((zero? count)
(newline)
(exit))
((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)