[plt-dev] Re: Speed up check-syntax
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!
>