On 2013-04-16 22:58:24, Artella Coding wrote:
> Hi James,
> 
> Thanks for the response. I have a few questions below :
> 
> >As for the exponetial slow-down, it's related to the fact that io is
> asynchronous and
> >handled by the scheduler task, but tasks are scheduled co-operative meaning
> >a CPU-intensive task can block other tasks in the same thread.
> 
> But why is it the case that calling "first" twice results in the twice the
> execution time as compared to calling "first" once, whereas calling
> "second" twice results in much more than doubling of execution time as
> compared to a call of "second" once. I did realise that "second" would be
> slower as no inlining would be performed, but what was more important to me
> was the way the program scales with function calls.
> 
> In particular what is it about calling a nested function (as compared to
> calling a non-nested function) that results in the io behaving in an
> unexpected way?
> 
> >I haven't yet figured out
> >the specific reasons, but wrapping each call to `second` in it's own task
> causes the time
> >to drop from ~1 minute to 7 seconds. If you account for parallelism from
> running in
> >multiple threads, then `time` reports ~15 seconds. Which is double.
> 
> How can I wrap each "second" call in its own task? Thanks
> 
> On Tue, Apr 16, 2013 at 2:37 AM, James Miller <[email protected]> wrote:
> 
> > As for the exponetial slow-down, it's related to the fact that io is
> > asynchronous and
> > handled by the scheduler task, but tasks are scheduled co-operative meaning
> > a CPU-intensive task can block other tasks in the same thread. I haven't
> > yet figured out
> > the specific reasons, but wrapping each call to `second` in it's own task
> > causes the time
> > to drop from ~1 minute to 7 seconds. If you account for parallelism from
> > running in
> > multiple threads, then `time` reports ~15 seconds. Which is double.
> > Rust-dev mailing list
> > [email protected]
> > https://mail.mozilla.org/listinfo/rust-dev
> >

I'm not entirely familiar on the inner workings of the scheduler. It's a little 
bit magic to me still. However, I did find that by moving the IO out of the 
way, so all the calculation happened then the output, the scaling was linear as
you'd expect.

If I had to guess, then I would say that the increased memory usage of calling 
an inner function tips some internal limit over and makes the scheduler thrash 
for a while. IIRC rust functions are passed an environment pointer, and I think
that the environment pointer for a top-level function is NULL, whereas it is 
not for closures and inner functions (internally Rust makes no significant 
distinction between the different "types" of functions, they are all more or 
less the same by the time it gets to code gen). It would explain why even level 
1
optimization fixed it, since I think LLVM would optimize out the unused 
environment as a dead store. However I am just guessing about that.

At any rate Patrick Walton (@pcwalton) is working on a new scheduler that fixed
many of the issues with the current one. So it is possible that this issue will
be solved by 0.7/8.

As for tasks, http://static.rust-lang.org/docs/0.6/core/task.html is where you 
want to look. The most basic version is `task::spawn` which takes a closure.  
this means that you write

    do task::spawn {
        /* my code here */
    }

to spawn a task.

Simple.

Thanks

--
James Miller
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to