|
My brain is built of paths and slides and ladders and lasers and I have invited all of you to enter its pavilion. My brain, as you enter, will smell of tangerines and brand-new running shoes.
 Epoch Release 8 |
Posted - 2/8/2010 9:18:50 PM | Release 8 of the Epoch language project is getting really close to ready to ship... finally!
I scraped together a couple of hours this evening and knocked out the remaining work for thread pooling support. The big caveat to using worker thread pools is that you can't pass messages to a pooled thread, because there is no way to identify which thread(s) are actually idle and ready to receive such a message.
You can send a message from a worker thread, and the target thread can reply to sender(), so it isn't impossible to communicate with pooled threads - just slightly less convenient than with task threads.
This brings R8 down to only a few outstanding items; another thing I got done today is support for building a runnable .EXE given just a standalone .epoch code file. There is no longer any need to set up a project in order to build a distribution-ready Epoch binary.
I also added a compiler switch which lets you choose whether or not to spawn a debug console when the program begins. Console apps can use this flag to get their own console space as they expect, and GUI apps can rest at ease knowing that there won't be an empty console window hovering around in the background.
There's a whopping four outstanding issues for R8, roughly prioritized as follows:
- Fix bug in the Scribble project (possible parser bug)
- Ensure that projects, compilation, assembly, disassembly, and binary generation are all functional
- Improve build configurations in the Epoch project
- Fix bug in Exegen which can mangle filenames/paths
You can watch the work list for Epoch at any time via our issue tracker. If you're more of an RSS person, check out our feed list. Live previews of the development fork can be browsed via our Mercurial repository, or directly on the web.
R8 will not have a particularly potent implementation of the CUDA integration yet, mainly because I just haven't had the time to play with the cross-compiler much. I intend to get much better support in place for R9/GDC'10 - enough to do a non-trivial demo of using CUDA threads on the GPU vs. using CPU threading.
I also need to implement failover support so that if CUDA is not available on the host machine, the VM falls back to CPU threads rather than trying to use the GPU. There are still a few architectural and syntax questions left to be solved before I can do that, but nothing major.
All in all, assuming I manage to avoid being hit by a bus and/or flying rhinoceros, R8 should be out Very Soon™ and R9 will be hot on its heels. With any luck the GDC'10 preview kit will have some nice goodies that'll really turn some heads 
| |
 Some basic C++ template metaprogramming |
Posted - 1/31/2010 12:11:53 PM | As much as I hate the language, I have to admit that C++ has an impressive amount of power under the hood - even though accessing that power sometimes requires some insane contortions. In particular, I'm always interested in the tricks that people come up with for template metaprogramming. They are usually perverse, twisted, and bizarre. Sometimes they are outright evil. It's gross what one has to do to really apply C++ to its fullest, but the fact that such a primitive language can do such things at all is still pretty impressive.
I ran into a situation the other day involving templated copy constructors, where the template was allowing some weird implicit conversions to take place that it really shouldn't have permitted. (For instance, converting from a FooClass* to a double. WTF, C++. WTF.)
Of course in a nicer language I would be able to trap and prevent such conversions easily; but C++ is, naturally, not a nice language. So I had to dig into the bag of magical goodies and whip out some high-powered voodoo.
Along the way, I realized that the workings of the code were pretty arcane, especially to newer C++ programmers. In the interest of helping my colleagues understand all the gibberish in the new code, I went through and heavily documented exactly how all of it works.
Hopefully, you'll find this interesting and informative 
#pragma once
template<class T1, class T2>
struct CanConvertTypes
{
typedef char (&yes)[1];
typedef char (&no)[2];
static yes TestDummy(T2*);
static no TestDummy(...);
enum PerformConversionCheck { CheckResult = (sizeof(TestDummy(static_cast<T1*>(NULL))) == sizeof(yes)) };
};
struct EnableIfDummy { };
template<bool> struct EnableIfTypesCanBeConvertedHelper;
template<> struct EnableIfTypesCanBeConvertedHelper<true> { typedef EnableIfDummy type; };
template<> struct EnableIfTypesCanBeConvertedHelper<false> { };
template<class T1, class T2>
struct EnableIfTypesCanBeConverted : public EnableIfTypesCanBeConvertedHelper<CanConvertTypes<T1, T2>::CheckResult> { };
| |
| Saturday, January 30, 2010 |
 Updates, of various kinds |
Posted - 1/30/2010 2:13:09 PM | Well, it's obviously getting real close to the end of January, and Epoch Release 8 is still obviously not here.
I had really hoped not to slip the schedule on this one, but other commitments have come up, and I just haven't had the time I'd like to pour into it. I still do plan to finish it up as quickly as I can, and start working on the GDC preview release; but that may take a few extra days. The tasklist is pretty much as it was before, although I've made steady progress in a couple of areas.
In any case, interest seems to have died off again on the project, so there's probably nobody out there getting all heart-broken about missing a release 
| |
| Wednesday, January 27, 2010 |
 We Are All On Drugs |
Posted - 1/27/2010 1:49:55 AM | So... Mass Effect 2 is remarkably kick-ass. I have one complaint about the game: it's chewing into my Bayonetta time 
Also, sleep is for the weak.
And now back to your regularly scheduled lack of content. (What? I'm busy! Got games to play, things to do! Get off my case.)
| |
| Tuesday, January 19, 2010 |
 Mmm, goodies. |
Posted - 1/19/2010 11:48:40 AM | Last week my nice happy 22" monitor on my main workstation decided to die. That's left me with just two 17" 1280x1024 displays to use, and that just doesn't cut it for serious development anymore. (Two or three instances of Visual Studio, a half dozen Notepad windows, a couple of Skype discussions, a few Explorer windows for rooting around in various code branches, a browser instance or two... you need your real estate these days.) So I decided to bite the bullet and pick up a couple of new widescreens to replace my old 22W/17 pairing. My two 17" displays will get shuffled over to my newly minted Linux development box, with one doing double duty as the display for my (usually headless) router and wireless access point machine.
I got a fairly good deal on a pair of these suckers today; assuming they ship in a sane manner I should be enjoying my new 44 inches of dual-screen awesomeness by Friday.
Since I was dropping a chunk of cash anyways, I decided to go ahead and pick up a copy of Bayonetta as well. I mean, I have to do something until Mass Effect 2 is released, right? 
So I should have a very enjoyable weekend coming up.
| |
 Juicy crunchy tasty sweet |
Posted - 1/17/2010 9:30:08 AM | I've scraped together a couple of free hours and spent some time hacking on Epoch Release 8 this weekend. A couple of minor task-list items have been knocked out, and I've done some architectural improving in the parser to help boost compile times.
At the moment I'm working on Issue 9 which involves adding thread pool support to the language's native threading features. Currently, any time you fork a task block or invoke a future, the VM spins off an OS thread under the hood. This is fine for really complex stuff, but for short calculations or general parallelism it really sucks. In most cases the overhead of splitting the thread is higher than the benefit that the parallelism provides.
To counteract this, we provide the option of thread pools. These are worker threads that are spun off at the beginning of the program's execution (well, technically, they are spun off whenever the threadpool function is invoked) and then sit around in a low-cost wait state until someone wants to use one. Once some code is on the worker thread's work queue, it wakes up, executes the code, does anything necessary to store the response and/or message the results back to the calling thread, and then goes back to sleep.
This reduces the overhead of forking a task or future to the overhead of an OS locking primitive (on Windows I'm using a simple Event), which is minimal on good platforms. The result is that it becomes dirt cheap to use multiple threads all over the place.
All of this is pretty easy to set up. Here's an example program from the upcoming Release 8 package:
entrypoint : () -> ()
{
threadpool("demo pool", 2)
thread("task1", "demo pool")
{
message(caller(), result(pi()))
}
thread("task2", "demo pool")
{
message(caller(), result(pi()))
}
future(r1, pi(), "demo pool")
future(r2, pi(), "demo pool")
responsemap(resulthandler)
{
result(real(piresult)) => { debugwritestring("Result: " ; cast(string, piresult)) }
}
acceptmsg(resulthandler)
acceptmsg(resulthandler)
debugwritestring("Future result: " ; cast(string, r1))
debugwritestring("Future result: " ; cast(string, r2))
}
pi : () -> (real(retval, 0.0))
{
real(denominator, 1.0)
boolean(isplus, true)
do
{
real(div, 4.0 / denominator)
if(isplus)
{
retval = retval + div
}
else
{
retval = retval - div
}
isplus = !isplus
denominator = denominator + 2.0
} while(denominator < 10000.0)
}
(You can see more example Epoch programs in the Examples repository.)
Note that instead of a typical task we request a thread. The thread construct accepts two parameters, in contrast to task's one. The first parameter is still the internal ID tag of the thread, so you can message it later. The second parameter is the name of the thread pool from which a thread should be used; this must match the name of a pool previously created by invoking the threadpool function.
A similar tweak is added to the future function: the optional third parameter controls which pool a future is computed in. All in all, using thread pooling is simple, intuitive, and concise - above all a supremely pragmatic sort of feature, which is exactly what Epoch should be.
Working on this has unearthed a couple of parser and validator bugs that I'm fixing; once that is out of the way, I still need to actually build the thread pool support in the VM (for now it still forks a thread, while I work on getting the parser stuff fixed).
Following that, there are only a handful of items left in the work list for Release 8:
- Fix a bug with batch operations and output filenames
- Add simple critical-section wrappers for CUDA library to give some primitive threading safety to CUDA integration
- Add some build configurations to the VS solution to allow building Epoch with no CUDA support (for all the ATi users out there)
- Perform a final code review, largely for documentation and exception safety purposes
Of these, the only really major chunk of time will be the code review. At this point I plan on doing a cursory pass over the code once to make sure it's bare-minimum acceptable for release, and then doing additional in-depth reviews over things as time permits. That should make sure that I can get this thing out the door by the end of the month, as planned.
Once R8 hits the shelves it's time to hop back into the CUDA integration side of things and really improve the supported features (right now you're kind of stuck with simple arithmetic on a single GPU-side thread, which is fairly useless). That and some other surprises are in store for R9, which will be the official GDC 2010 preview release - meaning I'll probably be cramming stuff into it right up until the first week of March.
Speaking of GDC 2010, I can confirm that I'll be present this year once again, and anyone interested in an Epoch preview kit can contact me here via PM to arrange a meeting at GDC. Ask nicely and I might even give you a hallway preview 
That concludes our show; join us next time for nothing of consequence, or stay tuned to see absolutely nothing.
| |
| Thursday, December 31, 2009 |
 So long, 2009! |
Posted - 12/31/2009 8:04:04 PM | 2009: In Before the Lock.
Now it's time to go get drunk! Woohoo!
| |
| Monday, December 28, 2009 |
 The Hardcore Development Box |
Posted - 12/28/2009 11:59:06 PM | Recently, I've been doing some Unix-land hackery for various bits of fun and profit. Very long story short, I've strayed from OpenBSD (my first choice of Unixes) into the wilds of FreeBSD, because of some wireless driver compatibility issues. From there I've returned to Linux, which I left a long time ago and swore never to mess with again - mostly because I needed a totally new set of hardware to do the hacking I wanted. And also because the FreeBSD machine was busy being a wireless access point for my home network.
So, armed with a trove of spare parts and more than a little gusto, I embarked on the journey of Linux From Scratch. I'd used LFS once before on an embedded hardware project, and remember liking the minimalism and the full control over how everything got built for the machine.
Turns out that LFS is far better suited to building embedded stuff than it is to building development workstations.
I've lost track of how many evenings and weekends I've poured into this mess, but it's getting fairly ridiculous. I'm no longer doing this from-scratch build out of curiosity, or masochism, or any of the normal reasons. I'm doing this because dammit I will not let this machine beat me.
Just getting the machine to boot was a nightmare in itself; I had to restart the LFS build from scratch at one point due to a conflict between my hardware RAID system and the Linux RAID drivers. (It had to do with RAID-per-drive vs. RAID-per-partition semantics; combined with a lack of a /boot partition for GRUB, this translates roughly into "you're screwed.") So getting that first kernel running was a triumph all its own.
Then there was the (admittedly minor) adventure of fixing the CD-ROM/DVD drive in the machine. To gloss over a couple of frustrating hours of details, I can simply say, the moral of the story is to be sure you actually turn on the kernel options that you think should be on. Things like IDE drivers are useful little bastards.
With a basic shell booting, it was of course time to begin the long, dreary road towards installing X Windows and GNOME. Thus far, this project has translated into several grueling hours of manually hunting down dependencies, because for some infernal reason I can't get any package manager software to build on this stupid machine.
I did succeed in getting X Windows installed a couple of hours ago; that leaves a rather considerable 150+ GNOME-related projects to compile and install. I'm supposed to fly out tomorrow afternoon, and I have yet to do laundry or pack - so chances are Real Life will interfere with finishing this build, at least in the near future.
Those of you who are old enough (and been around the programming world long enough) remember the glory days of DLL Hell back in the early Windows releases. Back then, it really mattered whether you installed your dependencies locally or in the system shared directory; hard drive space was still a premium commodity.
I deployed enough software in Windows 3.x and Windows 95/98/98SE environments that I remember DLL Hell all too vividly. It was a miserable, awful state of affairs, and releasing software to any nontrivial number of people was bound to elicit complaints of "it just dies when I try to run it."
We all loathed DLL Hell. We all pleaded with Microsoft to give us an alternative. We all pleaded with Microsoft to stop using the registry as the alternative, because the registry concept pretty much sucks. We all watched in horror as the NT kernel took over in Windows 2000, and the registry became still more important and central to tracking installed and shared libraries.
We all rejoiced when SxS finally arrived, eliminating an old foe and banishing the demons of DLL Hell forever. (OK, so SxS really just introduced a whole new family of issues - but hey, at least they're different issues, right?)
Now, though... now, I look at the cryptic compiler error involving time.h and some function duplication... and now, I weep softly and wish that mayhaps the days of DLL Hell might return, even for just a fleeting moment, that I might escape the pains and torment of trying to build software from sources on a Linux machine.
Stupid fucking Linux.
| |
| Monday, December 21, 2009 |
 Please. Kill. Me. |
Posted - 12/21/2009 9:29:11 AM | Let's just say that you should generally make decisions on how to clean up your memory before you're 300,000 lines deep into your project. Updating all of that code to use smart pointers is a bitch.
[Addendum] In a similar vein, if you spend the bulk of the day waiting on a JDK compile on your secondary workstation, don't fuck around with rm in the bin directory where the JDK gets installed.
| |
 *Poke* |
Posted - 12/6/2009 10:27:31 PM | I just realized that I haven't posted here since July.
I kind of left on a bad note, I guess. The intervening months have been, for lack of a less loaded word, completely insane. I've been on and off my medication, in and out of carefully monitored family care, and into a few other situations I'd rather not delve into. There's been a lot of bad decision-making, and the consequences of that are, to put it mildly, a bit overwhelming.
Fortunately, it's not all bad news. I've stayed out of the hospital, the wonderful folks over at Egosoft have seen fit to keep me employed and fed, and even with some serious clouds darkening the horizon, there's a touch of sunrise peeking through, waiting for its chance to break out into full blazing daylight.
Needless to say, I had a lot to ponder this year during Thanksgiving.
There's been some cool stuff going on at work, which I sadly can't get into yet; but there's definitely a lot of exciting things to look forward to on that front. Watch this space.
I've been asked by several people if and when I will be finishing the memory management article series; I intend to revisit that series in the near future, as soon as I can locate my notes and remember where the hell I was planning on going with the whole thing. So there's another reason to hang out and press F5 feverishly until my glorious bounty of words pours forth to the masses.
Last but very much not least, I've finally gotten a bit of a balanced schedule that lets me work on Epoch stuff again when I'm not busy with my primary job. A few good points from that:
- Prototype CUDA integration is now complete and scheduled for delivery in Release 8. This means you can write Epoch code which is then cross-compiled to CUDA, which the nVidia driver further compiles to bytecode that can run directly on supporting hardware. At the moment the cross-compiler is very limited and only supports primitive arithmetic operations, but deeper functionality is on its way.
- Up-to-the-minute development previews are now available courtesy of the Google Code hosting of our Mercurial repository. The code can be checked out and built locally to see where we're at in the development process on Release 8; you can also browse around and peek at the implementation of the language directly on the Google Code web site.
- Assuming the world does not implode, I'm planning on releasing R8 for general consumption sometime around January 2010.
- Great news for GDC attendees - there will be another preview package assembled for GDC '10; anyone who is interested, feel free to contact me and I'll be sure to get you a copy at the conference. The package will contain a snapshot of the current code, documentation from the website on the hows and whys of the language itself, and a special demo of the GPGPU capabilities of the Epoch platform. Don't miss it!
I fully intend to get back into the swing of things here journal-wise, and try and keep things up to date, especially where Epoch is concerned. If all else fails, though, you can see a live history of development progress in our changelog.
| |
In locus hic, omnes res dementes sunt.
|
| S | M | T | W | T | F | S | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | | | | | | |
OPTIONS
Track this Journal
ARCHIVES
February, 2010
January, 2010
December, 2009
July, 2009
June, 2009
May, 2009
April, 2009
March, 2009
February, 2009
January, 2009
October, 2008
September, 2008
August, 2008
July, 2008
June, 2008
May, 2008
April, 2008
March, 2008
February, 2008
January, 2008
December, 2007
November, 2007
October, 2007
September, 2007
August, 2007
July, 2007
June, 2007
May, 2007
April, 2007
March, 2007
February, 2007
January, 2007
December, 2006
November, 2006
October, 2006
September, 2006
August, 2006
July, 2006
June, 2006
May, 2006
April, 2006
March, 2006
February, 2006
January, 2006
December, 2005
November, 2005
October, 2005
|