Windows: Throwing Exceptions from Fibers in D2.059: Access Violation
Andrew Lauritzen
andrew.lauritzen at gmail.com
Fri Apr 20 10:21:28 PDT 2012
> To be precise, fibers in and of themselves aren't exacty what I
> want, but are the best means to getting it that I've seen so
> far. They enable efficient implementation of coroutines, which
> many languages either cannot express at all, or can only
> express very poorly by using the sledgehammer of a full-on
> kernel thread to get it. A call stack is a very useful way to
> group logic, and being forced to go outside the language and
> ask the OS for another one is a shame.
>
> Game logic is an area where this technique REALLY shines. Case
> in point: Unity3D. The entire engine is built around C#'s
> iterator method facility to implement coroutines to control
> entity logic. Hundreds or even thousands of them can be active
> with very little overhead compared to a full thread context
> switch. Unfortunately, they're hamstrung by not being a true
> coroutine (you can only yield from the top frame).
>
Right, exactly the above! Fibers are totally uninteresting as a
"lighter thread" or unit of scheduling for the reasons that you
note, but coroutines are just a better way to write a lot of
code. This is basically the entire premise for the Go programming
language, so it's worth taking a peek at that if you haven't
already.
In my example, it's effectively to yield and restore
connection-specific state for different clients. In the
equivalent C code, it's a gigantic mess of a state machine
specified by big switch statements and is almost impossible to
follow the intended flow. With coroutines it's quite simple: you
write the code in the most natural way - as if your sockets were
blocking - and when you would otherwise block, you yield the
fiber instead and come back to it when more socket data is
available. Go takes this a step further by embedding the yields
(and more) into both the standard library and the language
itself. It's quite a powerful programming model for certain types
of work.
When I started running into fiber issues I tried to use threads
instead (just to avoid the issues; I have no need of the
parallelism or other utilities that they provide in this
application) but I ran into a bunch of problems.
First, D's insistence on message-passing, while noble and
respectable, is not a perfect fit for cases where I have no need
or desire to synchronize large portions of the data structures.
In general, this sort of coarse-grained opportunistic parallelism
extracts very few additional useful cycles out of multicore
hardware compared to a more targeted fine-grained approach. As
you note, there's a reason that a lot of the scheduling is
starting to move more to user-space "tasks".
(As an aside, it would be awesome to see a Cilk-like work
stealing implementation in D. That's by far the easiest first
step to really extracting parallelism our of programs and you can
often get most of the benefit just with that. It's yet another
elegant way to use the call-stack for expressing and exploiting
parallelism and dependencies.)
Second, and more importantly, there didn't seem to be a clean way
to wait on multiple things in D right now. For instance, I want
to yield a thread/fiber until there is either a socket state
change, *or* a thread message. This can be a minor problem with
fibers, but less-so since the fiber itself can basically just
take over whatever work needs to be done rather than trying to
wake other threads. There doesn't seem to be a clean way to do
this in D currently other than waking threads and basically
polling multiple things, which I'm sure you can agree is not
ideal.
> Stack overflow? Give the fiber a larger stack when you create
> it. The default is really rather small.
I'm fairly certain that it's not a "real" stack overflow... the
program continues to operate normally unless the debugger is
stepping through and it only happens when an exception is thrown.
And it happens pretty much always when an exception is thrown,
you just won't see it unless you have a debugger attached to see
the output. So like I said, it is somewhat worrisome, but the
program seems to be running properly despite it, so it may be a
red herring.
More information about the Digitalmars-d
mailing list