[plt-dev] Re: Speed up check-syntax
PS: feel free to check this in, but it probably belongs in
scribble/xref or setup/xref, not in the syntax checker.
Robby
On Mon, Nov 9, 2009 at 4:13 PM, Robby Findler
<robby at eecs.northwestern.edu> wrote:
> Thanks, Eli. That looks nice.
>
> Matthew suggested something similar, but using mzlib/couroutine, where
> I use a low-priority gui callback to give the thread the next quantum.
>
> Robby
>
> On Mon, Nov 9, 2009 at 4:08 PM, Eli Barzilay <eli at barzilay.org> wrote:
>> [Moving to plt-dev.]
>>
>> On Nov 9, Robby Findler wrote:
>>>
>>> I find such behavior annoying in my OS and expect it would be the
>>> same in DrScheme. Things will be sluggish while it is loading.
>>>
>>> Nevertheless, I will try this if the parallelism stuff doesn't pan
>>> out.
>>
>> 1. I find the delay-on-first-syncheck especially annoying in class. I
>> always start a new drscheme at the beginning of the class, which
>> means that I'm guaranteed to get the annoying delay. (And it's a
>> classic case of unjustified delay, since drscheme will sit there
>> for many minutes doing nothing before I get to use it.) It's at a
>> level where I hesitate to use it -- and on some occasions I
>> pre-arrange myself so that I click it while I speak to mask out the
>> delay. (Being able to do such things is something that I had to
>> learn as a stutterer...)
>>
>> 2. BTW, the status-line message is not showing at all on linux. I
>> never knew that there was supposed to be such a message. (I almost
>> never run it on my laptop.)
>>
>> 3. IMO, the issue will not be completely resolved with multiple
>> cores. What if my other core is busy doing something else? What
>> about school machines that can be very outdated? What about IO
>> delays, since this does involve mostly IO?
>>
>> 4. The usual way to do these things is to have it loaded when it is
>> idle (exactly what Stephen said) -- but then don't just start to
>> load it so everything becomes slow, just do that in little
>> execution chunks which are done only if the system is still
>> otherwise idle. I think that MzScheme could use some more
>> functionality in this area -- a nice feature to have would be a way
>> for a thread to change its priority where this can also be a "run
>> me only when otherwise idle" (it would be especially nice to have a
>> hierarchy of these: "run me when otherwise idle including 1st-level
>> idle-priority threads, and give me only 20% running time").
>>
>> 5. Fantasies aside, I think that it is possible to do a reasonable job
>> for this given the current tools. The code below looks to me like
>> it should work fine. It runs a given thunk in the background while
>> drscheme is idle, and using little cpu time so there's no alarming
>> cpu load. The returned result is a thunk that returns the computed
>> value -- waiting for it (while giving it 100% cpu) if it isn't
>> ready yet.
>>
>> 6. To try it, I basically changed "syncheck.ss" with this definition:
>>
>> (define get-xref
>> (run-lazily (lambda ()
>> (with-handlers ([exn? (lambda (_) #f)])
>> (load-collections-xref)))))
>>
>> I've tried it in DrScheme (on my Windows laptop, so the delay is
>> more noticeable), and it looks like it works fine. No need for
>> multicore support...
>>
>> 7. Maybe this would be a good addition to `scheme/promise'.
>>
>>
>>
>> ;; Run `thunk' when idle, slicing the time to `slice'-second frames,
>> ;; using only `use' seconds from each frame. Return a thunk that
>> ;; returns the result of the computation, giving it full cpu if it's not
>> ;; ready yet.
>> (define (run-lazily thunk #:slice [slice 0.3] #:use [use 0.05])
>> (define idle-evt (system-idle-evt))
>> (define force-sema (make-semaphore 0))
>> (define results #f)
>> (define (work)
>> (with-handlers ([void (lambda (e) (set! results (cons raise e)))])
>> (set! results (cons values (call-with-values thunk list)))))
>> (define (start)
>> (sync idle-evt)
>> (let ([worker (parameterize ([current-thread-group (make-thread-group)])
>> (thread work))])
>> (thread-suspend worker)
>> (let loop ()
>> ;; rest, then wait for idle time, then resume working
>> (if (eq? (begin0 (or (sync/timeout (- slice use) force-sema)
>> (sync idle-evt force-sema))
>> (thread-resume worker))
>> force-sema)
>> ;; forced during one of these => let it run to completion
>> (thread-wait worker)
>> ;; not forced
>> (unless (sync/timeout use worker) (thread-suspend worker) (loop))))))
>> (define main-thread
>> (parameterize ([current-thread-group (make-thread-group)])
>> (thread start)))
>> (lambda ()
>> (unless (thread-dead? main-thread)
>> (semaphore-post force-sema)
>> (thread-wait main-thread))
>> (apply (car results) (cdr results))))
>>
>> --
>> ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
>> http://barzilay.org/ Maze is Life!
>>
>