🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Running commentary. Because you love it.

Published March 08, 2009
Advertisement
0327 Hours
So, here I am, awake at stupid-o'clock, working on adding parallel processing fundamentals to Epoch. Most of my time in the past 18 hours or so has been spent fixing up dozens of small bugs and omissions in the binary loader. On the plus side, this means all the SDK examples work, and the assembler/disassembler tool chain is a bit more refined.

With all the housekeeping work finished, it's time to take a look at what I originally planned to do today - the task operation. I'm still working out the syntax for this, and I still need to decide how exactly messages will be sent between tasks, but the groundwork can at least be done.

The task operation is pretty much what it sounds like - any code inside a task block will run in a parallel thread context. Eventually this will also support running tasks on a specific processor type (e.g. heavily vectorized math that can be done on a GPU, etc.).

Step 1 is now complete: I've added the operation to the parser grammar. Now it's time to update the parser state machine to handle tasks.


0442 Hours
Tasks are now correctly forking threads and running in parallel to the main program. However, there is a bit of a wrinkle in the plan: while each task gets its own stack space, it uses a single shared global set of metadata describing the lexical scope and its contents. The upshot of this is that calling the same function from two different tasks causes utter mayhem.

So my next big job is to figure out how to solve this issue. I was originally hoping to get tasks and message passing done over the weekend, but this new problem (coupled with my very important plans for seeing Watchmen tomorrow) has set things back a bit. For now I'll be happy just to see tasks working properly; we can mess with messages later.


0648 Hours
Yep, still up and cranking away.

I've run into a fascinating little bug, which grew out of the fix to the last problem. Specifically, I started by having each lexical scope clone itself the first time the scope is used in a new thread. This means that each thread gets a separate copy of the scope metadata, which can then be used to execute the code within that thread.

This works fine. The problem comes in when one of these clones points to a parent scope. Since the scope clones itself when entering a new thread, the scope also carries with it the pointer to its parent scope. However, the pointer is to the scope of a different thread. So any time a function is called from two separate threads - even if the calls are not simultaneous - one function instance clobbers the other's data, and everything comes to a very sudden halt.

I've been through a half-dozen solutions and rejected all of them. Some required traversing the entire program to fix up errant scope pointers - possible for tiny demo apps, but it would never scale to real-world code. Some other solutions required a global list that each thread would have to lock every time a new lexical scope was entered - way too much processing overhead.

So I'm wracking my poor sleepy brain, trying to come up with a lockless and efficient method for fixing up scope parent pointers so they enforce thread locality. Yayy.


Maybe I'll get some sleep.
Next Entry Woohoo!
0 likes 1 comments

Comments

Twisol
You can do it! [grin] Now go to bed. [lol]

(Also, Twitter makes for great on-the-go commentary. <zombie>Jooooin ussss.</zombie>)

~Jonathan
March 08, 2009 01:40 AM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement