* srfi-18 and the vm @ 2009-05-22 14:39 Andy Wingo 2009-05-22 15:01 ` Julian Graham ` (2 more replies) 0 siblings, 3 replies; 14+ messages in thread From: Andy Wingo @ 2009-05-22 14:39 UTC (permalink / raw) To: guile-devel Hi! I'm catching up with mail. On my syncase-in-boot-9 branch, I enabled compilation of srfi-18 and fixed a bug in it regarding multiple-value returns. Now I just ran the srfi-18 test like 100 times in a row and it didn't show any strange errors. Yaaaay! With psyntax running a pre-analysis phase on all source code, we can do away with lazy memoization entirely -- a neat hack, but it made eval.c buggy and impenetrable. I'll write more about that in the future. Andy -- http://wingolog.org/ ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: srfi-18 and the vm 2009-05-22 14:39 srfi-18 and the vm Andy Wingo @ 2009-05-22 15:01 ` Julian Graham 2009-05-22 15:10 ` Ludovic Courtès 2009-05-23 9:52 ` Neil Jerram 2 siblings, 0 replies; 14+ messages in thread From: Julian Graham @ 2009-05-22 15:01 UTC (permalink / raw) To: Andy Wingo; +Cc: guile-devel I second the Yaaaay! On Fri, May 22, 2009 at 10:39 AM, Andy Wingo <wingo@pobox.com> wrote: > Hi! > > I'm catching up with mail. On my syncase-in-boot-9 branch, I enabled > compilation of srfi-18 and fixed a bug in it regarding multiple-value > returns. Now I just ran the srfi-18 test like 100 times in a row and it > didn't show any strange errors. Yaaaay! > > With psyntax running a pre-analysis phase on all source code, we can do > away with lazy memoization entirely -- a neat hack, but it made eval.c > buggy and impenetrable. I'll write more about that in the future. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: srfi-18 and the vm 2009-05-22 14:39 srfi-18 and the vm Andy Wingo 2009-05-22 15:01 ` Julian Graham @ 2009-05-22 15:10 ` Ludovic Courtès 2009-05-22 16:20 ` Andy Wingo 2009-05-23 9:52 ` Neil Jerram 2 siblings, 1 reply; 14+ messages in thread From: Ludovic Courtès @ 2009-05-22 15:10 UTC (permalink / raw) To: guile-devel ¡Hola! Andy Wingo <wingo@pobox.com> writes: > I'm catching up with mail. On my syncase-in-boot-9 branch, I enabled > compilation of srfi-18 and fixed a bug in it regarding multiple-value > returns. Now I just ran the srfi-18 test like 100 times in a row and it > didn't show any strange errors. Yaaaay! What kind of "strange errors" would it lead to before? When SRFI-18 wasn't compiled, I would expect multiple value returns would translate in a `value.c' struct that would then be passed along as a single value. Thanks, Ludo'. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: srfi-18 and the vm 2009-05-22 15:10 ` Ludovic Courtès @ 2009-05-22 16:20 ` Andy Wingo 2009-05-22 22:04 ` Ludovic Courtès 0 siblings, 1 reply; 14+ messages in thread From: Andy Wingo @ 2009-05-22 16:20 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guile-devel On Fri 22 May 2009 17:10, ludo@gnu.org (Ludovic Courtès) writes: > ¡Hola! > > Andy Wingo <wingo@pobox.com> writes: > >> I'm catching up with mail. On my syncase-in-boot-9 branch, I enabled >> compilation of srfi-18 and fixed a bug in it regarding multiple-value >> returns. Now I just ran the srfi-18 test like 100 times in a row and it >> didn't show any strange errors. Yaaaay! > > What kind of "strange errors" would it lead to before? Random ones based on races, as code was lazily memoized from multiple threads at once. > When SRFI-18 wasn't compiled, I would expect multiple value returns > would translate in a `value.c' struct that would then be passed along as > a single value. Indeed. The VM truncates multiple values, but here we were doing a (let ((x (values))) something x), which returned 0 values to a continuation needing a value, raising a valid error. Fixed that in the original source code. In addition, we were sometimes getting 0 values in a for-effect context, which the GHIL->GLIL compiler didn't support. Like this: (begin (call/cc (lambda (k) (k))) 10) I've fixed this in the tree-il->glil compiler. Cheers, Andy -- http://wingolog.org/ ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: srfi-18 and the vm 2009-05-22 16:20 ` Andy Wingo @ 2009-05-22 22:04 ` Ludovic Courtès 0 siblings, 0 replies; 14+ messages in thread From: Ludovic Courtès @ 2009-05-22 22:04 UTC (permalink / raw) To: guile-devel Andy Wingo <wingo@pobox.com> writes: > On Fri 22 May 2009 17:10, ludo@gnu.org (Ludovic Courtès) writes: >> Andy Wingo <wingo@pobox.com> writes: >> >>> I'm catching up with mail. On my syncase-in-boot-9 branch, I enabled >>> compilation of srfi-18 and fixed a bug in it regarding multiple-value >>> returns. Now I just ran the srfi-18 test like 100 times in a row and it >>> didn't show any strange errors. Yaaaay! >> >> What kind of "strange errors" would it lead to before? > > Random ones based on races, as code was lazily memoized from multiple > threads at once. OK (I thought you were referring to errors related to multiple-value returns.) Then, indeed, yaay! > Indeed. The VM truncates multiple values, but here we were doing a (let > ((x (values))) something x), which returned 0 values to a continuation > needing a value, raising a valid error. Fixed that in the original > source code. > > In addition, we were sometimes getting 0 values in a for-effect context, > which the GHIL->GLIL compiler didn't support. Like this: > > (begin (call/cc (lambda (k) (k))) 10) > > I've fixed this in the tree-il->glil compiler. Thanks for the explanation. Ludo'. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: srfi-18 and the vm 2009-05-22 14:39 srfi-18 and the vm Andy Wingo 2009-05-22 15:01 ` Julian Graham 2009-05-22 15:10 ` Ludovic Courtès @ 2009-05-23 9:52 ` Neil Jerram 2009-05-23 16:38 ` Andy Wingo 2 siblings, 1 reply; 14+ messages in thread From: Neil Jerram @ 2009-05-23 9:52 UTC (permalink / raw) To: Andy Wingo; +Cc: guile-devel Andy Wingo <wingo@pobox.com> writes: > With psyntax running a pre-analysis phase on all source code, we can do > away with lazy memoization entirely -- a neat hack, but it made eval.c > buggy and impenetrable. I'll write more about that in the future. Anticipating your "more in the future", do you mean that the pre-analysis does all the memoization in advance? Neil ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: srfi-18 and the vm 2009-05-23 9:52 ` Neil Jerram @ 2009-05-23 16:38 ` Andy Wingo 2009-05-23 22:03 ` Ludovic Courtès 0 siblings, 1 reply; 14+ messages in thread From: Andy Wingo @ 2009-05-23 16:38 UTC (permalink / raw) To: Neil Jerram; +Cc: guile-devel Hi Neil, On Sat 23 May 2009 11:52, Neil Jerram <neil@ossau.uklinux.net> writes: > Andy Wingo <wingo@pobox.com> writes: > >> With psyntax running a pre-analysis phase on all source code, we can do >> away with lazy memoization entirely -- a neat hack, but it made eval.c >> buggy and impenetrable. I'll write more about that in the future. > > Anticipating your "more in the future", do you mean that the > pre-analysis does all the memoization in advance? It does not now, but it could. All output from psyntax is created by this set of procedures (internal to psyntax.scm): build-void build-application build-conditional build-lexical-reference build-lexical-assignment build-global-reference build-global-assignment build-global-definition build-lambda build-primref build-data build-sequence build-let build-named-let build-letrec In compile mode, these procedures create tree-il objects. In eval mode, they create s-expressions, so that the expander can work before modules are booted. (The mode is the second parameter to sc-expand; it's eval mode by default, but the compiler sets it to compile mode.) One should be able to memoize ilocs in from the result of the output, in a second pass, given that there are so few forms. Of course some memoization can happen lazily too, e.g. global lookup; but macros have already been expanded out, so the evaluator doesn't have to know about `cond' or `do' or anything else, and unmemoization becomes trivial. The evaluator can be drastically simplified, which is good for maintainance. It will probably be faster too. Then, later on, we can implement and compile an evaluator in Scheme itself, so that we can tail call between interpreted and compiled code. (We're not limited to just 2 passes, even in the interpreter, of course; once we have an inliner, it would probably be a good idea to run it on code for interpretation, as well.) What do you think? Andy -- http://wingolog.org/ ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: srfi-18 and the vm 2009-05-23 16:38 ` Andy Wingo @ 2009-05-23 22:03 ` Ludovic Courtès 2009-05-23 22:16 ` Andy Wingo 0 siblings, 1 reply; 14+ messages in thread From: Ludovic Courtès @ 2009-05-23 22:03 UTC (permalink / raw) To: guile-devel Hello! Andy Wingo <wingo@pobox.com> writes: > On Sat 23 May 2009 11:52, Neil Jerram <neil@ossau.uklinux.net> writes: > >> Andy Wingo <wingo@pobox.com> writes: >> >>> With psyntax running a pre-analysis phase on all source code, we can do >>> away with lazy memoization entirely -- a neat hack, but it made eval.c >>> buggy and impenetrable. I'll write more about that in the future. >> >> Anticipating your "more in the future", do you mean that the >> pre-analysis does all the memoization in advance? > > It does not now, but it could. [...] > In compile mode, these procedures create tree-il objects. In eval mode, > they create s-expressions, so that the expander can work before modules > are booted. (The mode is the second parameter to sc-expand; it's eval > mode by default, but the compiler sets it to compile mode.) > > One should be able to memoize ilocs in from the result of the output, in > a second pass, given that there are so few forms. Of course some > memoization can happen lazily too, e.g. global lookup; [...] I'm slightly concerned that doing things ahead of time rather than just in time (i.e., lazily) would have a negative impact on the interpreter's start-up time, which may be noticeable for short-lived scripts. What do you think? Thanks, Ludo'. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: srfi-18 and the vm 2009-05-23 22:03 ` Ludovic Courtès @ 2009-05-23 22:16 ` Andy Wingo 2009-05-24 14:08 ` Ludovic Courtès 0 siblings, 1 reply; 14+ messages in thread From: Andy Wingo @ 2009-05-23 22:16 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guile-devel Hi! On Sun 24 May 2009 00:03, ludo@gnu.org (Ludovic Courtès) writes: > I'm slightly concerned that doing things ahead of time rather than just > in time (i.e., lazily) would have a negative impact on the interpreter's > start-up time, which may be noticeable for short-lived scripts. In the guile -c 0 case, we don't have this issue, because no source is expanded; it's all compiled already. The load time on my machine is about 20 ms, which is about equal to what we discussed before (10 ms base + 10 ms for psyntax). It is faster than before, and will get faster. For loading uncompiled scripts, things will be slower, unless your modules #:use-syntax some other transformer. I don't know where the tradeoff is between the increased expansion speed due to compilation and slowdown due to a complete codewalk, but it's certainly there. OTOH I would suspect that we can implement some kind of just-in-time compilation -- essentially for each use-modules we can check to see if the module is compiled, and if not just compile it then and there. It would be a little slow the first time, but after that it would load much faster, even faster than before. Python does this. We could add a guile --no-comp option to disable it. > What do you think? I think it's a good question, and we're going to have to settle on a good answer at some point. Cheers, Andy. -- http://wingolog.org/ ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: srfi-18 and the vm 2009-05-23 22:16 ` Andy Wingo @ 2009-05-24 14:08 ` Ludovic Courtès 2009-05-25 21:57 ` Neil Jerram 0 siblings, 1 reply; 14+ messages in thread From: Ludovic Courtès @ 2009-05-24 14:08 UTC (permalink / raw) To: guile-devel Hello, Andy Wingo <wingo@pobox.com> writes: > For loading uncompiled scripts, things will be slower, unless your > modules #:use-syntax some other transformer. I don't know where the > tradeoff is between the increased expansion speed due to compilation and > slowdown due to a complete codewalk, but it's certainly there. Yes. Likewise, it may be reasonable to assume from now on that most of the code will be compiled. For instance, an uncompiled script may just be a small code snipped that uses mostly compiled code. > OTOH I would suspect that we can implement some kind of just-in-time > compilation -- essentially for each use-modules we can check to see if > the module is compiled, and if not just compile it then and there. It > would be a little slow the first time, but after that it would load much > faster, even faster than before. Python does this. We could add a guile > --no-comp option to disable it. I don't like this idea because it implies implicitly letting Guile fiddle with the user's file system. OTOH, it's a pragmatic approach to the problem at hand. Thanks, Ludo'. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: srfi-18 and the vm 2009-05-24 14:08 ` Ludovic Courtès @ 2009-05-25 21:57 ` Neil Jerram 2009-05-29 9:55 ` Andy Wingo 0 siblings, 1 reply; 14+ messages in thread From: Neil Jerram @ 2009-05-25 21:57 UTC (permalink / raw) To: Ludovic Courtès, Andy Wingo; +Cc: guile-devel ludo@gnu.org (Ludovic Courtès) writes: > Hello, > > Andy Wingo <wingo@pobox.com> writes: > >> For loading uncompiled scripts, things will be slower, unless your >> modules #:use-syntax some other transformer. I don't know where the >> tradeoff is between the increased expansion speed due to compilation and >> slowdown due to a complete codewalk, but it's certainly there. > > Yes. Likewise, it may be reasonable to assume from now on that most of > the code will be compiled. For instance, an uncompiled script may just > be a small code snipped that uses mostly compiled code. It seems to me that once we have a completely working compiler, we need to ask if there are any circumstances left where it is better to use the current interpreter instead. If the answer to that is yes, the details of those remaining circumstances will (probably) make it obvious whether the pre-memoization idea is worthwhile. Do we already have performance measurements, and are those recorded / summarized somewhere? >> OTOH I would suspect that we can implement some kind of just-in-time >> compilation -- essentially for each use-modules we can check to see if >> the module is compiled, and if not just compile it then and there. It >> would be a little slow the first time, but after that it would load much >> faster, even faster than before. Python does this. We could add a guile >> --no-comp option to disable it. > > I don't like this idea because it implies implicitly letting Guile > fiddle with the user's file system. I don't see why that should be. Isn't it possible to read a .scm file, compile its contents, and hold the compiled programs in memory? Regards, Neil ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: srfi-18 and the vm 2009-05-25 21:57 ` Neil Jerram @ 2009-05-29 9:55 ` Andy Wingo 2009-05-30 23:07 ` Neil Jerram 0 siblings, 1 reply; 14+ messages in thread From: Andy Wingo @ 2009-05-29 9:55 UTC (permalink / raw) To: Neil Jerram; +Cc: Ludovic Courtès, guile-devel Hi Neil, On Mon 25 May 2009 23:57, Neil Jerram <neil@ossau.uklinux.net> writes: > ludo@gnu.org (Ludovic Courtès) writes: > >> Andy Wingo <wingo@pobox.com> writes: >> >>> For loading uncompiled scripts, things will be slower, unless your >>> modules #:use-syntax some other transformer. I don't know where the >>> tradeoff is between the increased expansion speed due to compilation and >>> slowdown due to a complete codewalk, but it's certainly there. >> >> Yes. Likewise, it may be reasonable to assume from now on that most of >> the code will be compiled. For instance, an uncompiled script may just >> be a small code snipped that uses mostly compiled code. > > It seems to me that once we have a completely working compiler, we > need to ask if there are any circumstances left where it is better to > use the current interpreter instead. In the short term (within the next year or so), I would imagine that ceval/deval would be faster than an eval written in Scheme -- though I do not know. On the other hand, an eval written in Scheme would allow for tail-recursive calls between the evaluator and the VM. Another option, besides an eval in Scheme, is replacing the evaluator with the compiler. One could compile on the fly and run the compiled code from memory, or cache to the filesystem, either alongside the .scm files or in a ~/.guile-comp-cache/ or something. But compilation does take some time. It seems clear we still need an eval in C, at least to bootstrap Guile. WRT replacing ceval, I guess my conclusion is that I don't know yet. > If the answer to that is yes, the details of those remaining > circumstances will (probably) make it obvious whether the > pre-memoization idea is worthwhile. Yes, perhaps. We probably need some timings. > Do we already have performance measurements, and are those recorded / > summarized somewhere? We don't have very systematic ones. I was just running some of the feeley benchmarks again, and it looked to me that the VM's speed is about 3 or 4 times the speed of ceval in 1.9, but I should test with benchmarks that run for only 1s or so, and measure compilation time, and test against 1.8 too. >>> OTOH I would suspect that we can implement some kind of just-in-time >>> compilation -- essentially for each use-modules we can check to see if >>> the module is compiled, and if not just compile it then and there. It >>> would be a little slow the first time, but after that it would load much >>> faster, even faster than before. Python does this. We could add a guile >>> --no-comp option to disable it. >> >> I don't like this idea because it implies implicitly letting Guile >> fiddle with the user's file system. > > I don't see why that should be. Isn't it possible to read a .scm > file, compile its contents, and hold the compiled programs in memory? Yes, compile-and-load, from (system base compile). But you have to redo the compilation the next time the file is loaded, of course. Incidentally, ikarus had a similar discussion recently: http://thread.gmane.org/gmane.lisp.scheme.ikarus.user/723 http://thread.gmane.org/gmane.lisp.scheme.ikarus.user/745 Cheers, Andy -- http://wingolog.org/ ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: srfi-18 and the vm 2009-05-29 9:55 ` Andy Wingo @ 2009-05-30 23:07 ` Neil Jerram 2009-05-31 13:30 ` Andy Wingo 0 siblings, 1 reply; 14+ messages in thread From: Neil Jerram @ 2009-05-30 23:07 UTC (permalink / raw) To: Andy Wingo; +Cc: Ludovic Courtès, guile-devel Andy Wingo <wingo@pobox.com> writes: > Hi Neil, > > On Mon 25 May 2009 23:57, Neil Jerram <neil@ossau.uklinux.net> writes: > >> ludo@gnu.org (Ludovic Courtès) writes: >> >>> Andy Wingo <wingo@pobox.com> writes: >>> >>>> For loading uncompiled scripts, things will be slower, unless your >>>> modules #:use-syntax some other transformer. I don't know where the >>>> tradeoff is between the increased expansion speed due to compilation and >>>> slowdown due to a complete codewalk, but it's certainly there. >>> >>> Yes. Likewise, it may be reasonable to assume from now on that most of >>> the code will be compiled. For instance, an uncompiled script may just >>> be a small code snipped that uses mostly compiled code. >> >> It seems to me that once we have a completely working compiler, we >> need to ask if there are any circumstances left where it is better to >> use the current interpreter instead. > > In the short term (within the next year or so), I would imagine that > ceval/deval would be faster than an eval written in Scheme -- though I > do not know. I wasn't thinking of an eval written in Scheme. I was assuming the other option that you mention below, i.e. eval becomes compile on the fly followed by VM execution. > On the other hand, an eval written in Scheme would allow for > tail-recursive calls between the evaluator and the VM. > > Another option, besides an eval in Scheme, is replacing the evaluator > with the compiler. One could compile on the fly and run the compiled > code from memory, or cache to the filesystem, either alongside the .scm > files or in a ~/.guile-comp-cache/ or something. > > But compilation does take some time. I guess this is the key point. Even when the compiler has itself been compiled? So would it be correct to say, based on your performance observations so far, that the time needed to compile and then VM-execute a piece of code is greater than the time needed to interpret the same piece of code? In other words, that ahead-of-time compilation is helpful, performance-wise, but that just-in-time compilation is net negative? (Perhaps that is a ridiculous question even to ask... It may be well known that just-in-time compilation is always net negative if you only consider one execution of the code concerned. I'm afraid I'm not familiar enough with the CS background on this.) > It seems clear we still need an eval in C, at least to bootstrap Guile. Yes, good point, I had forgotten that! >> Do we already have performance measurements, and are those recorded / >> summarized somewhere? > > We don't have very systematic ones. I was just running some of the > feeley benchmarks again, and it looked to me that the VM's speed is > about 3 or 4 times the speed of ceval in 1.9, but I should test with > benchmarks that run for only 1s or so, and measure compilation time, and > test against 1.8 too. So, extremely roughly, that would mean that just-in-time compilation could only be net-zero or net-positive if the complexity of the compilation code was less than 3 or 4 times the complexity of the code being compiled. Which for a short piece of code is unlikely. >>>> OTOH I would suspect that we can implement some kind of just-in-time >>>> compilation -- essentially for each use-modules we can check to see if >>>> the module is compiled, and if not just compile it then and there. It >>>> would be a little slow the first time, but after that it would load much >>>> faster, even faster than before. Python does this. We could add a guile >>>> --no-comp option to disable it. >>> >>> I don't like this idea because it implies implicitly letting Guile >>> fiddle with the user's file system. >> >> I don't see why that should be. Isn't it possible to read a .scm >> file, compile its contents, and hold the compiled programs in memory? > > Yes, compile-and-load, from (system base compile). But you have to redo > the compilation the next time the file is loaded, of course. > > Incidentally, ikarus had a similar discussion recently: > > http://thread.gmane.org/gmane.lisp.scheme.ikarus.user/723 > http://thread.gmane.org/gmane.lisp.scheme.ikarus.user/745 I see; good references - there's no need for us to have the same conversation again! I think I agree with Aziz's conclusion - i.e. "auto-caching" should be disabled by default. The thread suggested to me that Ikarus has to compile the code that it reads before it can execute it; i.e. that it doesn't retain an interpretation option. Is that correct? If so, Guile might reasonably make slightly different decisions - e.g. to interpret a module when using it for the first time, and also to start compiling it on another thread, with the module's procedures being replaced one-by-one by VM programs as the compilation progresses. Regards, Neil ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: srfi-18 and the vm 2009-05-30 23:07 ` Neil Jerram @ 2009-05-31 13:30 ` Andy Wingo 0 siblings, 0 replies; 14+ messages in thread From: Andy Wingo @ 2009-05-31 13:30 UTC (permalink / raw) To: Neil Jerram; +Cc: Ludovic Courtès, guile-devel Ni Neil, On Sun 31 May 2009 01:07, Neil Jerram <neil@ossau.uklinux.net> writes: > Andy Wingo <wingo@pobox.com> writes: > >> In the short term (within the next year or so), I would imagine that >> ceval/deval would be faster than an eval written in Scheme -- though I >> do not know. > > I wasn't thinking of an eval written in Scheme. I was assuming the > other option that you mention below, i.e. eval becomes compile on the > fly followed by VM execution. Incidentally, the REPL compiles by default now, and has been doing so since VM was merged to master. But expressions at the REPL are less code than are full libraries. >> But compilation does take some time. > > I guess this is the key point. Even when the compiler has itself been > compiled? Much less time in that case, of course. It's the difference between the load-compiled case and the ceval case below. I think my understanding of the performance equation goes like this: 1.8 ceval time = (read time) + ((% of executed code) * (memoization time)) + (ceval runtime) 1.9 ceval time = (psyntax expansion time) + (1.8 ceval time) 1.9 compile time = (read time) + (psyntax expansion time) + (compile time) 1.9 load-compiled time = (VM runtime) 1.9 compile-and-load time = (1.9 compile time) + (1.9 load-compiled time) Let's say that (VM runtime) == 1/4 * (ceval runtime). Then: (1.9 compile-and-load time) < (1.9 ceval time) if (compile time) < (% of executed code) * (memoization time) + 3/4 * (ceval runtime) Compile-time and memozation time depend linearly on the "complexity" of the code, as you say. And my suspicion is that memoization doesn't actually take very much time, compared to expansion. So a simpler version would be that we win when: (compile time) < 3/4 * (ceval runtime) Of course there is probably a lower bound to all of this, that we don't care about differences under 50 ms or so, when operating on non-compiled code. So if we keep compile time always under 40 ms or so, we're good. Now how do we stack up, then? Well: scheme@(guile-user)> (use-modules (ice-9 time) (system base compile)) scheme@(guile-user)> (time (compile-file "module/language/tree-il.scm")) clock utime stime cutime cstime gctime 1.17 1.03 0.14 0.00 0.00 0.30 $1 = "module/language/tree-il.go" scheme@(guile-user)> (time (compile-file "module/language/tree-il.scm")) clock utime stime cutime cstime gctime 1.06 0.91 0.14 0.00 0.00 0.16 $2 = "module/language/tree-il.go" scheme@(guile-user)> (time (compile-file "module/language/tree-il/spec.scm")) clock utime stime cutime cstime gctime 0.03 0.03 0.00 0.00 0.00 0.01 $3 = "module/language/tree-il/spec.go" scheme@(guile-user)> (time (compile-file "module/language/tree-il/spec.scm")) clock utime stime cutime cstime gctime 0.02 0.02 0.00 0.00 0.00 0.00 $4 = "module/language/tree-il/spec.go" scheme@(guile-user)> (time (compile-file "module/language/assembly/disassemble.scm")) clock utime stime cutime cstime gctime 0.25 0.20 0.05 0.00 0.00 0.04 $5 = "module/language/assembly/disassemble.go" scheme@(guile-user)> (time (compile-file "module/language/assembly/disassemble.scm")) clock utime stime cutime cstime gctime 0.26 0.23 0.03 0.00 0.00 0.03 $6 = "module/language/assembly/disassemble.go" scheme@(guile-user)> (time (compile-file "module/language/tree-il/compile-glil.scm")) clock utime stime cutime cstime gctime 0.53 0.44 0.09 0.00 0.00 0.10 $7 = "module/language/tree-il/compile-glil.go" scheme@(guile-user)> wingo@unquote:~/src/guile$ ls -l module/language/tree-il.scm module/language/tree-il/spec.scm module/language/assembly/disassemble.scm module/language/tree-il/compile-glil.scm -rw-rw-r-- 1 wingo wingo 6467 2009-05-29 15:39 module/language/assembly/disassemble.scm -rw-rw-r-- 1 wingo wingo 16377 2009-05-29 15:39 module/language/tree-il/compile-glil.scm -rw-rw-r-- 1 wingo wingo 11734 2009-05-29 15:39 module/language/tree-il.scm -rw-rw-r-- 1 wingo wingo 1390 2009-05-29 15:39 module/language/tree-il/spec.scm This is on my laptop, with the ondemand cpu speed thingie. It seems expansion itself is taking a bit of this time: scheme@(guile-user)> ,m language tree-il scheme@(language tree-il)> (use-modules (ice-9 time)) scheme@(language tree-il)> (time (with-input-from-file "module/language/tree-il.scm" (lambda () (let lp ((x (read))) (if (not (eof-object? x)) (begin (sc-expand x) (lp (read)))))))) clock utime stime cutime cstime gctime 0.44 0.44 0.01 0.00 0.00 0.12 scheme@(language tree-il)> ,m language assembly disassemble scheme@(language assembly disassemble)> (use-modules (ice-9 time)) scheme@(language assembly disassemble)> (time (with-input-from-file "module/language/assembly/disassemble.scm" (lambda () (let lp ((x (read))) (if (not (eof-object? x)) (begin (sc-expand x) (lp (read)))))))) clock utime stime cutime cstime gctime 0.10 0.09 0.00 0.00 0.00 0.02 Indeed, the expander seems to take most of the time when loading (ice-9 match). I've run all of these in fresh Guiles so one expansion doesn't have the cost of creating a module: scheme@(guile-user)> (time (load "module/ice-9/match.scm")) clock utime stime cutime cstime gctime 1.02 0.98 0.01 0.00 0.00 0.26 scheme@(guile-user)> (time (with-input-from-file "module/ice-9/match.scm" (lambda () (let lp ((x (read))) (if (not (eof-object? x)) (begin (sc-expand x) (lp (read)))))))) clock utime stime cutime cstime gctime 0.97 0.95 0.01 0.00 0.00 0.25 scheme@(guile-user)> (time (compile-file "module/ice-9/match.scm")) clock utime stime cutime cstime gctime 3.40 3.01 0.39 0.00 0.00 0.79 scheme@(guile-user)> (time (load-compiled "module/ice-9/match.go")) clock utime stime cutime cstime gctime 0.00 0.00 0.00 0.00 0.00 0.00 Conclusions: * The 1.8 memoizer was a big win, because the % of executed code could be very small -- loading (ice-9 match) never had to traverse all of those nodes. OTOH, the memoizer seems to be irrelevant with psyntax run on all of the source code, because expansion has to traverse all nodes, so you don't get the savings. * Currently, expansion seems to take between 30% and 40% of compile time. (I imagine we can reduce this absolute time by a factor of 2 or so with some more optimized compilation of multiple-values cases, which should be easy, and the addition of an inliner, which will be a bit of work.) * Of course, once code is compiled, loading it is *very* fast, and I believe it to run at about 3 or 4 times the speed, though I have not shown that here. I guess the big question is, what will the impact be on our users? I suppose we can divide those users into three categories: * People who write short scripts in Guile, using standard libraries. These people are likely to see no change, speed-wise. Guile might start up faster and the libraries might load faster, but then again, perhaps their scripts take 300 ms to expand, which makes that speed gain moot. We could offer them compilation of their scripts, in the compile-and-load sense, which could help if their scripts take a long time to run. * People who write big programs in Guile. These people will likely be irked by the initial slowness with which their programs run, but will also likely be receptive to compiling their own programs and libraries, which will make them much faster. It is likely that these people have butted up against Guile's speed limitations. * People who use programs written in Guile, but that don't know anything about compiling or maybe even Scheme. This people are most likely to be adversely affected by all of this. Their programs start up more slowly, and for no obvious reason. I get the feeling that we really should compile libraries by default. We can put the results in ~/.guile-something if we don't have permissions to put them alongside the .scm files -- that allows for sharing in multiuser installations, but doesn't require it. This way we offer more advantages to our users. But I don't know. What do yall think? >> Incidentally, ikarus had a similar discussion recently: >> >> http://thread.gmane.org/gmane.lisp.scheme.ikarus.user/723 >> http://thread.gmane.org/gmane.lisp.scheme.ikarus.user/745 > > I see; good references - there's no need for us to have the same > conversation again! I think I agree with Aziz's conclusion - > i.e. "auto-caching" should be disabled by default. I think I might have convinced myself otherwise. > The thread suggested to me that Ikarus has to compile the code that it > reads before it can execute it; i.e. that it doesn't retain an > interpretation option. Is that correct? Yes. > If so, Guile might reasonably make slightly different decisions - e.g. > to interpret a module when using it for the first time, and also to > start compiling it on another thread, with the module's procedures > being replaced one-by-one by VM programs as the compilation > progresses. Interesting idea :) Cheers, Andy -- http://wingolog.org/ ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2009-05-31 13:30 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-05-22 14:39 srfi-18 and the vm Andy Wingo 2009-05-22 15:01 ` Julian Graham 2009-05-22 15:10 ` Ludovic Courtès 2009-05-22 16:20 ` Andy Wingo 2009-05-22 22:04 ` Ludovic Courtès 2009-05-23 9:52 ` Neil Jerram 2009-05-23 16:38 ` Andy Wingo 2009-05-23 22:03 ` Ludovic Courtès 2009-05-23 22:16 ` Andy Wingo 2009-05-24 14:08 ` Ludovic Courtès 2009-05-25 21:57 ` Neil Jerram 2009-05-29 9:55 ` Andy Wingo 2009-05-30 23:07 ` Neil Jerram 2009-05-31 13:30 ` Andy Wingo
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).